From adada506b8570c735f43ece64a369fb8a3c8ba3b Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 30 Jan 2018 10:19:37 +1100 Subject: [PATCH 1/4] Rationalize stream 0 flow control This leaves the exemption to the stream-level flow control for Initial and Retry packets only (previously it was Initial only). But, to address the possibility that the flow control limit is too small for the entire handshake it permits the sending of MAX_STREAM_DATA (and STREAM_BLOCKED) during the handshake. Closes #1074, #725, #1082. --- draft-ietf-quic-tls.md | 18 +++++------------- draft-ietf-quic-transport.md | 29 ++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 751e3bee20..291b70a7b4 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1269,20 +1269,12 @@ both protected with 1-RTT keys and contains an `ACK` frame. ### Updates to Data and Stream Limits -`MAX_DATA`, `MAX_STREAM_DATA`, `BLOCKED`, `STREAM_BLOCKED`, and `MAX_STREAM_ID` -frames MUST NOT be sent unprotected. +`MAX_DATA`, `BLOCKED`, `MAX_STREAM_ID`, and `STREAM_ID_BLOCKED` frames MUST NOT +be sent unprotected. -Though data is exchanged on stream 0, the initial flow control window on that -stream is sufficiently large to allow the TLS handshake to complete. This -limits the maximum size of the TLS handshake and would prevent a server or -client from using an abnormally large certificate chain. - -Stream 0 is exempt from the connection-level flow control window. - -Consequently, there is no need to signal being blocked on flow control. - -Similarly, there is no need to increase the number of allowed streams until the -handshake completes. +`MAX_STREAM_DATA` and `STREAM_BLOCKED` frames MUST NOT be sent unprotected +unless they identify stream 0. Stream 0 is exempt from the connection-level +flow control window and stream limits. ### Handshake Failures diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 0c6fc8db79..1fed8e4e46 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2825,7 +2825,6 @@ actually lost. ### Special Considerations for Packetization Layer PMTU Discovery - The PADDING frame provides a useful option for PMTU probe packets that does not exist in other transports. PADDING frames generate acknowledgements, but their content need not be delivered reliably. PADDING frames may delay the delivery of @@ -3251,6 +3250,7 @@ advertise a smaller maximum ID. A sender may receive MAX_STREAM_ID frames out of order; a sender MUST therefore ignore any MAX_STREAM_ID that does not increase the maximum. + ## Sending and Receiving Data Once a stream is created, endpoints may use the stream to send and receive data. @@ -3270,14 +3270,25 @@ delivery, as long as it is not in violation of the receiver's flow control limits. An endpoint MUST NOT send data on any stream without ensuring that it is within -the data limits set by its peer. The cryptographic handshake stream, Stream 0, -is exempt from the connection-level data limits established by MAX_DATA. Data on -stream 0 other than the initial cryptographic handshake message is still subject -to stream-level data limits and MAX_STREAM_DATA. This message is exempt -from flow control because it needs to be sent in a single packet regardless of -the server's flow control state. This rule applies even for 0-RTT handshakes -where the remembered value of MAX_STREAM_DATA would not permit sending a full -initial cryptographic handshake message. +the data limits set by its peer. + +The cryptographic handshake stream, Stream 0, is exempt from the +connection-level data limits established by MAX_DATA. That is, data sent on +stream 0 is not counted against the limit expressed by MAX_DATA. Data on stream +0 is still subject to stream-level data limits and MAX_STREAM_DATA. + +Data sent in the Initial and Retry packets do not count toward stream 0 flow +control limits. These packet types do not permit the sending of data in +multiple packets, so there is no opportunity for a peer to send MAX_STREAM_DATA +frames. Note also that the next packet sent after either of these packets might +start at a stream offset of 0. Thus, the only limit on the size of the +cryptographic handshake messages these packets contain is determined by the MTU. + +Endpoints MUST respect the stream flow control limit set by their peer. A +client might exceed this limit when sending an Initial packet and so might need +to await a MAX_STREAM_DATA frame from the server before it can sent additional +STREAM frames. A client MAY send ACK frames and STREAM_BLOCKED frames for +stream 0. Flow control is described in detail in {{flow-control}}, and congestion control is described in the companion document {{QUIC-RECOVERY}}. From 0bf027a92c0bda6597bd68e7eff47e7dbfb5d939 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 30 Jan 2018 11:18:25 +1100 Subject: [PATCH 2/4] Updates in response to review --- draft-ietf-quic-transport.md | 48 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1fed8e4e46..31f9797d7e 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -3272,24 +3272,6 @@ limits. An endpoint MUST NOT send data on any stream without ensuring that it is within the data limits set by its peer. -The cryptographic handshake stream, Stream 0, is exempt from the -connection-level data limits established by MAX_DATA. That is, data sent on -stream 0 is not counted against the limit expressed by MAX_DATA. Data on stream -0 is still subject to stream-level data limits and MAX_STREAM_DATA. - -Data sent in the Initial and Retry packets do not count toward stream 0 flow -control limits. These packet types do not permit the sending of data in -multiple packets, so there is no opportunity for a peer to send MAX_STREAM_DATA -frames. Note also that the next packet sent after either of these packets might -start at a stream offset of 0. Thus, the only limit on the size of the -cryptographic handshake messages these packets contain is determined by the MTU. - -Endpoints MUST respect the stream flow control limit set by their peer. A -client might exceed this limit when sending an Initial packet and so might need -to await a MAX_STREAM_DATA frame from the server before it can sent additional -STREAM frames. A client MAY send ACK frames and STREAM_BLOCKED frames for -stream 0. - Flow control is described in detail in {{flow-control}}, and congestion control is described in the companion document {{QUIC-RECOVERY}}. @@ -3385,6 +3367,36 @@ received on all streams, which are used to check for flow control violations. A receiver might use a sum of bytes consumed on all contributing streams to determine the maximum data limit to be advertised. + +### Stream 0 Flow Control + +The cryptographic handshake stream, Stream 0, is exempt from the +connection-level data limits established by MAX_DATA. That is, data sent on +stream 0 is not counted against the limit expressed by MAX_DATA. Data on stream +0 is still subject to stream-level data limits and MAX_STREAM_DATA. + +Data sent in the Initial and Retry packets do not count toward stream 0 flow +control limits. These packet types do not permit the sending of data in +multiple packets, so there is no opportunity for a peer to send MAX_STREAM_DATA +frames. Note that sending a Retry causes stream offsets and flow control to be +reset for subsequent packets. Thus, the only limit on the size of the +cryptographic handshake messages these packets contain is determined by the MTU. + +Endpoints MUST respect the stream flow control limit set by their peer when +sending STREAM frames for stream 0 in packets other than Initial or Retry. A +client might exceed stream flow control limits when sending an Initial packet +and so might need to await a MAX_STREAM_DATA frame from the server before it can +sent additional STREAM frames. Endpoints MAY send STREAM_BLOCKED frames for +stream 0 if they are unable to send due to flow control limits. + +Flow control for stream 0 is reset after the handshake is completed. The limit +is set to the greater of the initial_max_stream_data transport parameter and +current stream offset (that is, the amount of data sent on the stream, excluding +that sent in Retry and any Initial packet that caused a Retry packet to be +sent). This prevents an attacker from modifying an unauthenticated +MAX_STREAM_DATA frame to inflate the flow control limit. + + ## Edge Cases and Other Considerations There are some edge cases which must be considered when dealing with stream and From 2cf3d536d05d19faca2738aca118b7ba503a741a Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 30 Jan 2018 11:54:06 +1100 Subject: [PATCH 3/4] Contributing streams --- 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 31f9797d7e..caafc99cdc 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -3363,12 +3363,13 @@ one of the packets is lost. Connection flow control is a limit to the total bytes of stream data sent in STREAM frames on all streams. A receiver advertises credit for a connection by sending a MAX_DATA frame. A receiver maintains a cumulative sum of bytes -received on all streams, which are used to check for flow control violations. A -receiver might use a sum of bytes consumed on all contributing streams to -determine the maximum data limit to be advertised. +received on all contributing streams (those other than stream 0), which are used +to check for flow control violations. A receiver might use a sum of bytes +consumed on all contributing streams to determine the maximum data limit to be +advertised. -### Stream 0 Flow Control +## Stream 0 Flow Control The cryptographic handshake stream, Stream 0, is exempt from the connection-level data limits established by MAX_DATA. That is, data sent on From 13ab8ad2eb4e9b38a8bcea6cfb3c373f3fefbd31 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 30 Jan 2018 12:00:04 +1100 Subject: [PATCH 4/4] More editorial feedback --- draft-ietf-quic-transport.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index caafc99cdc..29a47e122c 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -3376,19 +3376,17 @@ connection-level data limits established by MAX_DATA. That is, data sent on stream 0 is not counted against the limit expressed by MAX_DATA. Data on stream 0 is still subject to stream-level data limits and MAX_STREAM_DATA. -Data sent in the Initial and Retry packets do not count toward stream 0 flow -control limits. These packet types do not permit the sending of data in -multiple packets, so there is no opportunity for a peer to send MAX_STREAM_DATA -frames. Note that sending a Retry causes stream offsets and flow control to be -reset for subsequent packets. Thus, the only limit on the size of the -cryptographic handshake messages these packets contain is determined by the MTU. - -Endpoints MUST respect the stream flow control limit set by their peer when -sending STREAM frames for stream 0 in packets other than Initial or Retry. A -client might exceed stream flow control limits when sending an Initial packet -and so might need to await a MAX_STREAM_DATA frame from the server before it can -sent additional STREAM frames. Endpoints MAY send STREAM_BLOCKED frames for -stream 0 if they are unable to send due to flow control limits. +Data sent in the Initial and Retry packets are allowed to temporarily exceed +flow control limits on stream 0. These packet types do not permit the sending +of data in multiple packets, so there is no opportunity for a peer to send +MAX_STREAM_DATA frames. Note that sending a Retry causes stream offsets and +flow control to be reset for subsequent packets. Thus, the only limit on the +size of the cryptographic handshake messages these packets contain is determined +by the MTU. + +A client might reach or exceed stream flow control limits when sending an +Initial packet and so might need to await a MAX_STREAM_DATA frame from the +server before it can send additional STREAM frames. Flow control for stream 0 is reset after the handshake is completed. The limit is set to the greater of the initial_max_stream_data transport parameter and @@ -3397,6 +3395,9 @@ that sent in Retry and any Initial packet that caused a Retry packet to be sent). This prevents an attacker from modifying an unauthenticated MAX_STREAM_DATA frame to inflate the flow control limit. +Endpoints MAY send STREAM_BLOCKED frames for stream 0 in Handshake packets if +they are unable to send due to flow control limits. + ## Edge Cases and Other Considerations