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
Unable to reset connection with zero-length connection ID with stateless reset token #4337
Comments
Checking the stateless reset token before the connection ID is a pretty large performance penalty (2 instead of 1 map lookups), happening in the hot path of the transport, so that's a non-starter. I could get behind your suggestion to add a Want to send us a PR? |
Can you explain why you think it should only be checked if every decryption fails? A few thoughts on the RFC:
not sure why only looking at the first packet in a datagram, as only the last one could be a stateless reset because it is short-header-like.
a callback
From the RFC it is not clear to me if coalesced packets can contain stateless resets.
as I understand, a valid behavior would be to process the first packets in a datagram and then detect a stateless reset in the last packet because it cannot be decrypted. I am not sure why someone would send such a packet, but it would require checking only the last packet independently of the previous ones in the datagram. Suggestion: let the connection call back via |
Some implementations satisfy the 1200 bytes minimum packet size requirement by appending some garbage data (or all 0s) to a coalesced packet. This is a valid implementation, and it shouldn't lead to a check for a stateless reset token.
Sounds good to me, modulo (maybe) the caveat for coalesced packets. |
Ok appending random data makes sense to me, but still not why some packet of the coalesced packet has to be checked for a reset token if the first long header packet could not be decrypted.
I don't see the problem, if by chance the random garbage data looks like a short header packet with the right connection id, the packet must even be tried to be decrypted, so checking for the reset token is negligible. |
Yes, you're right about that. My argument is not a performance argument. My point is that a coalesced packet can never be a stateless reset, because that's what RFC 9000 specifies: The stateless reset is a packet on its own. |
Oh, now I see. And even stateless resets in datagrams starting with a long header must be detected. So it is true that a stateless reset can never be part of a coalesced packet. But technically, packets that look like coalesced packets can actually be a stateless reset packet. So From RFC 10.3:
|
We don't have to deal with this caveat as long as we don't support a QUIC version that allows long header stateless resets, do we? That would simplify things, as there's no such QUIC version around, nor do I expect such a QUIC version to emerge anytime soon. |
In general, it conflicts with the statement in RFC 9000 about future versions of QUIC. So I think it should be fine for now to just check non-coalesced short-header packets. |
Sounds like a plan! Are you going to work on a PR? |
I will, but it's not super high on my priority list |
Because quic-go deviates from the RFC, stateless resets are never handled if the connection ID has length zero.
handlerMap.Get
always returns a handler, but the encryption will fail afterwards. No further reset token checks are performed. The same applies to short connection IDs, which are likely for clients. I would argue that collisions are not rare. RFC 9000 also says that if decryption fails, the token must be checked.Suggestion:
Add a callback
OnDecryptionFailed
from the connections to the transport to handle stateless resets.Sources:
From RFC 9000 10.3.1. Detecting a Stateless Reset:
From transport.go:
The text was updated successfully, but these errors were encountered: