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