github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/internal/ackhandler/sent_packet_handler.go (about)

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