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

feat(s2n-quic-transport): dc Manager #2218

Merged
merged 23 commits into from
May 23, 2024
Merged

Conversation

WesleyRosenblum
Copy link
Contributor

@WesleyRosenblum WesleyRosenblum commented May 22, 2024

Description of changes:

This change wires up the dc::Endpoint and dc::Path types through a dc::Manager. The dc:Manager is responsible for completing the dc handshake by transmitting and receiving DC_STATELESS_RESET_TOKENS and sending notifications to the dc::Path.

The expected handshake with a suitable dc::Endpoint and using MTLS looks like:

Client                                                                    Server

Initial[0]: CRYPTO[CH (DC_SUPPORTED_VERSIONS[3,2,1]] ->

                                     # dc_state_changed: state=VersionNegotiated
                                                   Initial[0]: CRYPTO[SH] ACK[0]
               Handshake[0]: CRYPTO[EE (DC_SUPPORTED_VERSIONS[3], CERT, CV, FIN]

# dc_state_changed: state=VersionNegotiated
# handshake_status_updated: status=Complete
# dc_state_changed: state=PathSecretsReady
Initial[1]: ACK[0]
Handshake[0]: CRYPTO[CERT, CV, FIN], ACK[0] ->
1-RTT[0]: DC_STATELESS_RESET_TOKENS[..]

                                      # dc_state_changed: state=PathSecretsReady
                                     # handshake_status_updated: status=Complete
                                    # handshake_status_updated: status=Confirmed
              <- 1-RTT[1]: HANDSHAKE_DONE, ACK[0], DC_STATELESS_RESET_TOKENS[..]

# handshake_status_updated: status=HandshakeDoneAcked
# handshake_status_updated: status=Confirmed
# key_space_discarded: space=Handshake
# dc_state_changed: state=Complete

1-RTT[1]: ACK[1] ->  
                           # handshake_status_updated: status=HandshakeDoneAcked
                                              # dc_state_changed: state=Complete

graphviz

Call-outs:

I ended up using the Flag sync to ensure both the client and the server aggressively send DC_STATELESS_RESET_TOKENS, as only the Server side could piggyback on the HANDSHAKE_DONE functionality. I couldn't find a way to use Flag without copying the stateless_reset::Tokens from the dc::Path, but I'm not sure that allocation matters much.

Testing:

Added unit tests and an integration to show the dc states changing and the handshake completing in the expected RTTs

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

enum State {
#[default]
Init,
PathSecretsReady(Flag),
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be a bit simpler to just put the Flag on the Manager so you don't have to match on it for interests. You also get to use the state transitions macro which can make it a bit clearer which transitions are valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the only thing that is a little weird with this approach is that the dc provider doesn't have the stateless reset tokens ready when the dc Manager is initialized, so the flag would just be Flag::default() and then it would get overwritten with the actual flag later on when path secrets are ready. Not a big deal though

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah default should be fine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ended up adding a new state ServerTokensSent, that the Server transitions to after it has received tokens from the client. I now have the server's flag only activating once it has received tokens from the Client, so that we don't end up in a situation where the Client didn't send tokens or they got lost, and the Server sent tokens and had them acked, and thus thinking it was done.

quic/s2n-quic-transport/src/dc/manager.rs Outdated Show resolved Hide resolved
session: &impl tls::TlsSession,
publisher: &mut Pub,
) {
ensure!(!self.state.is_complete());
Copy link
Contributor

Choose a reason for hiding this comment

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

should we also ensure!(self.path.is_some())? otherwise, we may be emitting an event that doesn't really make sense for the configured environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if path is none, the state moves straight to Complete

Copy link
Contributor

Choose a reason for hiding this comment

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

ah good call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ended up getting rid of all the ensures and just using the states

quic/s2n-quic-transport/src/space/session_context.rs Outdated Show resolved Hide resolved
quic/s2n-quic/src/tests/dc.rs Show resolved Hide resolved
quic/s2n-quic/src/tests/dc.rs Show resolved Hide resolved
camshaft
camshaft previously approved these changes May 23, 2024
quic/s2n-quic-transport/src/dc/manager.rs Outdated Show resolved Hide resolved
@WesleyRosenblum WesleyRosenblum merged commit 391068e into main May 23, 2024
127 of 128 checks passed
@WesleyRosenblum WesleyRosenblum deleted the WesleyRosenblum/dcmanager branch May 23, 2024 18:42
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.

2 participants