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

     1  package ackhandler
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/mikelsr/quic-go/internal/protocol"
     8  	"github.com/mikelsr/quic-go/internal/utils"
     9  	"github.com/mikelsr/quic-go/internal/wire"
    10  )
    11  
    12  type receivedPacketHandler struct {
    13  	sentPackets sentPacketTracker
    14  
    15  	initialPackets   *receivedPacketTracker
    16  	handshakePackets *receivedPacketTracker
    17  	appDataPackets   *receivedPacketTracker
    18  
    19  	lowest1RTTPacket protocol.PacketNumber
    20  }
    21  
    22  var _ ReceivedPacketHandler = &receivedPacketHandler{}
    23  
    24  func newReceivedPacketHandler(
    25  	sentPackets sentPacketTracker,
    26  	rttStats *utils.RTTStats,
    27  	logger utils.Logger,
    28  ) ReceivedPacketHandler {
    29  	return &receivedPacketHandler{
    30  		sentPackets:      sentPackets,
    31  		initialPackets:   newReceivedPacketTracker(rttStats, logger),
    32  		handshakePackets: newReceivedPacketTracker(rttStats, logger),
    33  		appDataPackets:   newReceivedPacketTracker(rttStats, logger),
    34  		lowest1RTTPacket: protocol.InvalidPacketNumber,
    35  	}
    36  }
    37  
    38  func (h *receivedPacketHandler) ReceivedPacket(
    39  	pn protocol.PacketNumber,
    40  	ecn protocol.ECN,
    41  	encLevel protocol.EncryptionLevel,
    42  	rcvTime time.Time,
    43  	shouldInstigateAck bool,
    44  ) error {
    45  	h.sentPackets.ReceivedPacket(encLevel)
    46  	switch encLevel {
    47  	case protocol.EncryptionInitial:
    48  		return h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
    49  	case protocol.EncryptionHandshake:
    50  		return h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
    51  	case protocol.Encryption0RTT:
    52  		if h.lowest1RTTPacket != protocol.InvalidPacketNumber && pn > h.lowest1RTTPacket {
    53  			return fmt.Errorf("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet", pn, h.lowest1RTTPacket)
    54  		}
    55  		return h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
    56  	case protocol.Encryption1RTT:
    57  		if h.lowest1RTTPacket == protocol.InvalidPacketNumber || pn < h.lowest1RTTPacket {
    58  			h.lowest1RTTPacket = pn
    59  		}
    60  		if err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck); err != nil {
    61  			return err
    62  		}
    63  		h.appDataPackets.IgnoreBelow(h.sentPackets.GetLowestPacketNotConfirmedAcked())
    64  		return nil
    65  	default:
    66  		panic(fmt.Sprintf("received packet with unknown encryption level: %s", encLevel))
    67  	}
    68  }
    69  
    70  func (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
    71  	//nolint:exhaustive // 1-RTT packet number space is never dropped.
    72  	switch encLevel {
    73  	case protocol.EncryptionInitial:
    74  		h.initialPackets = nil
    75  	case protocol.EncryptionHandshake:
    76  		h.handshakePackets = nil
    77  	case protocol.Encryption0RTT:
    78  		// Nothing to do here.
    79  		// If we are rejecting 0-RTT, no 0-RTT packets will have been decrypted.
    80  	default:
    81  		panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel))
    82  	}
    83  }
    84  
    85  func (h *receivedPacketHandler) GetAlarmTimeout() time.Time {
    86  	var initialAlarm, handshakeAlarm time.Time
    87  	if h.initialPackets != nil {
    88  		initialAlarm = h.initialPackets.GetAlarmTimeout()
    89  	}
    90  	if h.handshakePackets != nil {
    91  		handshakeAlarm = h.handshakePackets.GetAlarmTimeout()
    92  	}
    93  	oneRTTAlarm := h.appDataPackets.GetAlarmTimeout()
    94  	return utils.MinNonZeroTime(utils.MinNonZeroTime(initialAlarm, handshakeAlarm), oneRTTAlarm)
    95  }
    96  
    97  func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, onlyIfQueued bool) *wire.AckFrame {
    98  	var ack *wire.AckFrame
    99  	//nolint:exhaustive // 0-RTT packets can't contain ACK frames.
   100  	switch encLevel {
   101  	case protocol.EncryptionInitial:
   102  		if h.initialPackets != nil {
   103  			ack = h.initialPackets.GetAckFrame(onlyIfQueued)
   104  		}
   105  	case protocol.EncryptionHandshake:
   106  		if h.handshakePackets != nil {
   107  			ack = h.handshakePackets.GetAckFrame(onlyIfQueued)
   108  		}
   109  	case protocol.Encryption1RTT:
   110  		// 0-RTT packets can't contain ACK frames
   111  		return h.appDataPackets.GetAckFrame(onlyIfQueued)
   112  	default:
   113  		return nil
   114  	}
   115  	// For Initial and Handshake ACKs, the delay time is ignored by the receiver.
   116  	// Set it to 0 in order to save bytes.
   117  	if ack != nil {
   118  		ack.DelayTime = 0
   119  	}
   120  	return ack
   121  }
   122  
   123  func (h *receivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool {
   124  	switch encLevel {
   125  	case protocol.EncryptionInitial:
   126  		if h.initialPackets != nil {
   127  			return h.initialPackets.IsPotentiallyDuplicate(pn)
   128  		}
   129  	case protocol.EncryptionHandshake:
   130  		if h.handshakePackets != nil {
   131  			return h.handshakePackets.IsPotentiallyDuplicate(pn)
   132  		}
   133  	case protocol.Encryption0RTT, protocol.Encryption1RTT:
   134  		return h.appDataPackets.IsPotentiallyDuplicate(pn)
   135  	}
   136  	panic("unexpected encryption level")
   137  }