Subject: Confusion about PR#3499

From: Eric Rescorla <[email-masked]>
Date: Fri, 8 May 2020 15:32:54 -0700

OK, I'm trying to make sure I understand this PR correctly. It's
possible I'm just misunderstanding a lot of stuff, but as I go through
it, I'm finding things that are confusing to me.

Let's consider the following simple handshake, with each
flight being one arrow below:

   Client                                 Server

   Initial [CH] SCID = C1, DCID = S1 ----------->
   Initial [SH] <----------- SCID = S2, DCID = C1
   Handshake [EE...]  <----- SCID = S2, DCID = C1
   Handshake [CFIN] SCID = C1, DCID = S2 ------->
Now, based on this text, let's try to populate these fields.

The client sends only initial_connection_id, which is defined
variously as:

  Each endpoint includes the value of the Source Connection ID field from
the most
  recent Initial packet it sent in the initial_connection_id transport
  parameter; see {{transport-parameter-definitions}}. A server includes the

And:
  The value that the endpoint included in the Source Connection ID field of
the
  first Initial packet it sends during the handshake; see {{cid-auth}}.

Note that these definitions are actually in conflict, because the first says
it's the most recent Initial packet and the other says the first Initial
packet. However, as it happens only one Initial is sent, so it doesn't
matter.

So initial_connection_id = C1

SERVER
The server also sends initial_connection_id, which is S2.

It also sends original_connection_id, defined as:

  parameter; see {{transport-parameter-definitions}}. A server includes the
  Destination Connection ID field it receives in original Initial packets
from the
  client - Initial packets received by the server prior to sending a Retry
packet
  - in the original_connection_id transport parameter. After sending a Retry
  packet, a server also includes the Source Connection ID field from the
Retry
  packet in the retry_connection_id transport parameter.

And

: The value of the Destination Connection ID field from the first Initial
packet
  sent by the client; see {{cid-auth}}.  This transport parameter is only
sent
  by a server.  The value of this parameter depends on whether the server
  sent a Retry packet; see {{packet-retry}}.

And

  A server always includes an original_connection_id transport parameter.
If it
  sends a Retry packet, the server MUST subsequently include the Destination
  Connection ID field from the client's original Initial packets - packets
  received by the server prior to sending the Retry packet - in the
  original_connection_id transport parameter. If the server did not send a
Retry
  packet, the value of the original_connection_id transport parameter MUST
be
  copied from the Destination Connection ID field of the most recent client
  Initial packets.

So again, we have an inconsistency here between "first Initial packet"
and "most recent client Initial packets". In the handshake above it
doesn't matter, but consider what happens if the server's Initial spans
more than one packet and the client sends an ACK. As I understand it, that
would look like this:

   Client                                 Server

   Initial [CH] SCID = C1, DCID = S1 ----------->
   Initial [SH1] <---------- SCID = S2, DCID = C1
   Initial [SH2] <---------- SCID = S2, DCID = C1  // LOST
   Initial [ACK] SCID = C1, DCID = S2 ---------->

So now we have two Initial packets with different DCIDs. Which one
goes in this field? Or have I forgotten how ACKs work with Initials?

I've got some further questions, but I'd like to get unconfused about
this before I keep going.

Thanks,
-Ekr

---

From: David Schinazi <[email-masked]>
Date: Fri, 8 May 2020 16:34:19 -0700

Thanks for the review Eric!

Some thoughts:

1) initial_connection_id
Unless I'm missing something, all Initial packets that an
endpoint sends on a given connection use the same
source connection ID, regardless of this PR.

I agree that we should resolve the discrepancy between the
two definitions of initial_connection_id. I would use something
like
    "The value that the endpoint included in the Source
    Connection ID field of the first Initial packet it sends"
in both places.

2) original_connection_id
Similarly, the client uses the same DCID on its first flight of
Initial packets (and retransmissions thereof) until it
receives something from the server that makes it change it.

I also agree that we should clarify the discrepancy. I would
use something like
    "The value that the client included in the Destination
    Connection ID field of the first Initial packet it sent"
in both places.

I made note of these comments on the PR.

David

On Fri, May 8, 2020 at 3:33 PM Eric Rescorla <[email-masked]> wrote:

>   The value that the endpoint included in the Source Connection ID field
> of the

---

From: "Martin Thomson" <[email-masked]>
Date: Mon, 11 May 2020 12:04:32 +1000

Thanks mostly to David's thoughtful comments on the PR, I've revised the PR.  Mostly, this is just renaming.

Hopefully, this covers the two relevant examples.

Simple:

C->S: Initial SCID = C1, DCID = S1
C<-S: Initial SCID = S2, DCID = C1
...
C->S: Short DCID = S2
C<-S: Short DCID = C1

Client sends initial_source_connection_id = C1
Server sends initial_source_connection_id = S2 and original_destination_connection_id = S1
Each validates all of the values provided by their peer.  This includes verifying that retry_source_connection_id is absent.

Or with a Retry:

C->S: Initial SCID = C1, DCID = S1
C<-S: Retry SCID = S2, DCID = C1
C->S: Initial SCID = C1, DCID = S2
C<-S: Initial SCID = S3, DCID = C1
...
C->S: Short DCID = S3
C<-S: Short DCID = C1

Client sends initial_source_connection_id = C1
Server sends initial_source_connection_id = S3, retry_source_connection_id = S2, and original_destination_connection_id = S1
Each validates all of the values provided by their peer.

> > goes in this field? Or have I forgotten how ACKs work with Initials?

I think that David's proposed changes clarify this.  The "most recent" thing was confusing and wrong.

---

From: Ian Swett <[email-masked]>
Date: Mon, 11 May 2020 08:52:31 -0400

Thanks for the improvements, I do think this is clearer now.

On Sun, May 10, 2020 at 10:06 PM Martin Thomson <[email-masked]> wrote:

> ....
> Each validates all of the values provided by their peer.  This includes
> verifying that retry_source_connection_id is absent.
>
> Or with a Retry:
>
> ....
> Server sends initial_source_connection_id = S3, retry_source_connection_id
> = S2, and original_destination_connection_id = S1