github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/internal/ackhandler/sent_packet_handler.go (about)

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