diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index c3270254eb..280ee3574c 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -424,13 +424,13 @@ from HTTP/2, see {{h2-frames}}. All frames have the following format: ~~~~~~~~~~ drawing - 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 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Length (i) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type (8) | Flags (8) | Frame Payload (*) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Type (8) | Flags (8) | Frame Payload (*) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-frame title="HTTP/QUIC frame format"} @@ -506,15 +506,15 @@ The flags defined are: 5.3). ~~~~~~~~~~ drawing - 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 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prioritized Request ID (i) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Stream Dependency ID (i) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Weight (8) | - +-+-+-+-+-+-+-+-+ + 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Prioritized Request ID (i) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Stream Dependency ID (i) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Weight (8) | ++-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-priority title="PRIORITY frame payload"} @@ -634,13 +634,13 @@ consisting of an unsigned 16-bit setting identifier and a length-prefixed binary value. ~~~~~~~~~~~~~~~ drawing - 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 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Identifier (16) | Length (i) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Contents (?) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Identifier (16) | Length (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Contents (?) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~~~~~~ {: #fig-ext-settings title="SETTINGS value format"} @@ -717,13 +717,13 @@ The PUSH_PROMISE frame (type=0x05) is used to carry a request header set from server to client, as in HTTP/2. The PUSH_PROMISE frame defines no flags. ~~~~~~~~~~ drawing - 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 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Push ID (i) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Header Block (*) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Push ID (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Header Block (*) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-push-promise title="PUSH_PROMISE frame payload"} diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index d217459fd0..4a5ce0d57a 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -590,37 +590,38 @@ When an ack is received, it may acknowledge 0 or more packets. Pseudocode for OnAckReceived and UpdateRtt follow: ~~~ - OnAckReceived(ack): - largest_acked_packet = ack.largest_acked - // If the largest acked is newly acked, update the RTT. - if (sent_packets[ack.largest_acked]): - latest_rtt = now - sent_packets[ack.largest_acked].time - UpdateRtt(latest_rtt, ack.ack_delay) - // Find all newly acked packets. - for acked_packet in DetermineNewlyAckedPackets(): - OnPacketAcked(acked_packet.packet_number) - - DetectLostPackets(ack.largest_acked_packet) - SetLossDetectionAlarm() - - - UpdateRtt(latest_rtt, ack_delay): - // min_rtt ignores ack delay. - min_rtt = min(min_rtt, latest_rtt) - // Adjust for ack delay if it's plausible. - if (latest_rtt - min_rtt > ack_delay): - latest_rtt -= ack_delay - // Only save into max ack delay if it's used - // for rtt calculation and is not ack only. - if (!sent_packets[ack.largest_acked].ack_only) - max_ack_delay = max(max_ack_delay, ack_delay) - // Based on {{?RFC6298}}. - if (smoothed_rtt == 0): - smoothed_rtt = latest_rtt - rttvar = latest_rtt / 2 - else: - rttvar = 3/4 * rttvar + 1/4 * abs(smoothed_rtt - latest_rtt) - smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * latest_rtt + OnAckReceived(ack): + largest_acked_packet = ack.largest_acked + // If the largest acked is newly acked, update the RTT. + if (sent_packets[ack.largest_acked]): + latest_rtt = now - sent_packets[ack.largest_acked].time + UpdateRtt(latest_rtt, ack.ack_delay) + // Find all newly acked packets. + for acked_packet in DetermineNewlyAckedPackets(): + OnPacketAcked(acked_packet.packet_number) + + DetectLostPackets(ack.largest_acked_packet) + SetLossDetectionAlarm() + + + UpdateRtt(latest_rtt, ack_delay): + // min_rtt ignores ack delay. + min_rtt = min(min_rtt, latest_rtt) + // Adjust for ack delay if it's plausible. + if (latest_rtt - min_rtt > ack_delay): + latest_rtt -= ack_delay + // Only save into max ack delay if it's used + // for rtt calculation and is not ack only. + if (!sent_packets[ack.largest_acked].ack_only) + max_ack_delay = max(max_ack_delay, ack_delay) + // Based on {{?RFC6298}}. + if (smoothed_rtt == 0): + smoothed_rtt = latest_rtt + rttvar = latest_rtt / 2 + else: + rttvar_sample = abs(smoothed_rtt - latest_rtt) + rttvar = 3/4 * rttvar + 1/4 * rttvar_sample + smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * latest_rtt ~~~ ### On Packet Acknowledgment @@ -778,32 +779,33 @@ DetectLostPackets takes one parameter, acked, which is the largest acked packet. Pseudocode for DetectLostPackets follows: ~~~ - DetectLostPackets(largest_acked): - loss_time = 0 - lost_packets = {} - delay_until_lost = infinite - if (kUsingTimeLossDetection): - delay_until_lost = - (1 + time_reordering_fraction) * max(latest_rtt, smoothed_rtt) - else if (largest_acked.packet_number == largest_sent_packet): - // Early retransmit alarm. - delay_until_lost = 5/4 * max(latest_rtt, smoothed_rtt) - foreach (unacked < largest_acked.packet_number): - time_since_sent = now() - unacked.time_sent - delta = largest_acked.packet_number - unacked.packet_number - if (time_since_sent > delay_until_lost): - lost_packets.insert(unacked) - else if (delta > reordering_threshold) - lost_packets.insert(unacked) - else if (loss_time == 0 && delay_until_lost != infinite): - loss_time = now() + delay_until_lost - time_since_sent - - // Inform the congestion controller of lost packets and - // lets it decide whether to retransmit immediately. - if (!lost_packets.empty()) - OnPacketsLost(lost_packets) - foreach (packet in lost_packets) - sent_packets.remove(packet.packet_number) +DetectLostPackets(largest_acked): + loss_time = 0 + lost_packets = {} + delay_until_lost = infinite + if (kUsingTimeLossDetection): + delay_until_lost = + (1 + time_reordering_fraction) * + max(latest_rtt, smoothed_rtt) + else if (largest_acked.packet_number == largest_sent_packet): + // Early retransmit alarm. + delay_until_lost = 5/4 * max(latest_rtt, smoothed_rtt) + foreach (unacked < largest_acked.packet_number): + time_since_sent = now() - unacked.time_sent + delta = largest_acked.packet_number - unacked.packet_number + if (time_since_sent > delay_until_lost): + lost_packets.insert(unacked) + else if (delta > reordering_threshold) + lost_packets.insert(unacked) + else if (loss_time == 0 && delay_until_lost != infinite): + loss_time = now() + delay_until_lost - time_since_sent + + // Inform the congestion controller of lost packets and + // lets it decide whether to retransmit immediately. + if (!lost_packets.empty()) + OnPacketsLost(lost_packets) + foreach (packet in lost_packets) + sent_packets.remove(packet.packet_number) ~~~ ## Discussion diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 839ac6ab35..604e070d29 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -722,10 +722,10 @@ a Label of "client 1rtt" for the client and "server 1rtt" for the server, and the same output Length as the PRF hash function selected by TLS. ~~~ - client_pp_secret_ = - QHKDF-Expand(client_pp_secret_, "client 1rtt", Hash.length) - server_pp_secret_ = - QHKDF-Expand(server_pp_secret_, "server 1rtt", Hash.length) +client_pp_secret_ = + QHKDF-Expand(client_pp_secret_, "client 1rtt", Hash.length) +server_pp_secret_ = + QHKDF-Expand(server_pp_secret_, "server 1rtt", Hash.length) ~~~ This allows for a succession of new secrets to be created as needed. @@ -869,8 +869,8 @@ Section 7.7.1.1 of {{QUIC-TRANSPORT}} also requires a secret to compute packet number gaps on connection ID transitions. That secret is computed as: ~~~ - packet_number_secret = - TLS-Exporter("EXPORTER-QUIC packet number", "", Hash.length) +packet_number_secret = + TLS-Exporter("EXPORTER-QUIC packet number", "", Hash.length) ~~~ # Key Phases