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

Server Handshaker will not transition to Connection until client sends data #16

Open
ShadowJonathan opened this issue Dec 11, 2021 · 3 comments

Comments

@ShadowJonathan
Copy link
Owner

The DTLS 1.2 handshake looks like thus;
image

All of this is able to be encapsulated in Handshaker objects, which handle all of this (+ retransmission) for the clients.

Because of this, handshakes have a special API which makes them able to alert the program to wait until a certain moment to retransmit the packets they'd want to send.

However, the 6th flight could get lost, either the CCS or the Finished packet, which means the client can get in a deadlock, see the following passage from [RFC6347];

   In addition, for at least twice the default MSL defined for [TCP],
   when in the FINISHED state, the node that transmits the last flight
   (the server in an ordinary handshake or the client in a resumed
   handshake) MUST respond to a retransmit of the peer's last flight
   with a retransmit of the last flight.  This avoids deadlock
   conditions if the last flight gets lost.

However, this would block the server handshaker from transitioning into a connection object until the client has sent any application data.

It would be more "correct" to wait until a client sends data, but depending on the application, the server might want to immediately start to send data.

This could be especially problematic with resuming sessions, or #9, which might require this kind of "last state" to be certain before either side starts sending buffered data again.

For now, I think it's more clean to wait for application data, but in the future I could add a "server handshaker mode" which immediately transitions to a connection object after finishing the last flight, but keeps it sealed and keeps it ready to be sent if the client were to send flight 5 again, this would be a ton of extra logic to keep, though.

@ShadowJonathan
Copy link
Owner Author

This would actually maybe be a problem for SRTP, especially in combination with #15, which would separate away the sink for application data.

@ShadowJonathan
Copy link
Owner Author

Though, after thinking about it for a little more while, it is possible that this is okay.

We could probably let the connection object trigger the flight retransmission if it sees any part of the 5th flight instead, as the application would just blindly feed data from the socket, in hope of application data. If we see that (and verify it), we should then send the flight back. Though in this case, we're relying on the client to be the retransmission timer.

This would also be fine in a situation with #15, as the connection object would then just hold the sealed last flight data forever, if needed, only sending it when the application feeds it handshake messages from the last flight. This would be a little overhead in exchange for a nicer and cleaner API.

@ShadowJonathan
Copy link
Owner Author

Alright, I'll store this in the server Connection object as a Option<Box<HandshakeFinalizer>>, the box will make sure it has less overhead on the Connection object after it's been disposed of.

I'll also expose a function like unchecked_dispose_handshake_finaliser, which can be called by the application if it receives evidence of the connection being properly finalized (such as SRTP data being received), this'll allow applications to more tightly (and optionally) control this, at the expense of potentially turning the connection into an error state if at any point hereafter some packets of fight 5 are received, though those would potentially be ignored instead, possibly turning the connection into a deadlock state.

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

No branches or pull requests

1 participant