quicwg / base-drafts

Internet-Drafts that make up the base QUIC specification
https://quicwg.org
1.63k stars 205 forks source link

Asymmetric Connection IDs #1101

Closed ekr closed 6 years ago

ekr commented 6 years ago

Sorry to totally randomize things, but several of us had an offline discussion about asymmetric connection IDs, in which each side specifies the connection ID that the other side should send with. Here's a sketch of what that would look like.

PROTOCOL OVERVIEW

Client                                      Server

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

The initial packet contains:

All the server's packets are sent with the client's receive CID and the transport parameters contain the server's receive CID (ZZZ).

Subsequent packets from the client are sent with the server's receive CID (ZZZ)

Finally, you can send NEW_CONNECTION_ID in either direction to provide a new connection ID for the other side to use.

OTHER DETAILS This design doesn't require variable length CIDs but it's a natural fit. In particular, it doesn't require the C bit in the long header because each side gets to indicate exactly how long a CID it wants, and so sending an empty CID means "don't send me a CID". I haven't heard a good reason why we should let the packet sender decide whether to send a CID or not, and so this is largely for the benefit of middleboxes which doesn't seem like a good reason.

Orthogonally, here's a sketch of a long header with a variable length CID:

    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
   +-+-+-+-+-+-+-+-+---------------+
   |0|C|K| Type (5)|  CID length   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                     [Connection ID (*)]                       +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                      Packet Number (8/16/32)                ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                     Protected Payload (*)                   ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Given that the CID is now variable length, we might or might not want to move it to after the PN.

OPEN ISSUES/PROBLEMS

  1. 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. This might be an argument for the idea of putting both CIDs in the long header that I proposed in Melbourne.

  2. Any asymmetric ID scheme inherently makes stateless reset more difficult, because the server doesn't have the client's CID. It could use a random CID or the server's CID, though. One might not think this is so bad because it's really only an issue for a client which needs stateless routing of packets (the client itself is of course stateful). Previously, this topology was just impossible, so one could argue that this was strictly better, as the client will just fall back to timeout if the routing fails. Of course, you might think that it was really bad too.

hardie commented 6 years ago

On Tue, Feb 6, 2018 at 12:50 PM, ekr notifications@github.com wrote:

Sorry to totally randomize things, but several of us had an offline discussion about asymmetric connection IDs, in which each side specifies the connection ID that the other side should send with. Here's a sketch of what that would look like.

While this is a reasonable sketch of how it would work, it's not clear from it what problem you were trying to solve by switching to this. I can invent some scenarios, but it would help if you could elaborate a bit.

I am also a bit concerned that a client could be configured to use a very small number of connection IDs to all of its QUIC-speaking peers. Since the connection ID is path-visible, that seems like it would have all of the bad possibilities of an observable super cookie (albeit one the server is induced to send, rather than sent along by the client). Obviously, that's a terrible configuration choice, but we have, sadly, seen similar things deployed. Am I misunderstanding the risk there, or is there a way to mitigate you have in mind?

Ted

PROTOCOL OVERVIEW Client Server

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

The initial packet contains:

  • In the header CID field, XXX, which is either (a) a randomly chosen dummy CID (b) a CID which it received from the server in a stateless reset
  • The transport parameters contain the client's receive CID (YYY in the diagram above).

All the server's packets are sent with the client's receive CID and the transport parameters contain the server's receive CID (ZZZ).

Subsequent packets from the client are sent with the server's receive CID (ZZZ)

Finally, you can send NEW_CONNECTION_ID in either direction to provide a new connection ID for the other side to use.

OTHER DETAILS This design doesn't require variable length CIDs but it's a natural fit. In particular, it doesn't require the C bit in the long header because each side gets to indicate exactly how long a CID it wants, and so sending an empty CID means "don't send me a CID". I haven't heard a good reason why we should let the packet sender decide whether to send a CID or not, and so this is largely for the benefit of middleboxes which doesn't seem like a good reason.

Orthogonally, here's a sketch of a long header with a variable length CID:

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

+-+-+-+-+-+-+-+-+---------------+ 0 C K Type (5) CID length +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-

               [Connection ID (*)]                       +

| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Packet Number (8/16/32) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Protected Payload (*) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Given that the CID is now variable length, we might or might not want to move it to after the PN.

OPEN ISSUES/PROBLEMS

1.

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. This might be an argument for the idea of putting both CIDs in the long header that I proposed in Melbourne. 2.

Any asymmetric ID scheme inherently makes stateless reset more difficult, because the server doesn't have the client's CID. It could use a random CID or the server's CID, though. One might not think this is so bad because it's really only an issue for a client which needs stateless routing of packets (the client itself is of course stateful). Previously, this topology was just impossible, so one could argue that this was strictly better, as the client will just fall back to timeout if the routing fails. Of course, you might think that it was really bad too.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/quicwg/base-drafts/issues/1101, or mute the thread https://github.com/notifications/unsubscribe-auth/ABVb5BW2N6_WuM0qj-jPx13F7Hr1j3-gks5tSLspgaJpZM4R7tYt .

mikkelfj commented 6 years ago

Just wondering why you do not elaborate on the existing issue https://github.com/quicwg/base-drafts/issues/1089

ekr commented 6 years ago

Didn't notice it because there were a zillion issues.

On Tue, Feb 6, 2018 at 1:37 PM, MikkelFJ notifications@github.com wrote:

Just wondering why you do not elaborate on the existing issue #1089 https://github.com/quicwg/base-drafts/issues/1089

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/quicwg/base-drafts/issues/1101#issuecomment-363573021, or mute the thread https://github.com/notifications/unsubscribe-auth/ABD1oVPm9BJuK9WVzwNSiFnhuvDhxsuQks5tSMYigaJpZM4R7tYt .

ekr commented 6 years ago

@hardie: basically to have more symmetry in the routing structure between clients and servers. This isn't an issue for HTTP but is more potentially one for peer-to-peer scenarios.

I don't disagree that there's a potential risk here, but there are lots of ways for clients to screw this up, for instance by having a predictable initial ID.

martinthomson commented 6 years ago

1089 it is.