RE: Asymmetric CIDs

"Lubashev, Igor" <> Fri, 16 February 2018 17:43 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 2E76A126CB6 for <>; Fri, 16 Feb 2018 09:43:34 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.7
X-Spam-Status: No, score=-2.7 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id dpbDtlAphhL6 for <>; Fri, 16 Feb 2018 09:43:31 -0800 (PST)
Received: from ( [IPv6:2620:100:9005:57f::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 4D329124C27 for <>; Fri, 16 Feb 2018 09:43:31 -0800 (PST)
Received: from pps.filterd ( []) by ( with SMTP id w1GHgDuR008364; Fri, 16 Feb 2018 17:43:30 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; h=from : to : subject : date : message-id : references : in-reply-to : content-type : mime-version; s=jan2016.eng; bh=nRoR85xBsZSkpcezZP0MldnBjWDsFLOUVHGrdOIpAAM=; b=U1ZvD2F7jRupN2rXcwpXx+cSf4cgERbukraFR+/YxdwvejvNE+0lHsqRDuxKsiAzT7F0 BoS/VIMaOxzcMu7MFR9uGhMVgJ6VDBfRBf775YmxzhIg8hk7TObcksXfiYdfAbhfhxCe /99xmm6ktmlrVvhG/1s8Xma/gmdTdHtwPYFy2YlKYBqr63fmA7HoAA0u32zBlTgwa+lD 9UicbBalV6z5qvjQFzMkXg3oQXQQFcOjCZBYTuzAV/duKxuYXch6NlyhN3/rxV0ZhiNy CtKyN2EwYVS8XOI0tMMKsEANmZwtDfnnVDXbL1Qyh4QyXq8M3RJTUmwxYfxHr7IB1xS/ BA==
Received: from prod-mail-ppoint1 ( []) by with ESMTP id 2g63c40386-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Feb 2018 17:43:29 +0000
Received: from pps.filterd ( []) by ( with SMTP id w1GHf6u0024478; Fri, 16 Feb 2018 12:43:29 -0500
Received: from ([]) by with ESMTP id 2g1vy0d6rg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 16 Feb 2018 12:43:28 -0500
Received: from ( by ( with Microsoft SMTP Server (TLS) id 15.0.1263.5; Fri, 16 Feb 2018 12:43:28 -0500
Received: from ( by ( with Microsoft SMTP Server (TLS) id 15.0.1263.5; Fri, 16 Feb 2018 12:43:27 -0500
Received: from ([]) by ([]) with mapi id 15.00.1263.000; Fri, 16 Feb 2018 12:43:27 -0500
From: "Lubashev, Igor" <>
To: Eric Rescorla <>, IETF QUIC WG <>
Subject: RE: Asymmetric CIDs
Thread-Topic: Asymmetric CIDs
Thread-Index: AQHTp0fggIXU4KVY8ESyFyVlkYzgVKOnRTcw
Date: Fri, 16 Feb 2018 17:43:27 +0000
Message-ID: <>
References: <>
In-Reply-To: <>
Accept-Language: en-US
Content-Language: en-US
x-ms-exchange-transport-fromentityheader: Hosted
x-originating-ip: []
Content-Type: multipart/alternative; boundary="_000_7286e675a5c944e08d80e38c314eb103usma1exdag1mb5msgcorpak_"
MIME-Version: 1.0
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-16_06:, , signatures=0
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=908 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1802160211
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-16_06:, , signatures=0
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=856 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1802160211
Archived-At: <>
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Fri, 16 Feb 2018 17:43:34 -0000

Thanks for the write up.

(I thought the CID task force was to discuss CID length and its encoding, but this is much bigger.)

I want to point out that asym CID is sacrificing not only public reset (sometimes) but also the ability to route ICMP (& ICMPv6) Error packets back to the server.

The issue with the proposed short-header encoding is that it makes packet numbers useless for network troubleshooting, since they are located at an unpredictable offset, unless you’ve seen the negotiation and remembered CID lengths for each connection.

  The issue # seems incorrect.  Are you referring to issue #745?

From: Eric Rescorla []
Sent: Friday, February 16, 2018 12:01 PM
Subject: Asymmetric CIDs

Hi folks,

After a bunch of discussion, the CID task force came down to rough
consensus that asymmetric conn IDs were probably the right
direction (CID task force members, please feel free to voice dissent
here). Here's a complete writeup of what I think would be needed
for asymmetric connection IDs. It's not a PR, because I think
something self-contained is cleaner.

Note that if we adopt this direction, we would be sacrificing
public reset under some conditions (see previous emails to the
list) and we would need to decide if it was worth keeping at all.

The basic idea is that each side gets to dictate the connection IDs
that are used to send to it. During the handshake, you establish those
CIDs and then each side can issue new CIDs during the connection.  The
main advantage of this is that it allows for symmetric topologies in which
the client is also behind some kind of stateless LB/router rather than
just the server. See Issue #1091 for more info on this.

The overall handshake looks something like this:

Client                                      Server

Initial [CID=XXX] {recv-CID=YYY} ---------------->
<-------------- Cleartext [CID=YYY] {recv-CID=ZZZ}
Cleartext [CID=ZZZ], {recv-CID=YYY} ------------->
<-------------------------- Short header [CID=YYY]
Short header [CID=ZZZ] -------------------------->

The client's initial CID (XXX) is special, and either consists of

    (a) a randomly chosen dummy CID. Proposal: require this to be
        8 bytes or at least a minimum. This should be the same
        for all Initial packets in a connection (unless a stateless
        reject is received, as below).
    (b) a CID which it received from the server in a stateless reject

All the server's packets are sent with the client's receive CID (YYY)
and all subsequent client packets are sent with the server's receive
CID (ZZZ). The general rule is that you should send with the
connection ID that you most recently received (where recently
is defined as highest PN).

Note: I believe it's safe to just use the sending CID as the mixin
for the KDF, but I haven't thought this entirely through yet.

Finally, you can send NEW_CONNECTION_ID in either direction to provide
a new connection ID for the other side to use. The general assumption
is that you can do this at any time, just as with current QUIC, and
that any time you send to a new remote 3-tuple you should change CIDs
if you can. Note that this means that endpoints should try to make
sure that the other side has spare CIDs in case they need to migrate.

As we discussed in the meeting the short header should just have
an implicit length CID. This gives us the following short header:

   |0|C|K| Type (5)|
   |                                                               |
   +                     [Connection ID (*)]                       +  <- change from 64
   |                                                               |
   |                      Packet Number (8/16/32)                ...
   |                     Protected Payload (*)                   ...

Note that we may also be able to dispense with the C bit, if each
side just gets to say "send me this CID exactly", why do we want
to say "here is my CID but you can omit it".

We have several options about the long header. The first question
is where recv-CIDs go. In previous versions I suggested putting
them in transport parameters, or elsewhere in the TLS handshake,
and that might still be viable, though it has some drawbacks [0],
so the other alternative is to put both CIDs in in the long header.
This would look something like:

   |1|   Type (7)  |
   |  DCID-Length  |                                               |
   +-+-+-+-+-+-+-+-+   Dst Connection ID (*)                       +
   |                                                               |
   |  SCID-Length  |                                               |
   +-+-+-+-+-+-+-+-+   Src Connection ID (*)                       +
   |                                                               |
   |                         Version (32)                          |
   |                       Packet Number (32)                      |
   |                          Payload (*)                        ...

The semantics here are that the first value is the CID you want to
send to and the second one is the value you want used to send to you
(I've inverted these to keep the order the same as short header).

Two notes about this encoding:

1. I think we agreed that we didn't want arbitrary length CIDs up to
255 bytes, and yet we have room in this length byte. I propose we
limit it to 31 bytes and then grease the remaining 3 bits [1].

2. Because the client sends its CID first, there's no way to get the
current QUIC semantics of the server just dictates the CID.  I propose
we fix that by defining a special sentinel CID (all 1s, all 0s,
whatever) of whatever our maximum length is that means "just use your
own CID".

We can endlessly bikeshed on this structure.

Finally, we will need to update NEW_CONNECTION_ID to allow a variable
length CID. This would look like this:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   |                          Sequence (i)                       ...
   |  CID-Length   |                                               |
   +-+-+-+-+-+-+-+-+       Connection ID (*)                       +
   |                                                               |
   |                                                               |
   +                                                               +
   |                                                               |
   +                   Stateless Reset Token (128)                 +
   |                                                               |
   +                                                               +
   |                                                               |

[0] However, in the transport parameters design, if the server's
handshake gets reordered, the client might need to send some ACKs with
the initial CID. However, we've agreed that the client's IP address
has to be stable, so this isn't a problem. Alternately, you could
change C->S CIDs in the short header if that was easier.

[1] An alternative would be to have a sparse range (e.g., you can
express 0-7 and then 8-22 by 2s, assuming I have counted correctly)
and then we could pack both lengths into a single byte. As I said,
lots of opportunities for bikeshedding here.