From 61977b518599e3441fa473651588921c8dd2e783 Mon Sep 17 00:00:00 2001 From: martinduke Date: Sun, 7 Jan 2018 21:05:22 -0800 Subject: [PATCH 1/9] Rewrite text about Version Negotiation This is meant to resolve #1038. I made the following changes: 1) Explicitly state the conditions for each possible server action on receipt of the first packet 2) Use IETF terms like "MUST" when missing. 3) Eliminate redundant text 4) Eliminate all explicit mentions of the 1200-byte limit, as this is defined later in the text, where it also explains exactly how to measure packet size. I'm concerned that just saying "1200 bytes" here might cause people to count IP headers or something. Make them read the definition! I don't believe there's any substantive change to the spec. --- draft-ietf-quic-transport.md | 72 +++++++++++++++--------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 9f7551f4e9..1d1b687ec4 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -899,44 +899,33 @@ SHOULD be discarded if it is not buffered. Discarded packets MAY be logged for diagnostic or security purposes. For servers, packets that aren't associated with a connection potentially create -a new connection. However, only packets that use the long packet header and -that are at least the minimum size defined for the protocol version can be -initial packets. A server MAY discard packets with a short header or packets -that are smaller than the smallest minimum size for any version that the server -supports. A server that discards a packet that cannot be associated with a -connection MAY also generate a stateless reset ({{stateless-reset}}). - -This version of QUIC defines a minimum size for initial packets of 1200 octets -(see {{packetization}}). Versions of QUIC that define smaller minimum initial -packet sizes need to be aware that initial packets will be discarded without -action by servers that only support versions with larger minimums. Clients that -support multiple QUIC versions can avoid this problem by ensuring that they -increase the size of their initial packets to the largest minimum size across -all of the QUIC versions they support. Servers need to recognize initial -packets that are the minimum size of all QUIC versions they support. - - -## Version Negotiation {#version-negotiation} - -QUIC's connection establishment begins with version negotiation, since all -communication between the endpoints, including packet and frame formats, relies -on the two endpoints agreeing on a version. - -A QUIC connection begins with a client sending an Initial packet -({{packet-initial}}). The details of the handshake mechanisms are described in -{{handshake}}, but any Initial packet sent from the client to the server MUST -use the long header format - which includes the version of the protocol being -used - and they MUST be padded to at least 1200 octets. - -The server receives this packet and determines whether it potentially creates a -new connection (see {{packet-handling}}). If the packet might generate a new -connection, the server then checks whether it understands the version that the -client has selected. - -If the packet contains a version that is acceptable to the server, the server +a new connection. A series of tests dictate the allowed actions. + +If the packet uses a short form header, or is not long enough for the size +required for the initial packet of any of its supported versions (as defined +in {{packet-size}}), it cannot create a new connection. In this case, the server +MUST either buffer the packet in case more packets arrive, send a stateless +reset ({{stateless-reset}}), or silently drop it. + +If the packet could create a new connection, the server checks the version +field in the packet header. If a supported version, but not a valid Initial +packet for that version, the server MUST either drop the packet or buffer it in +anticipation of additional packets. + +If a supported version, and a valid Initial packet for that version, the server proceeds with the handshake ({{handshake}}). This commits the server to the version that the client selected. +If an unsupported version, the server MUST send a version negotiation packet +as described in {{send-vn}}. + +Versions of QUIC that define smaller minimum initial packet sizes need to be +aware that initial packets will be discarded without action by servers that only +support versions with larger minimums. Clients that support multiple QUIC +versions can avoid this problem by ensuring that they increase the size of their +initial packets to the largest minimum size across all of the QUIC versions they +support. Servers need to recognize initial packets that are the minimum size of +all QUIC versions they support. ### Sending Version Negotiation Packets {#send-vn} @@ -944,13 +933,10 @@ If the version selected by the client is not acceptable to the server, the server responds with a Version Negotiation packet ({{packet-version}}). This includes a list of versions that the server will accept. -A server sends a Version Negotiation packet for any packet with an unacceptable -version if that packet could create a new connection. This allows a server to -process packets with unsupported versions without retaining state. Though -either the Client Initial packet or the version negotiation packet that is sent -in response could be lost, the client will send new packets until it -successfully receives a response or it abandons the connection attempt. - +This system allows a server to process packets with unsupported versions without +retaining state. Though either the Initial packet or the version negotiation +packet that is sent in response could be lost, the client will send new packets +until it successfully receives a response or it abandons the connection attempt. ### Handling Version Negotiation Packets {#handle-vn} @@ -2746,7 +2732,7 @@ Strategies and implications of the frequency of generating acknowledgments are discussed in more detail in {{QUIC-RECOVERY}}. -## Packet Size +## Packet Size {#packet-size} The QUIC packet size includes the QUIC header and integrity check, but not the UDP or IP header. From bae27776631f1254750fdcef16cf10acc935f024 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 8 Jan 2018 10:33:31 -0800 Subject: [PATCH 2/9] Update to PR #1039 Addressed @martinthomson's issues. Made further edits to be concise and well-organized. --- draft-ietf-quic-transport.md | 96 +++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1d1b687ec4..0a62a43486 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -865,8 +865,8 @@ endpoint, as described in {{termination}}. ## Matching Packets to Connections {#packet-handling} Incoming packets are classified on receipt. Packets can either be associated -with an existing connection, be discarded, or - for servers - potentially create -a new connection. +with an existing connection, or - for servers - potentially create a new +connection. Packets that can be associated with an existing connection are handled according to the current state of that connection. Packets are associated with existing @@ -876,56 +876,62 @@ Packets without connection IDs and long-form packets for connections that have incomplete cryptographic handshakes are associated with an existing connection using the tuple of source and destination IP addresses and ports. -A packet that uses the short header could be associated with an existing -connection with an incomplete cryptographic handshake. Such a packet could be a -valid packet that has been reordered with respect to the long-form packets that -will complete the cryptographic handshake. This might happen after the final -set of cryptographic handshake messages from either peer. These packets are -expected to be correlated with a connection using the tuple of IP addresses and -ports. Packets that might be reordered in this fashion SHOULD be buffered in -anticipation of the handshake completing. +Clients SHOULD discard any packet that cannot be associated with an existing +connection. Discarded packets MAY be logged for diagnostic or security +purposes. -0-RTT packets might be received prior to a Client Initial packet at a server. -If the version of these packets is acceptable to the server, it MAY buffer these -packets in anticipation of receiving a reordered Client Initial packet. +If a server receives a packet not associated with an existing connection, it +executes the following steps, in order: + +The server MUST check if the packet uses a short form header, or is not long +enough for the size required for the initial packet of any QUIC version that +the server supports. See {{packet-size}} for the definition of packet size +and the minimum size in this version of QUIC. If either condition is true, +the packet cannot create a new connection. In this case, the server MUST +either buffer the packet (see {{handshake-buffer}}), send a stateless reset +({{stateless-reset}}), or silently drop it. + +Otherwise, the server checks the version field in the long header. If the +server does not support the chosen version, it MUST send a Version +Negotiation packet as described in {{send-vn}}. + +If the server supports the version, the server operates in accordance with +the specification of that version. For the version described in this +specification, it checks if the packet is a correctly formatted Initial packet. +If so, the server MUST proceed with the handshake ({{handshake}}). This +commits the server to the version that the client selected. If not an Initial +packet, the server MUST either buffer the packet or silently drop it. + +### Handshake Buffering {{#handshake-buffer}} + +Due to packet reordering or loss, subsequent packets for a handshake might +arrive at the server prior to the intended Initial packet. As described above, +servers MAY buffer these packets in anticipation of the Initial packet +arriving later. This is especially useful for 0-RTT packets that routinely +accompany Initial packets. Buffering ensures that data is not lost, which improves performance; conversely, discarding these packets could create false loss signals for the congestion controllers. However, limiting the number and size of buffered packets might be needed to prevent exposure to denial of service. -For clients, any packet that cannot be associated with an existing connection -SHOULD be discarded if it is not buffered. Discarded packets MAY be logged for -diagnostic or security purposes. - -For servers, packets that aren't associated with a connection potentially create -a new connection. A series of tests dictate the allowed actions. - -If the packet uses a short form header, or is not long enough for the size -required for the initial packet of any of its supported versions (as defined -in {{packet-size}}), it cannot create a new connection. In this case, the server -MUST either buffer the packet in case more packets arrive, send a stateless -reset ({{stateless-reset}}), or silently drop it. - -If the packet could create a new connection, the server checks the version -field in the packet header. If a supported version, but not a valid Initial -packet for that version, the server MUST either drop the packet or buffer it in -anticipation of additional packets. - -If a supported version, and a valid Initial packet for that version, the server -proceeds with the handshake ({{handshake}}). This commits the server to the -version that the client selected. - -If an unsupported version, the server MUST send a version negotiation packet -as described in {{send-vn}}. - -Versions of QUIC that define smaller minimum initial packet sizes need to be -aware that initial packets will be discarded without action by servers that only -support versions with larger minimums. Clients that support multiple QUIC -versions can avoid this problem by ensuring that they increase the size of their -initial packets to the largest minimum size across all of the QUIC versions they -support. Servers need to recognize initial packets that are the minimum size of -all QUIC versions they support. +Servers MUST NOT send packets in response to these buffered packets until +the initial packet arrives. + +In this version of QUIC, clients cannot send short form headers prior to a +response from the server. Servers that do not support a version of QUIC that +allows early short headers MUST either respond with a stateless reset or drop +the packet silently. + +## Version Negotiation + +{{packet-handling}} describes the conditions under which endpoints negotiate +versions. + +Clients that support multiple QUIC versions SHOULD pad their Initial packets +to reflect the largest minimum Initial packet size of all their versions. +This ensures that that the server respond if there are any mutually supported +versions. ### Sending Version Negotiation Packets {#send-vn} From 61c10035ada05379a6d1b7efe54238f383882b2b Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 8 Jan 2018 11:25:44 -0800 Subject: [PATCH 3/9] Update draft-ietf-quic-transport.md Addressed @mikkelfj's issue. --- draft-ietf-quic-transport.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 0a62a43486..375fd93fbf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -868,13 +868,14 @@ Incoming packets are classified on receipt. Packets can either be associated with an existing connection, or - for servers - potentially create a new connection. -Packets that can be associated with an existing connection are handled according -to the current state of that connection. Packets are associated with existing -connections using connection ID if it is present; this might include connection -IDs that were advertised using NEW_CONNECTION_ID ({{frame-new-connection-id}}). -Packets without connection IDs and long-form packets for connections that have -incomplete cryptographic handshakes are associated with an existing connection -using the tuple of source and destination IP addresses and ports. +Host handle packets that can be associated with an existing connection +according to the current state of that connection. Short form packets without +connection IDs, and long-form packets for connections that have incomplete +cryptographic handshakes, are associated with an existing connection using the +tuple of source and destination IP addresses and ports. Other packets are +associated with existing connections using connection ID the connection ID +in the header; this might include connection IDs that were advertised using +NEW_CONNECTION_ID ({{frame-new-connection-id}}). Clients SHOULD discard any packet that cannot be associated with an existing connection. Discarded packets MAY be logged for diagnostic or security From a847126f9351898ff5cfa2e4f92762d03169575b Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 8 Jan 2018 14:53:03 -0800 Subject: [PATCH 4/9] Update draft-ietf-quic-transport.md Addressed Martin's issues and fixed one error (first packets might not be "handshake" packets -- they might be 0RTT) --- draft-ietf-quic-transport.md | 53 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 375fd93fbf..246187c208 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -868,14 +868,14 @@ Incoming packets are classified on receipt. Packets can either be associated with an existing connection, or - for servers - potentially create a new connection. -Host handle packets that can be associated with an existing connection -according to the current state of that connection. Short form packets without -connection IDs, and long-form packets for connections that have incomplete -cryptographic handshakes, are associated with an existing connection using the -tuple of source and destination IP addresses and ports. Other packets are -associated with existing connections using connection ID the connection ID -in the header; this might include connection IDs that were advertised using -NEW_CONNECTION_ID ({{frame-new-connection-id}}). +Hosts handle packets that can be associated with an existing connection +according to the current state of that connection. Both short form packets +without connection IDs and long-form packets for connections that have +incomplete cryptographic handshakes are associated with an existing +connection using the tuple of source and destination IP addresses and ports. +Other packets are associated with existing connections using connection ID +the connection ID in the header; this might include connection IDs that were +advertised using NEW_CONNECTION_ID ({{frame-new-connection-id}}). Clients SHOULD discard any packet that cannot be associated with an existing connection. Discarded packets MAY be logged for diagnostic or security @@ -884,32 +884,31 @@ purposes. If a server receives a packet not associated with an existing connection, it executes the following steps, in order: -The server MUST check if the packet uses a short form header, or is not long -enough for the size required for the initial packet of any QUIC version that -the server supports. See {{packet-size}} for the definition of packet size -and the minimum size in this version of QUIC. If either condition is true, -the packet cannot create a new connection. In this case, the server MUST -either buffer the packet (see {{handshake-buffer}}), send a stateless reset -({{stateless-reset}}), or silently drop it. +1. The server MUST check if the packet uses a short form header, or is not +long enough for the size required for the first packet of any QUIC version +that the server supports. See {{packet-size}} for the definition of packet size +and the minimum size of the first packet in this version of QUIC. If either +condition is true, the packet cannot create a new connection. In this case, the +server MUST either buffer the packet (see {{handshake-buffer}}), send a +stateless reset ({{stateless-reset}}), or silently drop it. -Otherwise, the server checks the version field in the long header. If the +2. Otherwise, the server checks the version field in the long header. If the server does not support the chosen version, it MUST send a Version Negotiation packet as described in {{send-vn}}. -If the server supports the version, the server operates in accordance with +3. If the server supports the version, the server operates in accordance with the specification of that version. For the version described in this specification, it checks if the packet is a correctly formatted Initial packet. If so, the server MUST proceed with the handshake ({{handshake}}). This commits the server to the version that the client selected. If not an Initial packet, the server MUST either buffer the packet or silently drop it. -### Handshake Buffering {{#handshake-buffer}} +### Handshake Buffering {#handshake-buffer} -Due to packet reordering or loss, subsequent packets for a handshake might -arrive at the server prior to the intended Initial packet. As described above, -servers MAY buffer these packets in anticipation of the Initial packet -arriving later. This is especially useful for 0-RTT packets that routinely -accompany Initial packets. +Due to packet reordering or loss, subsequent packets might arrive at the server +prior to the Initial packet. As described above, servers MAY buffer these +packets in anticipation of the Initial packet arriving later. This is +especially useful for 0-RTT packets that routinely accompany Initial packets. Buffering ensures that data is not lost, which improves performance; conversely, discarding these packets could create false loss signals for the congestion @@ -926,12 +925,14 @@ the packet silently. ## Version Negotiation -{{packet-handling}} describes the conditions under which endpoints negotiate -versions. +Version negotiation ensures that client and server agree to a QUIC version +that is mutually supported. A server sends a Version Negotiation packet in +response to a packet that might initiate a new connection, see +{{packet-handling}} for details. Clients that support multiple QUIC versions SHOULD pad their Initial packets to reflect the largest minimum Initial packet size of all their versions. -This ensures that that the server respond if there are any mutually supported +This ensures that that the server responds if there are any mutually supported versions. ### Sending Version Negotiation Packets {#send-vn} From f1fe44676ef81ee931ebeea871a849b05932bd16 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 8 Jan 2018 14:55:10 -0800 Subject: [PATCH 5/9] Update draft-ietf-quic-transport.md Whoops, forgot the last of Martin's comments. --- draft-ietf-quic-transport.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 246187c208..daf3a96cb6 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -930,10 +930,11 @@ that is mutually supported. A server sends a Version Negotiation packet in response to a packet that might initiate a new connection, see {{packet-handling}} for details. -Clients that support multiple QUIC versions SHOULD pad their Initial packets -to reflect the largest minimum Initial packet size of all their versions. -This ensures that that the server responds if there are any mutually supported -versions. +The size of the first packet sent by a client will determine whether a server +sends a Version Negotiation packet. Clients that support multiple QUIC +versions SHOULD pad their Initial packets to reflect the largest minimum +Initial packet size of all their versions. This ensures that that the server +responds if there are any mutually supported versions. ### Sending Version Negotiation Packets {#send-vn} From b33d04e972bb073baf434d1d531130ba3661bee5 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 12 Feb 2018 15:08:43 -0800 Subject: [PATCH 6/9] Rewrote completely based on Martin's feedback @martinthomson's suggestions make this much cleaner. Please read it over for mistakes, but I think we're close. --- draft-ietf-quic-transport.md | 112 +++++++++++++++++------------------ 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a1a7ad64d4..7449d83d16 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -861,67 +861,62 @@ different IP or port at either endpoint, due to NAT rebinding or mobility, as described in {{migration}}. Finally a connection may be terminated by either endpoint, as described in {{termination}}. - ## Matching Packets to Connections {#packet-handling} Incoming packets are classified on receipt. Packets can either be associated with an existing connection, or - for servers - potentially create a new connection. -Hosts handle packets that can be associated with an existing connection -according to the current state of that connection. Both short form packets -without connection IDs and long-form packets for connections that have -incomplete cryptographic handshakes are associated with an existing -connection using the tuple of source and destination IP addresses and ports. -Other packets are associated with existing connections using connection ID -the connection ID in the header; this might include connection IDs that were -advertised using NEW_CONNECTION_ID ({{frame-new-connection-id}}). - -Clients SHOULD discard any packet that cannot be associated with an existing -connection. Discarded packets MAY be logged for diagnostic or security -purposes. - -If a server receives a packet not associated with an existing connection, it -executes the following steps, in order: - -1. The server MUST check if the packet uses a short form header, or is not -long enough for the size required for the first packet of any QUIC version -that the server supports. See {{packet-size}} for the definition of packet size -and the minimum size of the first packet in this version of QUIC. If either -condition is true, the packet cannot create a new connection. In this case, the -server MUST either buffer the packet (see {{handshake-buffer}}), send a -stateless reset ({{stateless-reset}}), or silently drop it. - -2. Otherwise, the server checks the version field in the long header. If the -server does not support the chosen version, it MUST send a Version -Negotiation packet as described in {{send-vn}}. - -3. If the server supports the version, the server operates in accordance with -the specification of that version. For the version described in this -specification, it checks if the packet is a correctly formatted Initial packet. -If so, the server MUST proceed with the handshake ({{handshake}}). This -commits the server to the version that the client selected. If not an Initial -packet, the server MUST either buffer the packet or silently drop it. - -### Handshake Buffering {#handshake-buffer} - -Due to packet reordering or loss, subsequent packets might arrive at the server -prior to the Initial packet. As described above, servers MAY buffer these -packets in anticipation of the Initial packet arriving later. This is -especially useful for 0-RTT packets that routinely accompany Initial packets. - -Buffering ensures that data is not lost, which improves performance; conversely, -discarding these packets could create false loss signals for the congestion -controllers. However, limiting the number and size of buffered packets might be -needed to prevent exposure to denial of service. - -Servers MUST NOT send packets in response to these buffered packets until -the initial packet arrives. - -In this version of QUIC, clients cannot send short form headers prior to a -response from the server. Servers that do not support a version of QUIC that -allows early short headers MUST either respond with a stateless reset or drop -the packet silently. +First, hosts try to associate the packet with an existing connection. If the +packet has a connection ID corresponding to an existing connection, QUIC +processes that packet accordingly. Note that a NEW_CONNECTION_ID frame +({{frame-new-connection-id}}) would associate more than one connection ID +with a connection. + +If there is no connection ID, but the packet matches the address/port tuple +of a connection where the host did not require connection IDs, QUIC processes +the packet as part of that connection. Endpoints MUST drop packets that omit +connection IDs if they do not meet both of these criteria. + + +### Client-Specific Behaviors {#client-specific-behaviors} + +If a client receives a packet with an unknown connection ID, and it matches +the tuple of a connection with no received packets, it is a reply to an +Initial packet with a server-generated connection ID and will be processed +accordingly. Clients SHOULD discard any packets with new connection IDs that +do not meet these criteria. + +Note that a successfully associated packet may be a Version Negotiation +packet, which is handled in accordance with {{handle-vn}}. + +Due to packet reordering or loss, clients might receive packets associated +with a connection for which it does not yet have the keys to decrypt it. +Clients MAY drop these packets, or MAY buffer them in anticipation of +later packets that allow it to compute the key. + + +### Server-Specific Behaviors {#server-specific-behaviors} + +If a server receives a packet with an unknown connection ID, an unsupported +version, and is long enough to be an Initial packet for some version +supported by the server, it SHOULD send a Version Negotiation packet as +described in {{send-vn}}. + +Servers MUST drop other packets that contain unsupported versions. + +If the packet is a supported version, and an Initial Packet fully +conforming with the specification, the server MUST proceed with the +handshake ({{handshake}}). This commits the server to the version that the +client selected. + +If the packet is a supported version, and a Handshake or 0RTT packet, the +server MAY buffer a limited number of these packets in anticipation of +a late-arriving Initial Packet. In the event the server later generates +a RETRY packet, this buffer should be purged. Servers MUST NOT send packets +in response to these buffered packets until the Initial packet arrives. + +Servers MUST drop incoming packets under all other circumstances. ## Version Negotiation @@ -947,6 +942,7 @@ retaining state. Though either the Initial packet or the version negotiation packet that is sent in response could be lost, the client will send new packets until it successfully receives a response or it abandons the connection attempt. + ### Handling Version Negotiation Packets {#handle-vn} When the client receives a Version Negotiation packet, it first checks that the @@ -975,9 +971,9 @@ Version Negotiation packet. A client MUST ignore a Version Negotiation packet that lists the client's chosen version. -Version negotiation packets have no cryptographic protection. The -result of the negotiation MUST be revalidated as part of the -cryptographic handshake (see {{version-validation}}). +Version negotiation packets have no cryptographic protection. The result of the +negotiation MUST be revalidated as part of the cryptographic handshake (see +{{version-validation}}). ### Using Reserved Versions From 5271b5952a5b68e9fcd5417d1c78cfe9812a4450 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 12 Feb 2018 22:02:50 -0800 Subject: [PATCH 7/9] Made Mike Bishop's changes --- draft-ietf-quic-transport.md | 39 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 7449d83d16..c1fbad53b2 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -888,33 +888,32 @@ accordingly. Clients SHOULD discard any packets with new connection IDs that do not meet these criteria. Note that a successfully associated packet may be a Version Negotiation -packet, which is handled in accordance with {{handle-vn}}. +packet, which is handled in accordance with {{handle-vn}}. -Due to packet reordering or loss, clients might receive packets associated -with a connection for which it does not yet have the keys to decrypt it. -Clients MAY drop these packets, or MAY buffer them in anticipation of -later packets that allow it to compute the key. +Due to packet reordering or loss, clients might receive packets for a +connection encrypted with a key it has not yet computed. Clients MAY drop +these packets, or MAY buffer them in anticipation of later packets that +allow it to compute the key. ### Server-Specific Behaviors {#server-specific-behaviors} -If a server receives a packet with an unknown connection ID, an unsupported -version, and is long enough to be an Initial packet for some version -supported by the server, it SHOULD send a Version Negotiation packet as -described in {{send-vn}}. +If a server receives a packet that has an unknown connection ID, an +unsupported version, and a sufficient length to be an Initial packet for +some version supported by the server, it SHOULD send a Version Negotiation +packet as described in {{send-vn}}. Servers MUST drop other packets that contain unsupported versions. -If the packet is a supported version, and an Initial Packet fully -conforming with the specification, the server MUST proceed with the -handshake ({{handshake}}). This commits the server to the version that the -client selected. +If the packet is a supported version, and an Initial packet fully +conforming with the specification, the server proceeds with the handshake +({{handshake}}). This commits the server to the version that the client +selected. -If the packet is a supported version, and a Handshake or 0RTT packet, the -server MAY buffer a limited number of these packets in anticipation of -a late-arriving Initial Packet. In the event the server later generates -a RETRY packet, this buffer should be purged. Servers MUST NOT send packets -in response to these buffered packets until the Initial packet arrives. +If the packet is a supported version and a 0-RTT packet, the server MAY +buffer a limited number of these packets in anticipation of a late-arriving +Initial Packet. Clients are forbidden from sending Handshake packets prior +to receiving a server response, so servers SHOULD ignore any such packets. Servers MUST drop incoming packets under all other circumstances. @@ -922,7 +921,7 @@ Servers MUST drop incoming packets under all other circumstances. Version negotiation ensures that client and server agree to a QUIC version that is mutually supported. A server sends a Version Negotiation packet in -response to a packet that might initiate a new connection, see +response to each packet that might initiate a new connection, see {{packet-handling}} for details. The size of the first packet sent by a client will determine whether a server @@ -938,7 +937,7 @@ server responds with a Version Negotiation packet ({{packet-version}}). This includes a list of versions that the server will accept. This system allows a server to process packets with unsupported versions without -retaining state. Though either the Initial packet or the version negotiation +retaining state. Though either the Initial packet or the Version Negotiation packet that is sent in response could be lost, the client will send new packets until it successfully receives a response or it abandons the connection attempt. From 00a80090ef056e340e0cb6813870e0f41edcd11b Mon Sep 17 00:00:00 2001 From: martinduke Date: Thu, 15 Feb 2018 15:52:55 -0800 Subject: [PATCH 8/9] Addressed Martin's Comments I don't think we've converged on whether it is desirable to process an Initial Packet before checking if the connection ID matches on open one; I would like to submit these extensive changes (assuming no other issues) and continue that specific debate in a new issue/PR. --- draft-ietf-quic-transport.md | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index c1fbad53b2..7da97deee4 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -867,7 +867,7 @@ Incoming packets are classified on receipt. Packets can either be associated with an existing connection, or - for servers - potentially create a new connection. -First, hosts try to associate the packet with an existing connection. If the +Hosts try to associate the packet with an existing connection. If the packet has a connection ID corresponding to an existing connection, QUIC processes that packet accordingly. Note that a NEW_CONNECTION_ID frame ({{frame-new-connection-id}}) would associate more than one connection ID @@ -879,7 +879,7 @@ the packet as part of that connection. Endpoints MUST drop packets that omit connection IDs if they do not meet both of these criteria. -### Client-Specific Behaviors {#client-specific-behaviors} +### Client Packet Handling {#client-pkt-handling} If a client receives a packet with an unknown connection ID, and it matches the tuple of a connection with no received packets, it is a reply to an @@ -896,24 +896,29 @@ these packets, or MAY buffer them in anticipation of later packets that allow it to compute the key. -### Server-Specific Behaviors {#server-specific-behaviors} +### Server Packet Handling {#server-pkt-handling} -If a server receives a packet that has an unknown connection ID, an -unsupported version, and a sufficient length to be an Initial packet for -some version supported by the server, it SHOULD send a Version Negotiation -packet as described in {{send-vn}}. +If a server receives a packet that has an unsupported version. and a +sufficient length to be an Initial packet for some version supported +by the server, it SHOULD send a Version Negotiation packet as +described in {{send-vn}}. Servers MAY rate control these packets to +avoid storms of Version Negotiaion packets. Servers MUST drop other packets that contain unsupported versions. -If the packet is a supported version, and an Initial packet fully -conforming with the specification, the server proceeds with the handshake -({{handshake}}). This commits the server to the version that the client -selected. +Packets with a supported version, or no version field, are matched to +a connection as described in {{packet-handling}}. If not matched, the +server continues below. -If the packet is a supported version and a 0-RTT packet, the server MAY -buffer a limited number of these packets in anticipation of a late-arriving -Initial Packet. Clients are forbidden from sending Handshake packets prior -to receiving a server response, so servers SHOULD ignore any such packets. +If the packet is an Initial packet fully conforming with the +specification, the server proceeds with the handshake ({{handshake}}). +This commits the server to the version that the client +selected. + +If the packet is a 0-RTT packet, the server MAY buffer a limited +number of these packets in anticipation of a late-arriving Initial +Packet. Clients are forbidden from sending Handshake packets prior to +receiving a server response, so servers SHOULD ignore any such packets. Servers MUST drop incoming packets under all other circumstances. From 80a47db5b7b6fb28e2cdbb1879c21b9bfc9f5e59 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 16 Feb 2018 11:41:18 +1100 Subject: [PATCH 9/9] Couple of typos --- draft-ietf-quic-transport.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 7da97deee4..235956381a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -898,11 +898,11 @@ allow it to compute the key. ### Server Packet Handling {#server-pkt-handling} -If a server receives a packet that has an unsupported version. and a +If a server receives a packet that has an unsupported version and sufficient length to be an Initial packet for some version supported by the server, it SHOULD send a Version Negotiation packet as described in {{send-vn}}. Servers MAY rate control these packets to -avoid storms of Version Negotiaion packets. +avoid storms of Version Negotiation packets. Servers MUST drop other packets that contain unsupported versions.