Closed QUICTester closed 1 year ago
Your tester is wrong. The spec (section 7.3 of RFC 9000) says that the client copies the "source connection ID" or the retry packet into the destination connection ID of the new Initial packet. This is tested in the interop runner, see test "R". See also section 17.2.5.1, "The server includes a connection ID of its choice in the Source Connection ID field. This value MUST NOT be equal to the Destination Connection ID field of the packet sent by the client. A client MUST discard a Retry packet that contains a Source Connection ID field that is identical to the Destination Connection ID field of its Initial packet. The client MUST use the value from the Source Connection ID field of the Retry packet in the Destination Connection ID field of subsequent packets that it sends."
To reproduce this behavior 1) Client sends an Initial packet carrying a Crypto frame that contains the Client Hello message. 2) Client receives a Retry packet from the server. 3) Client sends an Initial packet with the Retry token, carrying a Ping frame. 4) Client receives an Initial packet carrying an ACK frame from the server (Retry token verification is successful). 5) Client sends an Initial packet with the Retry token, carrying a Crypto frame that contains the Client Hello message. (Client has now used the initial_source_connection_id as the Destination Connection ID) 6) Client receives an Initial packet carrying a ConnectionClose frame saying the Retry token is invalid (Retry token verification is unsuccessful).
Due to the Retry token tied to the retry_source_connection_id, the retry token verification will only be valid once in each connection, although a valid Retry token is given.
Nope. Step 5 is wrong. The client must not do that. It must set the "Destination CID" at step 3-4-5 to the source CID of the retry packet. The only other acceptable value at step 5 would be the source CID of the ACK frame received at step 4.
Yes, exactly. At step 4, the server has changed its Source Connection ID for the ACK frame. Later when the client sends the Crypto frame carrying the Client Hello message with the Source Connection ID received at step 4, the Retry token verification will fail.
initial_source_connection_id = This is the value that the endpoint included in the Source Connection ID field of the first Initial packet it sends for the connection. (which is set at step 4 by the server in the example above).
The code was written specifically to check that the client follows the spec. This is a tricky spec.
Hi, Thank you for your response and insights.
Maybe the spec can be clearer in this case? As we are currently working on ensuring the QUIC implementations follow the QUIC specification, testing QUIC implementations, and also hope that our work can make QUIC better for the community.
You should probably take that discussion to the QUIC WG mailing list.
Hi, when testing commit d2f01093, we discovered that Picoquic's Retry token is tied to retry_source_connection_id.
According to RFC 9000, the client must include the received Retry token in all its Initial packets. Therefore, the client may send an Initial packet with the Retry token using initial_source_connection_id. Tying the Retry token with retry_source_connection_id will cause the token verification to fail when initial_source_connection_id is used.