Re: Asymmetric CIDs

Martin Thomson <martin.thomson@gmail.com> Mon, 19 February 2018 00:30 UTC

Return-Path: <martin.thomson@gmail.com>
X-Original-To: quic@ietfa.amsl.com
Delivered-To: quic@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id AAFC512702E for <quic@ietfa.amsl.com>; Sun, 18 Feb 2018 16:30:45 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2
X-Spam-Level:
X-Spam-Status: No, score=-2 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ued57NNqzjOh for <quic@ietfa.amsl.com>; Sun, 18 Feb 2018 16:30:44 -0800 (PST)
Received: from mail-oi0-x22e.google.com (mail-oi0-x22e.google.com [IPv6:2607:f8b0:4003:c06::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 079FC126FDC for <quic@ietf.org>; Sun, 18 Feb 2018 16:30:43 -0800 (PST)
Received: by mail-oi0-x22e.google.com with SMTP id t185so947876oif.6 for <quic@ietf.org>; Sun, 18 Feb 2018 16:30:43 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=DS0/K0N9sdib4Ki8AfbYgCmVJKjOEJ4MG9THVBH+12c=; b=OkkS8tV2be61uvaNiOAfo0doNLZM/N4tbEhTV3hwD0H04UjYmROnh3osUZgtQ3o4Bk EeijZVJ/1V3Efw8f8cc0V7f9tvjFEohQt5qXOpCjx5l2IYZciR0dllLnItima70ERd3C Wd8XpXbCCH1a2w/bueF6hiivNysBPGr2fc67k6SjC+1Fd7fJ1sVwOejprrlsMfrJjt6m 9gOqs9guI1wSSKjsW2qPxAQs6WCN9UY+xQipFuxcrWuSMah130A1dRy9s9wpxSyPrbBz iq8KSYAalV7A6MMQMoqODirAwm/E9JbFfdnaKZsRgQnQHkIqkJgmt4r9ZE9Srm0lunc6 GrVA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=DS0/K0N9sdib4Ki8AfbYgCmVJKjOEJ4MG9THVBH+12c=; b=Qd6n4Pi/qhltpTc2ZZ4lqhB4WWbkY3tQEqHwWp619V3s2+CTTtbUNtiK18tTdV3mF8 4/ntgX0EfuWpjwjG/n8lBdQNUZ3DugW8VKFpKUzzHma9KxR1J4hrNdEV4tqRUN+EVLC+ zBCYqMUOWrUacKzjwBEOXhD3YkG8luIuxziWCxKESqVBfyCQuIu0r5U09BPUl/j07hh9 jYTN00YxzLdbhC/HwleXix0z4I7OOlWDANorPxK/b6qH1DRkY0HREhinQaFVRV75ceU8 2oxYmhh0RHqOtG6jI2KdzOLdodPiwxxHjvb/Sx3LYfZMZoUOtdSZScp5v+BqlVlVu7/H 0yTQ==
X-Gm-Message-State: APf1xPAtH4VmQldWsardRWXdeP0mGdq6pTNPPDpBbp61CleJJvhJyNPX GuzCdVd+u/o5Gag9oaHUy+DqP9XOxmQJgc393II=
X-Google-Smtp-Source: AH8x2268XkSeqihJ0wS7pNAu4Z/pNM0fwhPuKFBuV+b3SoX/gbr+Ja3uK1QnM25WPm0lq5HB/vQDdVfFPdyeJRT1qUo=
X-Received: by 10.202.94.196 with SMTP id s187mr8728231oib.144.1519000243082; Sun, 18 Feb 2018 16:30:43 -0800 (PST)
MIME-Version: 1.0
Received: by 10.157.52.196 with HTTP; Sun, 18 Feb 2018 16:30:42 -0800 (PST)
In-Reply-To: <CAKcm_gOvf0N7sq2so38sQaD+2jHGnDpsSQHEwU8HPgSpMJRfzA@mail.gmail.com>
References: <CABcZeBMVabN9LQ42BxpSwK71hzu_TbzwqhHTJV1uJBKr5g-N3A@mail.gmail.com> <CAKcm_gOvf0N7sq2so38sQaD+2jHGnDpsSQHEwU8HPgSpMJRfzA@mail.gmail.com>
From: Martin Thomson <martin.thomson@gmail.com>
Date: Mon, 19 Feb 2018 11:30:42 +1100
Message-ID: <CABkgnnVTeAWomSnajdPZN=KfqFWdH3E=UDe4gyG8KNafipe+Yw@mail.gmail.com>
Subject: Re: Asymmetric CIDs
To: Ian Swett <ianswett@google.com>
Cc: Eric Rescorla <ekr@rtfm.com>, IETF QUIC WG <quic@ietf.org>
Content-Type: text/plain; charset="UTF-8"
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic/MNWNGlLrJ53EnVCn7MgyuemkcQc>
X-BeenThere: quic@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <quic.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic>, <mailto:quic-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic/>
List-Post: <mailto:quic@ietf.org>
List-Help: <mailto:quic-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic>, <mailto:quic-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 19 Feb 2018 00:30:46 -0000

The breakage of a stateless reset is limited.  It is only a problem
for clients that use - and depend on - connection IDs.

A stateless reset will not carry the client-selected connection ID.
It will appear - to the network - to be a change in connection ID.  If
we change connection IDs occasionally for other reasons, then this
won't be a significant problem.

The main problem is in ensuring that the packet arrives at the right
place at the client.  However, it is possible that we can suggest
routing based on address tuple over short timescales at clients.  In
that case, the reset might still arrive at the right place.  That, or
exceptional processing for unrouteable packets.

BTW, I like ekr's idea of making the number space for connection IDs
sparse.  A (short-ish) fixed limit is necessary to ensure that the
stateless reset can be constructed such that it appears plausible and
that means at least overhead + max(connection ID) + AEAD expansion +
an ACK frame.

Would also add the idea of a minimum size for connection IDs.  A one
octet connection ID has awful linkability properties that are pretty
much irredeemable.  You can get 8-22 with single octet steps if you
are willing to make 1-7 invalid.


On Sat, Feb 17, 2018 at 4:25 AM, Ian Swett <ianswett@google.com> wrote:
> Thanks for the excellent summary EKR.  I like this design and think the
> breakage of stateless reset in certain cases is acceptable, since it only
> applies if both sides must have their preferred connection ID present in
> order to route correctly, which is a use case that's impossible in the
> status quo.  I have not come up with any other downsides.
>
> On Fri, Feb 16, 2018 at 12:01 PM, Eric Rescorla <ekr@rtfm.com> wrote:
>>
>> 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.
>>
>>
>> OVERVIEW
>> 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.
>>
>>
>> WIRE ENCODING
>> 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.
>>
>