Source file src/vendor/golang.org/x/net/quic/acks.go

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

View as plain text