github.com/mikelsr/quic-go@v0.36.1-0.20230701132136-1d9415b66898/internal/ackhandler/sent_packet_handler.go (about)

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