-
Notifications
You must be signed in to change notification settings - Fork 720
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
base: master
Are you sure you want to change the base?
Introduces preferred addressing to the Quiche apps server and client examples #1634
Conversation
05d791a
to
b4a009c
Compare
quiche/src/lib.rs
Outdated
/// IPv4: 4 bytes | ||
/// Port: 2 bytes | ||
/// IPv6: 16 bytes |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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 //"
// Create another preferred UDP listening socket that can be used for server | ||
// migration. | ||
let mut preferred_socket = | ||
mio::net::UdpSocket::bind(preferred_address).unwrap(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lucas "Still remove this"
/// 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, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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"
let port_v4 = b.get_u16()?; | ||
|
||
if ip_v4.is_unspecified() ^ (port_v4 == 0) { | ||
return Err(Error::InvalidTransportParam); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
apps/src/client.rs
Outdated
// event occur and begin migration. The server will see | ||
// `PathEvent::PeerMigrated` upon successful | ||
// migration. | ||
if let Some(addr_v4) = preferred_address_params.addr_v4 { |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 && |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
// Create the new connection! | ||
#[allow(unused_mut)] | ||
// Automatically provisions SCID for preferred address. | ||
let mut conn = quiche::accept( |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)]"
Signed-off-by: Miguel Guarniz <[email protected]>
Signed-off-by: Miguel Guarniz <[email protected]>
Signed-off-by: Miguel Guarniz <[email protected]>
Signed-off-by: Miguel Guarniz <[email protected]>
Signed-off-by: Miguel Guarniz <[email protected]>
Signed-off-by: Miguel Guarniz <[email protected]>
8ae7f6e
to
045e5de
Compare
This PR:
To reproduce:
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
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
127.0.0.1:4435
). It then performs a subsequent migration to a new port of its own.