mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-10-31 00:08:08 -04:00
99 lines
3.5 KiB
Go
99 lines
3.5 KiB
Go
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
|
|
}
|
|
}
|