golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/acks.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "time" 11 ) 12 13 // ackState tracks packets received from a peer within a number space. 14 // It handles packet deduplication (don't process the same packet twice) and 15 // determines the timing and content of ACK frames. 16 type ackState struct { 17 seen rangeset[packetNumber] 18 19 // The time at which we must send an ACK frame, even if we have no other data to send. 20 nextAck time.Time 21 22 // The time we received the largest-numbered packet in seen. 23 maxRecvTime time.Time 24 25 // The largest-numbered ack-eliciting packet in seen. 26 maxAckEliciting packetNumber 27 28 // The number of ack-eliciting packets in seen that we have not yet acknowledged. 29 unackedAckEliciting int 30 } 31 32 // shouldProcess reports whether a packet should be handled or discarded. 33 func (acks *ackState) shouldProcess(num packetNumber) bool { 34 if packetNumber(acks.seen.min()) > num { 35 // We've discarded the state for this range of packet numbers. 36 // Discard the packet rather than potentially processing a duplicate. 37 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.3-5 38 return false 39 } 40 if acks.seen.contains(num) { 41 // Discard duplicate packets. 42 return false 43 } 44 return true 45 } 46 47 // receive records receipt of a packet. 48 func (acks *ackState) receive(now time.Time, space numberSpace, num packetNumber, ackEliciting bool) { 49 if ackEliciting { 50 acks.unackedAckEliciting++ 51 if acks.mustAckImmediately(space, num) { 52 acks.nextAck = now 53 } else if acks.nextAck.IsZero() { 54 // This packet does not need to be acknowledged immediately, 55 // but the ack must not be intentionally delayed by more than 56 // the max_ack_delay transport parameter we sent to the peer. 57 // 58 // We always delay acks by the maximum allowed, less the timer 59 // granularity. ("[max_ack_delay] SHOULD include the receiver's 60 // expected delays in alarms firing.") 61 // 62 // https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.28.1 63 acks.nextAck = now.Add(maxAckDelay - timerGranularity) 64 } 65 if num > acks.maxAckEliciting { 66 acks.maxAckEliciting = num 67 } 68 } 69 70 acks.seen.add(num, num+1) 71 if num == acks.seen.max() { 72 acks.maxRecvTime = now 73 } 74 75 // Limit the total number of ACK ranges by dropping older ranges. 76 // 77 // Remembering more ranges results in larger ACK frames. 78 // 79 // Remembering a large number of ranges could result in ACK frames becoming 80 // too large to fit in a packet, in which case we will silently drop older 81 // ranges during packet construction. 82 // 83 // Remembering fewer ranges can result in unnecessary retransmissions, 84 // since we cannot accept packets older than the oldest remembered range. 85 // 86 // The limit here is completely arbitrary. If it seems wrong, it probably is. 87 // 88 // https://www.rfc-editor.org/rfc/rfc9000#section-13.2.3 89 const maxAckRanges = 8 90 if overflow := acks.seen.numRanges() - maxAckRanges; overflow > 0 { 91 acks.seen.removeranges(0, overflow) 92 } 93 } 94 95 // mustAckImmediately reports whether an ack-eliciting packet must be acknowledged immediately, 96 // or whether the ack may be deferred. 97 func (acks *ackState) mustAckImmediately(space numberSpace, num packetNumber) bool { 98 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1 99 if space != appDataSpace { 100 // "[...] all ack-eliciting Initial and Handshake packets [...]" 101 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-2 102 return true 103 } 104 if num < acks.maxAckEliciting { 105 // "[...] when the received packet has a packet number less than another 106 // ack-eliciting packet that has been received [...]" 107 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-8.1 108 return true 109 } 110 if acks.seen.rangeContaining(acks.maxAckEliciting).end != num { 111 // "[...] when the packet has a packet number larger than the highest-numbered 112 // ack-eliciting packet that has been received and there are missing packets 113 // between that packet and this packet." 114 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-8.2 115 // 116 // This case is a bit tricky. Let's say we've received: 117 // 0, ack-eliciting 118 // 1, ack-eliciting 119 // 3, NOT ack eliciting 120 // 121 // We have sent ACKs for 0 and 1. If we receive ack-eliciting packet 2, 122 // we do not need to send an immediate ACK, because there are no missing 123 // packets between it and the highest-numbered ack-eliciting packet (1). 124 // If we receive ack-eliciting packet 4, we do need to send an immediate ACK, 125 // because there's a gap (the missing packet 2). 126 // 127 // We check for this by looking up the ACK range which contains the 128 // highest-numbered ack-eliciting packet: [0, 1) in the above example. 129 // If the range ends just before the packet we are now processing, 130 // there are no gaps. If it does not, there must be a gap. 131 return true 132 } 133 // "[...] SHOULD send an ACK frame after receiving at least two ack-eliciting packets." 134 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.2 135 // 136 // This ack frequency takes a substantial toll on performance, however. 137 // Follow the behavior of Google QUICHE: 138 // Ack every other packet for the first 100 packets, and then ack every 10th packet. 139 // This keeps ack frequency high during the beginning of slow start when CWND is 140 // increasing rapidly. 141 packetsBeforeAck := 2 142 if acks.seen.max() > 100 { 143 packetsBeforeAck = 10 144 } 145 return acks.unackedAckEliciting >= packetsBeforeAck 146 } 147 148 // shouldSendAck reports whether the connection should send an ACK frame at this time, 149 // in an ACK-only packet if necessary. 150 func (acks *ackState) shouldSendAck(now time.Time) bool { 151 return !acks.nextAck.IsZero() && !acks.nextAck.After(now) 152 } 153 154 // acksToSend returns the set of packet numbers to ACK at this time, and the current ack delay. 155 // It may return acks even if shouldSendAck returns false, when there are unacked 156 // ack-eliciting packets whose ack is being delayed. 157 func (acks *ackState) acksToSend(now time.Time) (nums rangeset[packetNumber], ackDelay time.Duration) { 158 if acks.nextAck.IsZero() && acks.unackedAckEliciting == 0 { 159 return nil, 0 160 } 161 // "[...] the delays intentionally introduced between the time the packet with the 162 // largest packet number is received and the time an acknowledgement is sent." 163 // https://www.rfc-editor.org/rfc/rfc9000#section-13.2.5-1 164 delay := now.Sub(acks.maxRecvTime) 165 if delay < 0 { 166 delay = 0 167 } 168 return acks.seen, delay 169 } 170 171 // sentAck records that an ACK frame has been sent. 172 func (acks *ackState) sentAck() { 173 acks.nextAck = time.Time{} 174 acks.unackedAckEliciting = 0 175 } 176 177 // handleAck records that an ack has been received for a ACK frame we sent 178 // containing the given Largest Acknowledged field. 179 func (acks *ackState) handleAck(largestAcked packetNumber) { 180 // We can stop acking packets less or equal to largestAcked. 181 // https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.4-1 182 // 183 // We rely on acks.seen containing the largest packet number that has been successfully 184 // processed, so we retain the range containing largestAcked and discard previous ones. 185 acks.seen.sub(0, acks.seen.rangeContaining(largestAcked).start) 186 } 187 188 // largestSeen reports the largest seen packet. 189 func (acks *ackState) largestSeen() packetNumber { 190 return acks.seen.max() 191 }