Subject: Re: [quicwg/base-drafts] A 17 octet connection ID (#1088)

From: Brian Trammell <[email-masked]>
Date: Thu, 01 Feb 2018 05:58:02 -0800

I share both of @ekr's concerns here.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#issuecomment-362273249

---

From: janaiyengar <[email-masked]>
Date: Thu, 01 Feb 2018 07:45:03 -0800

janaiyengar commented on this pull request.

> +
+Ensuring that the server sends the correct connection ID in its stateless reset
+presents an additional challenge.  Truncation of the connection ID in packets
+that use the short header means that the entire connection ID might not be
+present in the packet that triggers the stateless reset.  Furthermore, the
+server cannot know how many octets from the connection ID that the client
+requested be included in the short header.
+
+A server is expected to have a minimum number of octets that are needed for
+correct routing.  Thus, the server can always know that at least this many
+octets of the packet it receives contain a connection ID.
+
+If the server uses a longer connection ID than the client, there is the
+potential for the additional octets to be used to reveal that the stateless
+reset is not a regular packet.  This is not a serious issue, as it is already
+possible to use other fields to distinguish them from other packet.

Fair enough. I don't grok your point about using a connection ID from the past. 

This is another way that a stateless reset might be detectable: while sending a stateless reset the server does not know what the client had negotiated for connection ID truncation in the server -> client direction. If the client required the server to send a connection ID, the stateless reset would likely not carry one.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#discussion_r165395655

---

From: janaiyengar <[email-masked]>
Date: Thu, 01 Feb 2018 16:02:56 +0000 (UTC)

>  {: #short-packet-types title="Short Header Packet Types"}
 
-The header form, omit connection ID flag, and connection ID of a short header
-packet are version-independent.  The remaining fields are specific to the
-selected QUIC version.  See {{version-specific}} for details on how packets
-from different versions of QUIC are interpreted.
+The header form and connection ID of a short header packet are
+version-independent.  The remaining fields are specific to the selected QUIC

That's not the scenario I outlined in my comment. You run a server farm and purchase a middlebox from a vendor. If you have a connection ID bit, you don't have to configure the middlebox to align with server policy about connection ID, because packets are self-describing.

The bit makes sense only if the size is known to both the server and the middlebox however, so you have a good point. Both entities have to agree on a way to determine the size of the connection ID, and as we've discussed earlier, that can be achieved by making the connection ID a varlen. The spec doesn't have to make it a varlen. A middlebox can simply require that connection IDs are vended with a particular encoding by servers, and that's adequate.

I don't want to design this here; I'm noting that self-describing packets have value. I think this should be discussed separately from this PR. That said

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#discussion_r165401735

---

From: MikkelFJ <[email-masked]>
Date: Thu, 01 Feb 2018 16:48:37 +0000 (UTC)

> I share both of @ekr's concerns here.

Also note my proposal for asymmetric CID which would resolve some of those concerns. I think it would require a separate initial packet type when responding to a stateless retry, but then CID and CID length and in each direction can be place in transport params.
https://github.com/quicwg/base-drafts/issues/1089

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#issuecomment-362327570

---

From: Christian Huitema <[email-masked]>
Date: Mon, 05 Feb 2018 19:26:46 -0800

huitema commented on this pull request.

Well, OK, that PR matches pretty much what we discussed. I don't know how the truncation will work in practice -- I suspect that the choice will end up being either 0 or 17. And I would really like to consider a symmetric solution, in which packets sent to the client bear a connection ID chosen by the client. But of course, that doesn't play well with Stateless Reset.

>    {{short-packet-types}} lists the types that are defined for short packets.
 
 Connection ID:
 
-: If the Omit Connection ID Flag is not set, a connection ID occupies octets
-  1 through 8 of the packet.  See {{connection-id}} for more details.
+: A connection ID occupies between 0 and 17 octets inclusive, starting from
+  octet 1.  This value can be truncated from the full 17 octet connection ID.
+  See {{connection-id}} for more details.

So, if I read correctly, there is no indication in the short header of the presence and size of the connection ID field. In practice, this forces clients and servers to pick one same size for all connections. Yes, in theory it can be negotiated on a per connection basis, but you need to parse the CID to retrieve the connection context and find the result of that negotiation. Better not try to change the encoded length over the lifetime of the server...

> +expresses how many octets of the connection ID they require in packets that are
+sent to that endpoint.  The truncate_connection_id transport parameter
+({{transport-parameter-definitions}}) of a receiving endpoint determines the
+number of octets that are included by the sending peer.  A truncated connection
+ID includes the indicated number of octets, starting from the first octet.  An
+endpoint can request that the connection ID to be omitted entirely by setting
+truncate_connection_id to 0, or include any number of octets up to the full
+connection ID length of 17 octets.  Connection IDs are not truncated for any
+other use.
+
+Note:
+
+: The odd length of the connection ID is chosen to enable efficient construction
+  of the value using 128-bit ciphers with an additional octet for overheads such
+  as key identifiers.
+

OK. Now, in the direction from server to client, are we sending the server chosen CID, or the client chosen one? Because, the client has no way to know how many bytes of the server connection ID it might need before seeing the CID. Yet the client's transport parameters are sent in the client initial packet, before seeing the value chosen by the server. So the clients only practical choices are 0 and 17...

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#pullrequestreview-94215187

---

From: Martin Thomson <[email-masked]>
Date: Tue, 06 Feb 2018 04:49:28 +0000 (UTC)

martinthomson commented on this pull request.

 Connection ID:

A server has to pick a consistent minimum.  It could occasionally choose longer, but the load balancer would just ignore those extra bytes.

Yes, there is general recognition that a client can't use stateless routing.  For a client, you are right.  This is why I would prefer some symmetric in connection ID selection, but that means making a hard call with respect to the stateless reset.

-: The omit connection identifier parameter indicates that packets sent to the
-  endpoint that advertises this parameter MAY omit the connection ID in packets
-  using short header format.  This can be used by an endpoint where it knows
-  that source and destination IP address and port are sufficient for it to
-  identify a connection.  This parameter is zero length.  Absence of this
-  parameter means that the connection ID MUST be present in every packet sent to
-  this endpoint.
+: An 8-bit unsigned integer that indicates the length of the connection ID that
+  is to be put in packets that use the short header ({{short-header}}) that are
+  sent to this endpoint.  Values between 0 and 17 inclusive are valid; larger
+  values MUST be treated as a connection error of type
+  TRANSPORT_PARAMETER_ERROR.  This parameter is set to 0 if the transport
+  parameter is omitted, meaning that packets with short headers that are sent to

I just wanted to say that it defaults to 0.  I'll revise.

My point is that if there were packets sent on this connection in the past, then the packet numbers there and in the stateless reset might reveal something.

The point about truncation is addressed in this PR (3 paragraphs down).  It's ugly though.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#discussion_r166186394

---

From: Christian Huitema <[email-masked]>
Date: Tue, 06 Feb 2018 07:18:59 +0000 (UTC)

> @@ -552,7 +552,7 @@ older than 1.3 is negotiated.
 
 QUIC requires that the initial handshake packet from a client fit within the
 payload of a single packet.  The size limits on QUIC packets mean that a record
-containing a ClientHello needs to fit within 1171 octets.
+containing a ClientHello needs to fit within 1162 octets.

That's not the only change required to the TLS document. The connection ID is also used as in the creation of Handshake Secrets. Pointing out the change in length may not be strictly necessary, but it will be helpful for implementers.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#pullrequestreview-94243003

---

From: ianswett <[email-masked]>
Date: Tue, 06 Feb 2018 06:06:07 -0800

ianswett commented on this pull request.

In regards to the stateless reset issue for asymmetric connection IDs, one use case is picking a connection ID so the packet is received by the optimal receive queue and doesn't have to hop threads/CPUs.  For use cases like this, it's an optimization, but the machine should be able to route the packet correctly if it chooses to.

Also, I'll note that right now, the client doesn't get to pick any portion of the connection ID, so allowing the client to pick knowing that stateless reset might not route optimally seems acceptable, since the client can always pick the same value as the server, like today.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#discussion_r166308718

---

From: Martin Thomson <[email-masked]>
Date: Wed, 28 Feb 2018 03:00:08 +0000 (UTC)

Closed #1088.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#event-1495839240

---

From: Martin Thomson <[email-masked]>
Date: Wed, 28 Feb 2018 03:00:09 +0000 (UTC)

Parking this.  We will need something to capture the design team conclusions, which included two connection IDs.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1088#issuecomment-369105281