github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/ackhandler/sent_packet_handler.go (about)

     1  package ackhandler
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sync"
     7  	"time"
     8  
     9  	congestionExt "github.com/apernet/quic-go/congestion"
    10  	"github.com/apernet/quic-go/internal/congestion"
    11  	"github.com/apernet/quic-go/internal/protocol"
    12  	"github.com/apernet/quic-go/internal/qerr"
    13  	"github.com/apernet/quic-go/internal/utils"
    14  	"github.com/apernet/quic-go/internal/wire"
    15  	"github.com/apernet/quic-go/logging"
    16  )
    17  
    18  const (
    19  	// Maximum reordering in time space before time based loss detection considers a packet lost.
    20  	// Specified as an RTT multiplier.
    21  	timeThreshold = 9.0 / 8
    22  	// Maximum reordering in packets before packet threshold loss detection considers a packet lost.
    23  	packetThreshold = 3
    24  	// Before validating the client's address, the server won't send more than 3x bytes than it received.
    25  	amplificationFactor = 3
    26  	// We use Retry packets to derive an RTT estimate. Make sure we don't set the RTT to a super low value yet.
    27  	minRTTAfterRetry = 5 * time.Millisecond
    28  	// The PTO duration uses exponential backoff, but is truncated to a maximum value, as allowed by RFC 8961, section 4.4.
    29  	maxPTODuration = 60 * time.Second
    30  )
    31  
    32  type packetNumberSpace struct {
    33  	history *sentPacketHistory
    34  	pns     packetNumberGenerator
    35  
    36  	lossTime                   time.Time
    37  	lastAckElicitingPacketTime time.Time
    38  
    39  	largestAcked protocol.PacketNumber
    40  	largestSent  protocol.PacketNumber
    41  }
    42  
    43  func newPacketNumberSpace(initialPN protocol.PacketNumber, skipPNs bool) *packetNumberSpace {
    44  	var pns packetNumberGenerator
    45  	if skipPNs {
    46  		pns = newSkippingPacketNumberGenerator(initialPN, protocol.SkipPacketInitialPeriod, protocol.SkipPacketMaxPeriod)
    47  	} else {
    48  		pns = newSequentialPacketNumberGenerator(initialPN)
    49  	}
    50  	return &packetNumberSpace{
    51  		history:      newSentPacketHistory(),
    52  		pns:          pns,
    53  		largestSent:  protocol.InvalidPacketNumber,
    54  		largestAcked: protocol.InvalidPacketNumber,
    55  	}
    56  }
    57  
    58  type sentPacketHandler struct {
    59  	initialPackets   *packetNumberSpace
    60  	handshakePackets *packetNumberSpace
    61  	appDataPackets   *packetNumberSpace
    62  
    63  	// Do we know that the peer completed address validation yet?
    64  	// Always true for the server.
    65  	peerCompletedAddressValidation bool
    66  	bytesReceived                  protocol.ByteCount
    67  	bytesSent                      protocol.ByteCount
    68  	// Have we validated the peer's address yet?
    69  	// Always true for the client.
    70  	peerAddressValidated bool
    71  
    72  	handshakeConfirmed bool
    73  
    74  	// lowestNotConfirmedAcked is the lowest packet number that we sent an ACK for, but haven't received confirmation, that this ACK actually arrived
    75  	// example: we send an ACK for packets 90-100 with packet number 20
    76  	// once we receive an ACK from the peer for packet 20, the lowestNotConfirmedAcked is 101
    77  	// Only applies to the application-data packet number space.
    78  	lowestNotConfirmedAcked protocol.PacketNumber
    79  
    80  	ackedPackets     []*packet // to avoid allocations in detectAndRemoveAckedPackets
    81  	ackedPacketsInfo []congestionExt.AckedPacketInfo
    82  	lostPacketsInfo  []congestionExt.LostPacketInfo
    83  
    84  	bytesInFlight protocol.ByteCount
    85  
    86  	congestion      congestion.SendAlgorithmWithDebugInfos
    87  	congestionMutex sync.RWMutex
    88  	rttStats        *utils.RTTStats
    89  
    90  	// The number of times a PTO has been sent without receiving an ack.
    91  	ptoCount uint32
    92  	ptoMode  SendMode
    93  	// The number of PTO probe packets that should be sent.
    94  	// Only applies to the application-data packet number space.
    95  	numProbesToSend int
    96  
    97  	// The alarm timeout
    98  	alarm time.Time
    99  
   100  	enableECN  bool
   101  	ecnTracker ecnHandler
   102  
   103  	perspective protocol.Perspective
   104  
   105  	tracer *logging.ConnectionTracer
   106  	logger utils.Logger
   107  }
   108  
   109  var (
   110  	_ SentPacketHandler = &sentPacketHandler{}
   111  	_ sentPacketTracker = &sentPacketHandler{}
   112  )
   113  
   114  // clientAddressValidated indicates whether the address was validated beforehand by an address validation token.
   115  // If the address was validated, the amplification limit doesn't apply. It has no effect for a client.
   116  func newSentPacketHandler(
   117  	initialPN protocol.PacketNumber,
   118  	initialMaxDatagramSize protocol.ByteCount,
   119  	rttStats *utils.RTTStats,
   120  	clientAddressValidated bool,
   121  	enableECN bool,
   122  	pers protocol.Perspective,
   123  	tracer *logging.ConnectionTracer,
   124  	logger utils.Logger,
   125  ) *sentPacketHandler {
   126  	congestion := congestion.NewCubicSender(
   127  		congestion.DefaultClock{},
   128  		rttStats,
   129  		initialMaxDatagramSize,
   130  		true, // use Reno
   131  		tracer,
   132  	)
   133  
   134  	h := &sentPacketHandler{
   135  		peerCompletedAddressValidation: pers == protocol.PerspectiveServer,
   136  		peerAddressValidated:           pers == protocol.PerspectiveClient || clientAddressValidated,
   137  		initialPackets:                 newPacketNumberSpace(initialPN, false),
   138  		handshakePackets:               newPacketNumberSpace(0, false),
   139  		appDataPackets:                 newPacketNumberSpace(0, true),
   140  		rttStats:                       rttStats,
   141  		congestion:                     congestion,
   142  		perspective:                    pers,
   143  		tracer:                         tracer,
   144  		logger:                         logger,
   145  	}
   146  	if enableECN {
   147  		h.enableECN = true
   148  		h.ecnTracker = newECNTracker(logger, tracer)
   149  	}
   150  	return h
   151  }
   152  
   153  func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) {
   154  	if p.includedInBytesInFlight {
   155  		if p.Length > h.bytesInFlight {
   156  			panic("negative bytes_in_flight")
   157  		}
   158  		h.bytesInFlight -= p.Length
   159  		p.includedInBytesInFlight = false
   160  	}
   161  }
   162  
   163  func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
   164  	// The server won't await address validation after the handshake is confirmed.
   165  	// This applies even if we didn't receive an ACK for a Handshake packet.
   166  	if h.perspective == protocol.PerspectiveClient && encLevel == protocol.EncryptionHandshake {
   167  		h.peerCompletedAddressValidation = true
   168  	}
   169  	// remove outstanding packets from bytes_in_flight
   170  	if encLevel == protocol.EncryptionInitial || encLevel == protocol.EncryptionHandshake {
   171  		pnSpace := h.getPacketNumberSpace(encLevel)
   172  		// We might already have dropped this packet number space.
   173  		if pnSpace == nil {
   174  			return
   175  		}
   176  		pnSpace.history.Iterate(func(p *packet) (bool, error) {
   177  			h.removeFromBytesInFlight(p)
   178  			return true, nil
   179  		})
   180  	}
   181  	// drop the packet history
   182  	//nolint:exhaustive // Not every packet number space can be dropped.
   183  	switch encLevel {
   184  	case protocol.EncryptionInitial:
   185  		h.initialPackets = nil
   186  	case protocol.EncryptionHandshake:
   187  		h.handshakePackets = nil
   188  	case protocol.Encryption0RTT:
   189  		// This function is only called when 0-RTT is rejected,
   190  		// and not when the client drops 0-RTT keys when the handshake completes.
   191  		// When 0-RTT is rejected, all application data sent so far becomes invalid.
   192  		// Delete the packets from the history and remove them from bytes_in_flight.
   193  		h.appDataPackets.history.Iterate(func(p *packet) (bool, error) {
   194  			if p.EncryptionLevel != protocol.Encryption0RTT && !p.skippedPacket {
   195  				return false, nil
   196  			}
   197  			h.removeFromBytesInFlight(p)
   198  			h.appDataPackets.history.Remove(p.PacketNumber)
   199  			return true, nil
   200  		})
   201  	default:
   202  		panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel))
   203  	}
   204  	if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {
   205  		h.tracer.UpdatedPTOCount(0)
   206  	}
   207  	h.ptoCount = 0
   208  	h.numProbesToSend = 0
   209  	h.ptoMode = SendNone
   210  	h.setLossDetectionTimer()
   211  }
   212  
   213  func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount) {
   214  	wasAmplificationLimit := h.isAmplificationLimited()
   215  	h.bytesReceived += n
   216  	if wasAmplificationLimit && !h.isAmplificationLimited() {
   217  		h.setLossDetectionTimer()
   218  	}
   219  }
   220  
   221  func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel) {
   222  	if h.perspective == protocol.PerspectiveServer && l == protocol.EncryptionHandshake && !h.peerAddressValidated {
   223  		h.peerAddressValidated = true
   224  		h.setLossDetectionTimer()
   225  	}
   226  }
   227  
   228  func (h *sentPacketHandler) packetsInFlight() int {
   229  	packetsInFlight := h.appDataPackets.history.Len()
   230  	if h.handshakePackets != nil {
   231  		packetsInFlight += h.handshakePackets.history.Len()
   232  	}
   233  	if h.initialPackets != nil {
   234  		packetsInFlight += h.initialPackets.history.Len()
   235  	}
   236  	return packetsInFlight
   237  }
   238  
   239  func (h *sentPacketHandler) SentPacket(
   240  	t time.Time,
   241  	pn, largestAcked protocol.PacketNumber,
   242  	streamFrames []StreamFrame,
   243  	frames []Frame,
   244  	encLevel protocol.EncryptionLevel,
   245  	ecn protocol.ECN,
   246  	size protocol.ByteCount,
   247  	isPathMTUProbePacket bool,
   248  ) {
   249  	h.bytesSent += size
   250  
   251  	pnSpace := h.getPacketNumberSpace(encLevel)
   252  	if h.logger.Debug() && pnSpace.history.HasOutstandingPackets() {
   253  		for p := max(0, pnSpace.largestSent+1); p < pn; p++ {
   254  			h.logger.Debugf("Skipping packet number %d", p)
   255  		}
   256  	}
   257  
   258  	pnSpace.largestSent = pn
   259  	isAckEliciting := len(streamFrames) > 0 || len(frames) > 0
   260  
   261  	if isAckEliciting {
   262  		pnSpace.lastAckElicitingPacketTime = t
   263  		h.bytesInFlight += size
   264  		if h.numProbesToSend > 0 {
   265  			h.numProbesToSend--
   266  		}
   267  	}
   268  
   269  	cc := h.getCongestionControl()
   270  	cc.OnPacketSent(t, h.bytesInFlight, pn, size, isAckEliciting)
   271  
   272  	if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {
   273  		h.ecnTracker.SentPacket(pn, ecn)
   274  	}
   275  
   276  	if !isAckEliciting {
   277  		pnSpace.history.SentNonAckElicitingPacket(pn)
   278  		if !h.peerCompletedAddressValidation {
   279  			h.setLossDetectionTimer()
   280  		}
   281  		return
   282  	}
   283  
   284  	p := getPacket()
   285  	p.SendTime = t
   286  	p.PacketNumber = pn
   287  	p.EncryptionLevel = encLevel
   288  	p.Length = size
   289  	p.LargestAcked = largestAcked
   290  	p.StreamFrames = streamFrames
   291  	p.Frames = frames
   292  	p.IsPathMTUProbePacket = isPathMTUProbePacket
   293  	p.includedInBytesInFlight = true
   294  
   295  	pnSpace.history.SentAckElicitingPacket(p)
   296  	if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
   297  		h.tracer.UpdatedMetrics(h.rttStats, cc.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
   298  	}
   299  	h.setLossDetectionTimer()
   300  }
   301  
   302  func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace {
   303  	switch encLevel {
   304  	case protocol.EncryptionInitial:
   305  		return h.initialPackets
   306  	case protocol.EncryptionHandshake:
   307  		return h.handshakePackets
   308  	case protocol.Encryption0RTT, protocol.Encryption1RTT:
   309  		return h.appDataPackets
   310  	default:
   311  		panic("invalid packet number space")
   312  	}
   313  }
   314  
   315  func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* contained 1-RTT packet */, error) {
   316  	pnSpace := h.getPacketNumberSpace(encLevel)
   317  
   318  	largestAcked := ack.LargestAcked()
   319  	if largestAcked > pnSpace.largestSent {
   320  		return false, &qerr.TransportError{
   321  			ErrorCode:    qerr.ProtocolViolation,
   322  			ErrorMessage: "received ACK for an unsent packet",
   323  		}
   324  	}
   325  
   326  	// Servers complete address validation when a protected packet is received.
   327  	if h.perspective == protocol.PerspectiveClient && !h.peerCompletedAddressValidation &&
   328  		(encLevel == protocol.EncryptionHandshake || encLevel == protocol.Encryption1RTT) {
   329  		h.peerCompletedAddressValidation = true
   330  		h.logger.Debugf("Peer doesn't await address validation any longer.")
   331  		// Make sure that the timer is reset, even if this ACK doesn't acknowledge any (ack-eliciting) packets.
   332  		h.setLossDetectionTimer()
   333  	}
   334  
   335  	priorInFlight := h.bytesInFlight
   336  	ackedPackets, err := h.detectAndRemoveAckedPackets(ack, encLevel)
   337  	if err != nil || len(ackedPackets) == 0 {
   338  		return false, err
   339  	}
   340  
   341  	cc := h.getCongestionControl()
   342  
   343  	// update the RTT, if the largest acked is newly acknowledged
   344  	if len(ackedPackets) > 0 {
   345  		if p := ackedPackets[len(ackedPackets)-1]; p.PacketNumber == ack.LargestAcked() {
   346  			// don't use the ack delay for Initial and Handshake packets
   347  			var ackDelay time.Duration
   348  			if encLevel == protocol.Encryption1RTT {
   349  				ackDelay = min(ack.DelayTime, h.rttStats.MaxAckDelay())
   350  			}
   351  			h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime)
   352  			if h.logger.Debug() {
   353  				h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())
   354  			}
   355  			cc.MaybeExitSlowStart()
   356  		}
   357  	}
   358  
   359  	// Only inform the ECN tracker about new 1-RTT ACKs if the ACK increases the largest acked.
   360  	if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil && largestAcked > pnSpace.largestAcked {
   361  		congested := h.ecnTracker.HandleNewlyAcked(ackedPackets, int64(ack.ECT0), int64(ack.ECT1), int64(ack.ECNCE))
   362  		if congested {
   363  			cc.OnCongestionEvent(largestAcked, 0, priorInFlight)
   364  		}
   365  	}
   366  
   367  	pnSpace.largestAcked = max(pnSpace.largestAcked, largestAcked)
   368  
   369  	if err := h.detectLostPackets(rcvTime, encLevel); err != nil {
   370  		return false, err
   371  	}
   372  	h.ackedPacketsInfo = h.ackedPacketsInfo[:0]
   373  	var acked1RTTPacket bool
   374  	for _, p := range ackedPackets {
   375  		if p.includedInBytesInFlight && !p.declaredLost {
   376  			cc.OnPacketAcked(p.PacketNumber, p.Length, priorInFlight, rcvTime)
   377  			h.ackedPacketsInfo = append(h.ackedPacketsInfo, congestionExt.AckedPacketInfo{
   378  				PacketNumber: congestionExt.PacketNumber(p.PacketNumber),
   379  				BytesAcked:   congestionExt.ByteCount(p.Length),
   380  			})
   381  		}
   382  		if p.EncryptionLevel == protocol.Encryption1RTT {
   383  			acked1RTTPacket = true
   384  		}
   385  		h.removeFromBytesInFlight(p)
   386  		putPacket(p)
   387  	}
   388  
   389  	if cex, ok := h.congestion.(congestion.SendAlgorithmEx); ok &&
   390  		(len(h.ackedPacketsInfo) != 0 || len(h.lostPacketsInfo) != 0) {
   391  		cex.OnCongestionEventEx(priorInFlight, rcvTime, h.ackedPacketsInfo, h.lostPacketsInfo)
   392  	}
   393  
   394  	// After this point, we must not use ackedPackets any longer!
   395  	// We've already returned the buffers.
   396  	ackedPackets = nil       //nolint:ineffassign // This is just to be on the safe side.
   397  	h.ackedPacketsInfo = nil //nolint:ineffassign // This is just to be on the safe side.
   398  	h.lostPacketsInfo = nil  //nolint:ineffassign // This is just to be on the safe side.
   399  
   400  	// Reset the pto_count unless the client is unsure if the server has validated the client's address.
   401  	if h.peerCompletedAddressValidation {
   402  		if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {
   403  			h.tracer.UpdatedPTOCount(0)
   404  		}
   405  		h.ptoCount = 0
   406  	}
   407  	h.numProbesToSend = 0
   408  
   409  	if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
   410  		h.tracer.UpdatedMetrics(h.rttStats, cc.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
   411  	}
   412  
   413  	h.setLossDetectionTimer()
   414  	return acked1RTTPacket, nil
   415  }
   416  
   417  func (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber {
   418  	return h.lowestNotConfirmedAcked
   419  }
   420  
   421  // Packets are returned in ascending packet number order.
   422  func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encLevel protocol.EncryptionLevel) ([]*packet, error) {
   423  	pnSpace := h.getPacketNumberSpace(encLevel)
   424  	h.ackedPackets = h.ackedPackets[:0]
   425  	ackRangeIndex := 0
   426  	lowestAcked := ack.LowestAcked()
   427  	largestAcked := ack.LargestAcked()
   428  	err := pnSpace.history.Iterate(func(p *packet) (bool, error) {
   429  		// Ignore packets below the lowest acked
   430  		if p.PacketNumber < lowestAcked {
   431  			return true, nil
   432  		}
   433  		// Break after largest acked is reached
   434  		if p.PacketNumber > largestAcked {
   435  			return false, nil
   436  		}
   437  
   438  		if ack.HasMissingRanges() {
   439  			ackRange := ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex]
   440  
   441  			for p.PacketNumber > ackRange.Largest && ackRangeIndex < len(ack.AckRanges)-1 {
   442  				ackRangeIndex++
   443  				ackRange = ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex]
   444  			}
   445  
   446  			if p.PacketNumber < ackRange.Smallest { // packet not contained in ACK range
   447  				return true, nil
   448  			}
   449  			if p.PacketNumber > ackRange.Largest {
   450  				return false, fmt.Errorf("BUG: ackhandler would have acked wrong packet %d, while evaluating range %d -> %d", p.PacketNumber, ackRange.Smallest, ackRange.Largest)
   451  			}
   452  		}
   453  		if p.skippedPacket {
   454  			return false, &qerr.TransportError{
   455  				ErrorCode:    qerr.ProtocolViolation,
   456  				ErrorMessage: fmt.Sprintf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel),
   457  			}
   458  		}
   459  		h.ackedPackets = append(h.ackedPackets, p)
   460  		return true, nil
   461  	})
   462  	if h.logger.Debug() && len(h.ackedPackets) > 0 {
   463  		pns := make([]protocol.PacketNumber, len(h.ackedPackets))
   464  		for i, p := range h.ackedPackets {
   465  			pns[i] = p.PacketNumber
   466  		}
   467  		h.logger.Debugf("\tnewly acked packets (%d): %d", len(pns), pns)
   468  	}
   469  
   470  	for _, p := range h.ackedPackets {
   471  		if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT {
   472  			h.lowestNotConfirmedAcked = max(h.lowestNotConfirmedAcked, p.LargestAcked+1)
   473  		}
   474  
   475  		for _, f := range p.Frames {
   476  			if f.Handler != nil {
   477  				f.Handler.OnAcked(f.Frame)
   478  			}
   479  		}
   480  		for _, f := range p.StreamFrames {
   481  			if f.Handler != nil {
   482  				f.Handler.OnAcked(f.Frame)
   483  			}
   484  		}
   485  		if err := pnSpace.history.Remove(p.PacketNumber); err != nil {
   486  			return nil, err
   487  		}
   488  		if h.tracer != nil && h.tracer.AcknowledgedPacket != nil {
   489  			h.tracer.AcknowledgedPacket(encLevel, p.PacketNumber)
   490  		}
   491  	}
   492  
   493  	return h.ackedPackets, err
   494  }
   495  
   496  func (h *sentPacketHandler) getLossTimeAndSpace() (time.Time, protocol.EncryptionLevel) {
   497  	var encLevel protocol.EncryptionLevel
   498  	var lossTime time.Time
   499  
   500  	if h.initialPackets != nil {
   501  		lossTime = h.initialPackets.lossTime
   502  		encLevel = protocol.EncryptionInitial
   503  	}
   504  	if h.handshakePackets != nil && (lossTime.IsZero() || (!h.handshakePackets.lossTime.IsZero() && h.handshakePackets.lossTime.Before(lossTime))) {
   505  		lossTime = h.handshakePackets.lossTime
   506  		encLevel = protocol.EncryptionHandshake
   507  	}
   508  	if lossTime.IsZero() || (!h.appDataPackets.lossTime.IsZero() && h.appDataPackets.lossTime.Before(lossTime)) {
   509  		lossTime = h.appDataPackets.lossTime
   510  		encLevel = protocol.Encryption1RTT
   511  	}
   512  	return lossTime, encLevel
   513  }
   514  
   515  func (h *sentPacketHandler) getScaledPTO(includeMaxAckDelay bool) time.Duration {
   516  	pto := h.rttStats.PTO(includeMaxAckDelay) << h.ptoCount
   517  	if pto > maxPTODuration || pto <= 0 {
   518  		return maxPTODuration
   519  	}
   520  	return pto
   521  }
   522  
   523  // same logic as getLossTimeAndSpace, but for lastAckElicitingPacketTime instead of lossTime
   524  func (h *sentPacketHandler) getPTOTimeAndSpace() (pto time.Time, encLevel protocol.EncryptionLevel, ok bool) {
   525  	// We only send application data probe packets once the handshake is confirmed,
   526  	// because before that, we don't have the keys to decrypt ACKs sent in 1-RTT packets.
   527  	if !h.handshakeConfirmed && !h.hasOutstandingCryptoPackets() {
   528  		if h.peerCompletedAddressValidation {
   529  			return
   530  		}
   531  		t := time.Now().Add(h.getScaledPTO(false))
   532  		if h.initialPackets != nil {
   533  			return t, protocol.EncryptionInitial, true
   534  		}
   535  		return t, protocol.EncryptionHandshake, true
   536  	}
   537  
   538  	if h.initialPackets != nil {
   539  		encLevel = protocol.EncryptionInitial
   540  		if t := h.initialPackets.lastAckElicitingPacketTime; !t.IsZero() {
   541  			pto = t.Add(h.getScaledPTO(false))
   542  		}
   543  	}
   544  	if h.handshakePackets != nil && !h.handshakePackets.lastAckElicitingPacketTime.IsZero() {
   545  		t := h.handshakePackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(false))
   546  		if pto.IsZero() || (!t.IsZero() && t.Before(pto)) {
   547  			pto = t
   548  			encLevel = protocol.EncryptionHandshake
   549  		}
   550  	}
   551  	if h.handshakeConfirmed && !h.appDataPackets.lastAckElicitingPacketTime.IsZero() {
   552  		t := h.appDataPackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(true))
   553  		if pto.IsZero() || (!t.IsZero() && t.Before(pto)) {
   554  			pto = t
   555  			encLevel = protocol.Encryption1RTT
   556  		}
   557  	}
   558  	return pto, encLevel, true
   559  }
   560  
   561  func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool {
   562  	if h.initialPackets != nil && h.initialPackets.history.HasOutstandingPackets() {
   563  		return true
   564  	}
   565  	if h.handshakePackets != nil && h.handshakePackets.history.HasOutstandingPackets() {
   566  		return true
   567  	}
   568  	return false
   569  }
   570  
   571  func (h *sentPacketHandler) hasOutstandingPackets() bool {
   572  	return h.appDataPackets.history.HasOutstandingPackets() || h.hasOutstandingCryptoPackets()
   573  }
   574  
   575  func (h *sentPacketHandler) setLossDetectionTimer() {
   576  	oldAlarm := h.alarm // only needed in case tracing is enabled
   577  	lossTime, encLevel := h.getLossTimeAndSpace()
   578  	if !lossTime.IsZero() {
   579  		// Early retransmit timer or time loss detection.
   580  		h.alarm = lossTime
   581  		if h.tracer != nil && h.tracer.SetLossTimer != nil && h.alarm != oldAlarm {
   582  			h.tracer.SetLossTimer(logging.TimerTypeACK, encLevel, h.alarm)
   583  		}
   584  		return
   585  	}
   586  
   587  	// Cancel the alarm if amplification limited.
   588  	if h.isAmplificationLimited() {
   589  		h.alarm = time.Time{}
   590  		if !oldAlarm.IsZero() {
   591  			h.logger.Debugf("Canceling loss detection timer. Amplification limited.")
   592  			if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
   593  				h.tracer.LossTimerCanceled()
   594  			}
   595  		}
   596  		return
   597  	}
   598  
   599  	// Cancel the alarm if no packets are outstanding
   600  	if !h.hasOutstandingPackets() && h.peerCompletedAddressValidation {
   601  		h.alarm = time.Time{}
   602  		if !oldAlarm.IsZero() {
   603  			h.logger.Debugf("Canceling loss detection timer. No packets in flight.")
   604  			if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
   605  				h.tracer.LossTimerCanceled()
   606  			}
   607  		}
   608  		return
   609  	}
   610  
   611  	// PTO alarm
   612  	ptoTime, encLevel, ok := h.getPTOTimeAndSpace()
   613  	if !ok {
   614  		if !oldAlarm.IsZero() {
   615  			h.alarm = time.Time{}
   616  			h.logger.Debugf("Canceling loss detection timer. No PTO needed..")
   617  			if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
   618  				h.tracer.LossTimerCanceled()
   619  			}
   620  		}
   621  		return
   622  	}
   623  	h.alarm = ptoTime
   624  	if h.tracer != nil && h.tracer.SetLossTimer != nil && h.alarm != oldAlarm {
   625  		h.tracer.SetLossTimer(logging.TimerTypePTO, encLevel, h.alarm)
   626  	}
   627  }
   628  
   629  func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) error {
   630  	h.lostPacketsInfo = h.lostPacketsInfo[:0]
   631  	pnSpace := h.getPacketNumberSpace(encLevel)
   632  	pnSpace.lossTime = time.Time{}
   633  
   634  	maxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
   635  	lossDelay := time.Duration(timeThreshold * maxRTT)
   636  
   637  	// Minimum time of granularity before packets are deemed lost.
   638  	lossDelay = max(lossDelay, protocol.TimerGranularity)
   639  
   640  	// Packets sent before this time are deemed lost.
   641  	lostSendTime := now.Add(-lossDelay)
   642  
   643  	cc := h.getCongestionControl()
   644  
   645  	priorInFlight := h.bytesInFlight
   646  	err := pnSpace.history.Iterate(func(p *packet) (bool, error) {
   647  		if p.PacketNumber > pnSpace.largestAcked {
   648  			return false, nil
   649  		}
   650  
   651  		var packetLost bool
   652  		if p.SendTime.Before(lostSendTime) {
   653  			packetLost = true
   654  			if !p.skippedPacket {
   655  				if h.logger.Debug() {
   656  					h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber)
   657  				}
   658  				if h.tracer != nil && h.tracer.LostPacket != nil {
   659  					h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold)
   660  				}
   661  			}
   662  		} else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold {
   663  			packetLost = true
   664  			if !p.skippedPacket {
   665  				if h.logger.Debug() {
   666  					h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber)
   667  				}
   668  				if h.tracer != nil && h.tracer.LostPacket != nil {
   669  					h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold)
   670  				}
   671  			}
   672  		} else if pnSpace.lossTime.IsZero() {
   673  			// Note: This conditional is only entered once per call
   674  			lossTime := p.SendTime.Add(lossDelay)
   675  			if h.logger.Debug() {
   676  				h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", p.PacketNumber, encLevel, lossDelay, lossTime)
   677  			}
   678  			pnSpace.lossTime = lossTime
   679  		}
   680  		if packetLost {
   681  			pnSpace.history.DeclareLost(p.PacketNumber)
   682  			if !p.skippedPacket {
   683  				// the bytes in flight need to be reduced no matter if the frames in this packet will be retransmitted
   684  				h.removeFromBytesInFlight(p)
   685  				h.queueFramesForRetransmission(p)
   686  				if !p.IsPathMTUProbePacket {
   687  					cc.OnCongestionEvent(p.PacketNumber, p.Length, priorInFlight)
   688  				}
   689  				h.lostPacketsInfo = append(h.lostPacketsInfo, congestionExt.LostPacketInfo{
   690  					PacketNumber: congestionExt.PacketNumber(p.PacketNumber),
   691  					BytesLost:    congestionExt.ByteCount(p.Length),
   692  				})
   693  				if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {
   694  					h.ecnTracker.LostPacket(p.PacketNumber)
   695  				}
   696  			}
   697  		}
   698  		return true, nil
   699  	})
   700  	return err
   701  }
   702  
   703  func (h *sentPacketHandler) OnLossDetectionTimeout() error {
   704  	defer h.setLossDetectionTimer()
   705  	priorInFlight := h.bytesInFlight
   706  	earliestLossTime, encLevel := h.getLossTimeAndSpace()
   707  	if !earliestLossTime.IsZero() {
   708  		if h.logger.Debug() {
   709  			h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", earliestLossTime)
   710  		}
   711  		if h.tracer != nil && h.tracer.LossTimerExpired != nil {
   712  			h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)
   713  		}
   714  		// Early retransmit or time loss detection
   715  		err := h.detectLostPackets(time.Now(), encLevel)
   716  
   717  		if cex, ok := h.congestion.(congestion.SendAlgorithmEx); ok &&
   718  			len(h.lostPacketsInfo) != 0 {
   719  			cex.OnCongestionEventEx(priorInFlight, time.Now(), nil, h.lostPacketsInfo)
   720  		}
   721  
   722  		return err
   723  	}
   724  
   725  	// PTO
   726  	// When all outstanding are acknowledged, the alarm is canceled in
   727  	// setLossDetectionTimer. This doesn't reset the timer in the session though.
   728  	// When OnAlarm is called, we therefore need to make sure that there are
   729  	// actually packets outstanding.
   730  	if h.bytesInFlight == 0 && !h.peerCompletedAddressValidation {
   731  		h.ptoCount++
   732  		h.numProbesToSend++
   733  		if h.initialPackets != nil {
   734  			h.ptoMode = SendPTOInitial
   735  		} else if h.handshakePackets != nil {
   736  			h.ptoMode = SendPTOHandshake
   737  		} else {
   738  			return errors.New("sentPacketHandler BUG: PTO fired, but bytes_in_flight is 0 and Initial and Handshake already dropped")
   739  		}
   740  		return nil
   741  	}
   742  
   743  	_, encLevel, ok := h.getPTOTimeAndSpace()
   744  	if !ok {
   745  		return nil
   746  	}
   747  	if ps := h.getPacketNumberSpace(encLevel); !ps.history.HasOutstandingPackets() && !h.peerCompletedAddressValidation {
   748  		return nil
   749  	}
   750  	h.ptoCount++
   751  	if h.logger.Debug() {
   752  		h.logger.Debugf("Loss detection alarm for %s fired in PTO mode. PTO count: %d", encLevel, h.ptoCount)
   753  	}
   754  	if h.tracer != nil {
   755  		if h.tracer.LossTimerExpired != nil {
   756  			h.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel)
   757  		}
   758  		if h.tracer.UpdatedPTOCount != nil {
   759  			h.tracer.UpdatedPTOCount(h.ptoCount)
   760  		}
   761  	}
   762  	h.numProbesToSend += 2
   763  	//nolint:exhaustive // We never arm a PTO timer for 0-RTT packets.
   764  	switch encLevel {
   765  	case protocol.EncryptionInitial:
   766  		h.ptoMode = SendPTOInitial
   767  	case protocol.EncryptionHandshake:
   768  		h.ptoMode = SendPTOHandshake
   769  	case protocol.Encryption1RTT:
   770  		// skip a packet number in order to elicit an immediate ACK
   771  		pn := h.PopPacketNumber(protocol.Encryption1RTT)
   772  		h.getPacketNumberSpace(protocol.Encryption1RTT).history.SkippedPacket(pn)
   773  		h.ptoMode = SendPTOAppData
   774  	default:
   775  		return fmt.Errorf("PTO timer in unexpected encryption level: %s", encLevel)
   776  	}
   777  	return nil
   778  }
   779  
   780  func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time {
   781  	return h.alarm
   782  }
   783  
   784  func (h *sentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN {
   785  	if !h.enableECN {
   786  		return protocol.ECNUnsupported
   787  	}
   788  	if !isShortHeaderPacket {
   789  		return protocol.ECNNon
   790  	}
   791  	return h.ecnTracker.Mode()
   792  }
   793  
   794  func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) {
   795  	pnSpace := h.getPacketNumberSpace(encLevel)
   796  	pn := pnSpace.pns.Peek()
   797  	// See section 17.1 of RFC 9000.
   798  	return pn, protocol.GetPacketNumberLengthForHeader(pn, pnSpace.largestAcked)
   799  }
   800  
   801  func (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) protocol.PacketNumber {
   802  	pnSpace := h.getPacketNumberSpace(encLevel)
   803  	skipped, pn := pnSpace.pns.Pop()
   804  	if skipped {
   805  		skippedPN := pn - 1
   806  		pnSpace.history.SkippedPacket(skippedPN)
   807  		if h.logger.Debug() {
   808  			h.logger.Debugf("Skipping packet number %d", skippedPN)
   809  		}
   810  	}
   811  	return pn
   812  }
   813  
   814  func (h *sentPacketHandler) SendMode(now time.Time) SendMode {
   815  	numTrackedPackets := h.appDataPackets.history.Len()
   816  	if h.initialPackets != nil {
   817  		numTrackedPackets += h.initialPackets.history.Len()
   818  	}
   819  	if h.handshakePackets != nil {
   820  		numTrackedPackets += h.handshakePackets.history.Len()
   821  	}
   822  
   823  	if h.isAmplificationLimited() {
   824  		h.logger.Debugf("Amplification window limited. Received %d bytes, already sent out %d bytes", h.bytesReceived, h.bytesSent)
   825  		return SendNone
   826  	}
   827  	// Don't send any packets if we're keeping track of the maximum number of packets.
   828  	// Note that since MaxOutstandingSentPackets is smaller than MaxTrackedSentPackets,
   829  	// we will stop sending out new data when reaching MaxOutstandingSentPackets,
   830  	// but still allow sending of retransmissions and ACKs.
   831  	if numTrackedPackets >= protocol.MaxTrackedSentPackets {
   832  		if h.logger.Debug() {
   833  			h.logger.Debugf("Limited by the number of tracked packets: tracking %d packets, maximum %d", numTrackedPackets, protocol.MaxTrackedSentPackets)
   834  		}
   835  		return SendNone
   836  	}
   837  	if h.numProbesToSend > 0 {
   838  		return h.ptoMode
   839  	}
   840  	// Only send ACKs if we're congestion limited.
   841  	cc := h.getCongestionControl()
   842  	if !cc.CanSend(h.bytesInFlight) {
   843  		if h.logger.Debug() {
   844  			h.logger.Debugf("Congestion limited: bytes in flight %d, window %d", h.bytesInFlight, cc.GetCongestionWindow())
   845  		}
   846  		return SendAck
   847  	}
   848  	if numTrackedPackets >= protocol.MaxOutstandingSentPackets {
   849  		if h.logger.Debug() {
   850  			h.logger.Debugf("Max outstanding limited: tracking %d packets, maximum: %d", numTrackedPackets, protocol.MaxOutstandingSentPackets)
   851  		}
   852  		return SendAck
   853  	}
   854  	if !cc.HasPacingBudget(now) {
   855  		return SendPacingLimited
   856  	}
   857  	return SendAny
   858  }
   859  
   860  func (h *sentPacketHandler) TimeUntilSend() time.Time {
   861  	return h.getCongestionControl().TimeUntilSend(h.bytesInFlight)
   862  }
   863  
   864  func (h *sentPacketHandler) SetMaxDatagramSize(s protocol.ByteCount) {
   865  	h.getCongestionControl().SetMaxDatagramSize(s)
   866  }
   867  
   868  func (h *sentPacketHandler) isAmplificationLimited() bool {
   869  	if h.peerAddressValidated {
   870  		return false
   871  	}
   872  	return h.bytesSent >= amplificationFactor*h.bytesReceived
   873  }
   874  
   875  func (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) bool {
   876  	pnSpace := h.getPacketNumberSpace(encLevel)
   877  	p := pnSpace.history.FirstOutstanding()
   878  	if p == nil {
   879  		return false
   880  	}
   881  	h.queueFramesForRetransmission(p)
   882  	// TODO: don't declare the packet lost here.
   883  	// Keep track of acknowledged frames instead.
   884  	h.removeFromBytesInFlight(p)
   885  	pnSpace.history.DeclareLost(p.PacketNumber)
   886  	return true
   887  }
   888  
   889  func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) {
   890  	if len(p.Frames) == 0 && len(p.StreamFrames) == 0 {
   891  		panic("no frames")
   892  	}
   893  	for _, f := range p.Frames {
   894  		if f.Handler != nil {
   895  			f.Handler.OnLost(f.Frame)
   896  		}
   897  	}
   898  	for _, f := range p.StreamFrames {
   899  		if f.Handler != nil {
   900  			f.Handler.OnLost(f.Frame)
   901  		}
   902  	}
   903  	p.StreamFrames = nil
   904  	p.Frames = nil
   905  }
   906  
   907  func (h *sentPacketHandler) ResetForRetry(now time.Time) error {
   908  	h.bytesInFlight = 0
   909  	var firstPacketSendTime time.Time
   910  	h.initialPackets.history.Iterate(func(p *packet) (bool, error) {
   911  		if firstPacketSendTime.IsZero() {
   912  			firstPacketSendTime = p.SendTime
   913  		}
   914  		if p.declaredLost || p.skippedPacket {
   915  			return true, nil
   916  		}
   917  		h.queueFramesForRetransmission(p)
   918  		return true, nil
   919  	})
   920  	// All application data packets sent at this point are 0-RTT packets.
   921  	// In the case of a Retry, we can assume that the server dropped all of them.
   922  	h.appDataPackets.history.Iterate(func(p *packet) (bool, error) {
   923  		if !p.declaredLost && !p.skippedPacket {
   924  			h.queueFramesForRetransmission(p)
   925  		}
   926  		return true, nil
   927  	})
   928  
   929  	// Only use the Retry to estimate the RTT if we didn't send any retransmission for the Initial.
   930  	// Otherwise, we don't know which Initial the Retry was sent in response to.
   931  	if h.ptoCount == 0 {
   932  		// Don't set the RTT to a value lower than 5ms here.
   933  		h.rttStats.UpdateRTT(max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now)
   934  		if h.logger.Debug() {
   935  			h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())
   936  		}
   937  		if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
   938  			cc := h.getCongestionControl()
   939  			h.tracer.UpdatedMetrics(h.rttStats, cc.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
   940  		}
   941  	}
   942  	h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Peek(), false)
   943  	h.appDataPackets = newPacketNumberSpace(h.appDataPackets.pns.Peek(), true)
   944  	oldAlarm := h.alarm
   945  	h.alarm = time.Time{}
   946  	if h.tracer != nil {
   947  		if h.tracer.UpdatedPTOCount != nil {
   948  			h.tracer.UpdatedPTOCount(0)
   949  		}
   950  		if !oldAlarm.IsZero() && h.tracer.LossTimerCanceled != nil {
   951  			h.tracer.LossTimerCanceled()
   952  		}
   953  	}
   954  	h.ptoCount = 0
   955  	return nil
   956  }
   957  
   958  func (h *sentPacketHandler) SetHandshakeConfirmed() {
   959  	if h.initialPackets != nil {
   960  		panic("didn't drop initial correctly")
   961  	}
   962  	if h.handshakePackets != nil {
   963  		panic("didn't drop handshake correctly")
   964  	}
   965  	h.handshakeConfirmed = true
   966  	// We don't send PTOs for application data packets before the handshake completes.
   967  	// Make sure the timer is armed now, if necessary.
   968  	h.setLossDetectionTimer()
   969  }
   970  
   971  func (h *sentPacketHandler) getCongestionControl() congestion.SendAlgorithmWithDebugInfos {
   972  	h.congestionMutex.RLock()
   973  	cc := h.congestion
   974  	h.congestionMutex.RUnlock()
   975  	return cc
   976  }
   977  
   978  func (h *sentPacketHandler) SetCongestionControl(cc congestionExt.CongestionControl) {
   979  	h.congestionMutex.Lock()
   980  	cc.SetRTTStatsProvider(h.rttStats)
   981  	h.congestion = &ccAdapter{cc}
   982  	h.congestionMutex.Unlock()
   983  }