Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduces preferred addressing to the Quiche apps server and client examples #1634

Open
wants to merge 53 commits into
base: master
Choose a base branch
from

Conversation

Clendenin
Copy link

@Clendenin Clendenin commented Oct 18, 2023

This PR:

To reproduce:

  • Run server by: RUST_LOG=trace cargo run --bin quiche-server -- --cert apps/src/bin/cert.crt --key apps/src/bin/cert.key --enable-active-migration --max-active-cids 4 --preferred-address 127.0.0.1:4435
  • Run client by: RUST_LOG=trace cargo run --bin quiche-client -- --no-verify --enable-active-migration --perform-migration --max-active-cids 4 https://127.0.0.1:4433
  • The Quiche Client App initially migrates to the servers preferred address (127.0.0.1:4435). It then performs a subsequent migration to a new port of its own.
  • Confirm migration by seeing path validations, examples below, and other logs stating the number of written bytes on your migrated path.
Screen Shot 2023-10-18 at 9 31 33 AM Screen Shot 2023-10-18 at 9 30 10 AM Screen Shot 2023-10-18 at 9 31 00 AM

@Clendenin Clendenin requested a review from a team as a code owner October 18, 2023 14:40
@Clendenin Clendenin changed the title Introduce preferred addressing to the Quiche apps server and client examples Introduces preferred addressing to the Quiche apps server and client examples Oct 18, 2023
@Clendenin Clendenin force-pushed the quiche-apps-preferred-addressing branch 2 times, most recently from 05d791a to b4a009c Compare April 12, 2024 22:06
Comment on lines 8431 to 8433
/// IPv4: 4 bytes
/// Port: 2 bytes
/// IPv6: 16 bytes
Copy link
Author

@Clendenin Clendenin Jul 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"nit: these should use double quotes //" - Lucas

Copy link
Author

@Clendenin Clendenin Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe my original intention was to have these serve as "Documentation Comments" to the constant below. This is what it looks like when the documentation for the constant is pulled up in my editor:
Screenshot 2024-07-30 at 11 57 40 AM

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas: "Switch these to regular //"

apps/src/client.rs Outdated Show resolved Hide resolved
Comment on lines +84 to +89
// Create another preferred UDP listening socket that can be used for server
// migration.
let mut preferred_socket =
mio::net::UdpSocket::bind(preferred_address).unwrap();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this preferred socket take new connections not just migrated connections?
If a new connection starts here, is the preferred address provided over the transport params? What does this cause? - Lucas

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error Result if preferred address is same as current address - fail on startup - Lucas

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that is a great question.
For the example app the app will accept connections starting on the servers preferred address. The server will still encode a "preferred address" transport parameter into the transport parameters it initially sends to the client. The client will receive the transport parameters and begin decoding them. It will see an encoded preferred address transport parameter and begin decoding it. The example app will then initiate probe_path() on this "new" preferred address. The probe_path() logic sees that this is an existing path. It will generate a Path_Challenge frame and then it does not do path migration since there in no migration to perform.

This separation of concerns makes sense to me. The probe_path / connection migration code should be resilient enough to not attempt migrations to the path it is already on.

Screenshot 2024-08-01 at 2 07 11 PM

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas: "Add a comment to explicitly state that this is intentional and not a bug"
Lucas to follow up with working group to further discuss.

///
/// Returns a list of tuples (DCID sequence number, Path ID), containing the
/// sequence number of retired DCIDs that were linked to their respective
/// Path ID.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment has been deleted but there was no code change. Is the comment actually wrong (and we can just fix that up in a quick standalone PR) or is there something else at hand?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment was out of date. iirc the function was changed but the comment was never updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, please create a separate PR with the change


conn.on_timeout();
}

// Read incoming UDP packets from the socket and feed them to quiche,
// until there are no more packets to read.
for event in &events {
trace!("Event occured: {:?}", event);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be too spammy to land

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused. Isn't this file just to demonstrate how to use the code? I left this in because it is helpful to see what event occurred and when.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas "Still remove this"

apps/src/client.rs Outdated Show resolved Hide resolved
apps/src/client.rs Show resolved Hide resolved
/// Returns the server's preferred address transport parameters which can be
/// used to perform a connection migration.
pub fn server_preferred_address_params(
&mut self,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't need to be mut

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The internal call to new_destination_cid() requires it be mutable

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas: "Double check to see if you can remove this"

quiche/src/lib.rs Outdated Show resolved Hide resolved
let port_v4 = b.get_u16()?;

if ip_v4.is_unspecified() ^ (port_v4 == 0) {
return Err(Error::InvalidTransportParam);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is trying to enforce https://datatracker.ietf.org/doc/html/rfc9000#section-18.2-4.32.1 ?

Servers MAY choose to only send a preferred address of one address family by sending an all-zero address and port (0.0.0.0:0 or [::]:0) for the other family. IP addresses are encoded in network byte order.

My concern is that this is called in the top-level [decode()](https://github.com/cloudflare/quiche/pull/1634/files#diff-2ac678416f8d7ea462a714681b63acedcbbb7f2c99e537ce61b7667b3bf4ac41R8589) function and would early abort something that is not technicall invalid

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the IPv4 address is unspecified (all 0s) and the associated port is also unspecified (all 0s) then the XOR operation will fail and this decode_v4 function will return Ok(None)

// event occur and begin migration. The server will see
// `PathEvent::PeerMigrated` upon successful
// migration.
if let Some(addr_v4) = preferred_address_params.addr_v4 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The selection of which preffered address to use is subjective - this is just an example. There's also bit of duplication across the branches that can be reduced. Consider extracting into a function like "select_and_probe_preferred_address"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I coalesced the branches into one to dry the code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas: "Put this into a function to make it more obvious to others"

}

// Perform client side connection migration
if args.perform_migration &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also consider making this its own function

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite follow, what is your reasoning to break this out into a function?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas: "Split it out to enforce soc"

///
/// Returns a list of tuples (DCID sequence number, Path ID), containing the
/// sequence number of retired DCIDs that were linked to their respective
/// Path ID.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, please create a separate PR with the change

quiche/src/frame.rs Outdated Show resolved Hide resolved
quiche/src/lib.rs Outdated Show resolved Hide resolved
apps/src/bin/quiche-server.rs Outdated Show resolved Hide resolved
Comment on lines +437 to +450
// Create the new connection!
#[allow(unused_mut)]
// Automatically provisions SCID for preferred address.
let mut conn = quiche::accept(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a hangover? if we don't need the mut then lets not declare it as such

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conn.set_keylog(Box::new(keylog)); needs a mutable ref

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucas "Why have #[allow(unused_mut)]"

apps/src/bin/quiche-server.rs Outdated Show resolved Hide resolved
apps/src/bin/quiche-server.rs Outdated Show resolved Hide resolved
apps/src/bin/quiche-server.rs Outdated Show resolved Hide resolved
@Clendenin Clendenin force-pushed the quiche-apps-preferred-addressing branch from 8ae7f6e to 045e5de Compare August 6, 2024 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants