github.com/MerlinKodo/quic-go@v0.39.2/internal/ackhandler/received_packet_handler.go (about)

     1  package ackhandler
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/MerlinKodo/quic-go/internal/protocol"
     8  	"github.com/MerlinKodo/quic-go/internal/utils"
     9  	"github.com/MerlinKodo/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  	ackEliciting bool,
    44  ) error {
    45  	h.sentPackets.ReceivedPacket(encLevel)
    46  	switch encLevel {
    47  	case protocol.EncryptionInitial:
    48  		return h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
    49  	case protocol.EncryptionHandshake:
    50  		// The Handshake packet number space might already have been dropped as a result
    51  		// of processing the CRYPTO frame that was contained in this packet.
    52  		if h.handshakePackets == nil {
    53  			return nil
    54  		}
    55  		return h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
    56  	case protocol.Encryption0RTT:
    57  		if h.lowest1RTTPacket != protocol.InvalidPacketNumber && pn > h.lowest1RTTPacket {
    58  			return fmt.Errorf("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet", pn, h.lowest1RTTPacket)
    59  		}
    60  		return h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
    61  	case protocol.Encryption1RTT:
    62  		if h.lowest1RTTPacket == protocol.InvalidPacketNumber || pn < h.lowest1RTTPacket {
    63  			h.lowest1RTTPacket = pn
    64  		}
    65  		if err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil {
    66  			return err
    67  		}
    68  		h.appDataPackets.IgnoreBelow(h.sentPackets.GetLowestPacketNotConfirmedAcked())
    69  		return nil
    70  	default:
    71  		panic(fmt.Sprintf("received packet with unknown encryption level: %s", encLevel))
    72  	}
    73  }
    74  
    75  func (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
    76  	//nolint:exhaustive // 1-RTT packet number space is never dropped.
    77  	switch encLevel {
    78  	case protocol.EncryptionInitial:
    79  		h.initialPackets = nil
    80  	case protocol.EncryptionHandshake:
    81  		h.handshakePackets = nil
    82  	case protocol.Encryption0RTT:
    83  		// Nothing to do here.
    84  		// If we are rejecting 0-RTT, no 0-RTT packets will have been decrypted.
    85  	default:
    86  		panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel))
    87  	}
    88  }
    89  
    90  func (h *receivedPacketHandler) GetAlarmTimeout() time.Time {
    91  	var initialAlarm, handshakeAlarm time.Time
    92  	if h.initialPackets != nil {
    93  		initialAlarm = h.initialPackets.GetAlarmTimeout()
    94  	}
    95  	if h.handshakePackets != nil {
    96  		handshakeAlarm = h.handshakePackets.GetAlarmTimeout()
    97  	}
    98  	oneRTTAlarm := h.appDataPackets.GetAlarmTimeout()
    99  	return utils.MinNonZeroTime(utils.MinNonZeroTime(initialAlarm, handshakeAlarm), oneRTTAlarm)
   100  }
   101  
   102  func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, onlyIfQueued bool) *wire.AckFrame {
   103  	var ack *wire.AckFrame
   104  	//nolint:exhaustive // 0-RTT packets can't contain ACK frames.
   105  	switch encLevel {
   106  	case protocol.EncryptionInitial:
   107  		if h.initialPackets != nil {
   108  			ack = h.initialPackets.GetAckFrame(onlyIfQueued)
   109  		}
   110  	case protocol.EncryptionHandshake:
   111  		if h.handshakePackets != nil {
   112  			ack = h.handshakePackets.GetAckFrame(onlyIfQueued)
   113  		}
   114  	case protocol.Encryption1RTT:
   115  		// 0-RTT packets can't contain ACK frames
   116  		return h.appDataPackets.GetAckFrame(onlyIfQueued)
   117  	default:
   118  		return nil
   119  	}
   120  	// For Initial and Handshake ACKs, the delay time is ignored by the receiver.
   121  	// Set it to 0 in order to save bytes.
   122  	if ack != nil {
   123  		ack.DelayTime = 0
   124  	}
   125  	return ack
   126  }
   127  
   128  func (h *receivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool {
   129  	switch encLevel {
   130  	case protocol.EncryptionInitial:
   131  		if h.initialPackets != nil {
   132  			return h.initialPackets.IsPotentiallyDuplicate(pn)
   133  		}
   134  	case protocol.EncryptionHandshake:
   135  		if h.handshakePackets != nil {
   136  			return h.handshakePackets.IsPotentiallyDuplicate(pn)
   137  		}
   138  	case protocol.Encryption0RTT, protocol.Encryption1RTT:
   139  		return h.appDataPackets.IsPotentiallyDuplicate(pn)
   140  	}
   141  	panic("unexpected encryption level")
   142  }