package ackhandler
import (
"fmt"
"github.com/quic-go/quic-go/internal/monotime"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/utils"
"github.com/quic-go/quic-go/internal/wire"
)
type ReceivedPacketHandler struct {
initialPackets *receivedPacketTracker
handshakePackets *receivedPacketTracker
appDataPackets appDataReceivedPacketTracker
lowest1RTTPacket protocol .PacketNumber
}
func NewReceivedPacketHandler (logger utils .Logger ) *ReceivedPacketHandler {
return &ReceivedPacketHandler {
initialPackets : newReceivedPacketTracker (),
handshakePackets : newReceivedPacketTracker (),
appDataPackets : *newAppDataReceivedPacketTracker (logger ),
lowest1RTTPacket : protocol .InvalidPacketNumber ,
}
}
func (h *ReceivedPacketHandler ) ReceivedPacket (
pn protocol .PacketNumber ,
ecn protocol .ECN ,
encLevel protocol .EncryptionLevel ,
rcvTime monotime .Time ,
ackEliciting bool ,
) error {
switch encLevel {
case protocol .EncryptionInitial :
return h .initialPackets .ReceivedPacket (pn , ecn , ackEliciting )
case protocol .EncryptionHandshake :
if h .handshakePackets == nil {
return nil
}
return h .handshakePackets .ReceivedPacket (pn , ecn , ackEliciting )
case protocol .Encryption0RTT :
if h .lowest1RTTPacket != protocol .InvalidPacketNumber && pn > h .lowest1RTTPacket {
return fmt .Errorf ("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet" , pn , h .lowest1RTTPacket )
}
return h .appDataPackets .ReceivedPacket (pn , ecn , rcvTime , ackEliciting )
case protocol .Encryption1RTT :
if h .lowest1RTTPacket == protocol .InvalidPacketNumber || pn < h .lowest1RTTPacket {
h .lowest1RTTPacket = pn
}
return h .appDataPackets .ReceivedPacket (pn , ecn , rcvTime , ackEliciting )
default :
panic (fmt .Sprintf ("received packet with unknown encryption level: %s" , encLevel ))
}
}
func (h *ReceivedPacketHandler ) IgnorePacketsBelow (pn protocol .PacketNumber ) {
h .appDataPackets .IgnoreBelow (pn )
}
func (h *ReceivedPacketHandler ) DropPackets (encLevel protocol .EncryptionLevel ) {
switch encLevel {
case protocol .EncryptionInitial :
h .initialPackets = nil
case protocol .EncryptionHandshake :
h .handshakePackets = nil
case protocol .Encryption0RTT :
default :
panic (fmt .Sprintf ("Cannot drop keys for encryption level %s" , encLevel ))
}
}
func (h *ReceivedPacketHandler ) GetAlarmTimeout () monotime .Time {
return h .appDataPackets .GetAlarmTimeout ()
}
func (h *ReceivedPacketHandler ) GetAckFrame (encLevel protocol .EncryptionLevel , now monotime .Time , onlyIfQueued bool ) *wire .AckFrame {
switch encLevel {
case protocol .EncryptionInitial :
if h .initialPackets != nil {
return h .initialPackets .GetAckFrame ()
}
return nil
case protocol .EncryptionHandshake :
if h .handshakePackets != nil {
return h .handshakePackets .GetAckFrame ()
}
return nil
case protocol .Encryption1RTT :
return h .appDataPackets .GetAckFrame (now , onlyIfQueued )
default :
return nil
}
}
func (h *ReceivedPacketHandler ) IsPotentiallyDuplicate (pn protocol .PacketNumber , encLevel protocol .EncryptionLevel ) bool {
switch encLevel {
case protocol .EncryptionInitial :
if h .initialPackets != nil {
return h .initialPackets .IsPotentiallyDuplicate (pn )
}
case protocol .EncryptionHandshake :
if h .handshakePackets != nil {
return h .handshakePackets .IsPotentiallyDuplicate (pn )
}
case protocol .Encryption0RTT , protocol .Encryption1RTT :
return h .appDataPackets .IsPotentiallyDuplicate (pn )
}
panic ("unexpected encryption level" )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .