package ackhandler import ( "fmt" "time" "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/congestion" "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol" "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/utils" "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/wire" ) const ( // maximum delay that can be applied to an ACK for a retransmittable packet ackSendDelay = 25 * time.Millisecond // initial maximum number of retransmittable packets received before sending an ack. initialRetransmittablePacketsBeforeAck = 2 // number of retransmittable that an ACK is sent for retransmittablePacketsBeforeAck = 10 // 1/5 RTT delay when doing ack decimation ackDecimationDelay = 1.0 / 4 // 1/8 RTT delay when doing ack decimation shortAckDecimationDelay = 1.0 / 8 // Minimum number of packets received before ack decimation is enabled. // This intends to avoid the beginning of slow start, when CWNDs may be // rapidly increasing. minReceivedBeforeAckDecimation = 100 // Maximum number of packets to ack immediately after a missing packet for // fast retransmission to kick in at the sender. This limit is created to // reduce the number of acks sent that have no benefit for fast retransmission. // Set to the number of nacks needed for fast retransmit plus one for protection // against an ack loss maxPacketsAfterNewMissing = 4 ) type receivedPacketHandler struct { initialPackets *receivedPacketTracker handshakePackets *receivedPacketTracker oneRTTPackets *receivedPacketTracker } var _ ReceivedPacketHandler = &receivedPacketHandler{} // NewReceivedPacketHandler creates a new receivedPacketHandler func NewReceivedPacketHandler( rttStats *congestion.RTTStats, logger utils.Logger, version protocol.VersionNumber, ) ReceivedPacketHandler { return &receivedPacketHandler{ initialPackets: newReceivedPacketTracker(rttStats, logger, version), handshakePackets: newReceivedPacketTracker(rttStats, logger, version), oneRTTPackets: newReceivedPacketTracker(rttStats, logger, version), } } func (h *receivedPacketHandler) ReceivedPacket( pn protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time, shouldInstigateAck bool, ) error { switch encLevel { case protocol.EncryptionInitial: return h.initialPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) case protocol.EncryptionHandshake: return h.handshakePackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) case protocol.Encryption1RTT: return h.oneRTTPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) default: return fmt.Errorf("received packet with unknown encryption level: %s", encLevel) } } // only to be used with 1-RTT packets func (h *receivedPacketHandler) IgnoreBelow(pn protocol.PacketNumber) { h.oneRTTPackets.IgnoreBelow(pn) } func (h *receivedPacketHandler) GetAlarmTimeout() time.Time { initialAlarm := h.initialPackets.GetAlarmTimeout() handshakeAlarm := h.handshakePackets.GetAlarmTimeout() oneRTTAlarm := h.oneRTTPackets.GetAlarmTimeout() return utils.MinNonZeroTime(utils.MinNonZeroTime(initialAlarm, handshakeAlarm), oneRTTAlarm) } func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel) *wire.AckFrame { switch encLevel { case protocol.EncryptionInitial: return h.initialPackets.GetAckFrame() case protocol.EncryptionHandshake: return h.handshakePackets.GetAckFrame() case protocol.Encryption1RTT: return h.oneRTTPackets.GetAckFrame() default: return nil } }