Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
124 lines (112 sloc) 3.91 KB
package ackhandler
import (
"fmt"
"time"
"github.com/lucas-clemente/quic-go/internal/congestion"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/internal/wire"
)
const (
// initial maximum number of ack-eliciting packets received before sending an ack.
initialAckElicitingPacketsBeforeAck = 2
// number of ack-eliciting that an ACK is sent for
ackElicitingPacketsBeforeAck = 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,
) {
switch encLevel {
case protocol.EncryptionInitial:
h.initialPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck)
case protocol.EncryptionHandshake:
h.handshakePackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck)
case protocol.Encryption1RTT:
h.oneRTTPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck)
default:
panic(fmt.Sprintf("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) DropPackets(encLevel protocol.EncryptionLevel) {
switch encLevel {
case protocol.EncryptionInitial:
h.initialPackets = nil
case protocol.EncryptionHandshake:
h.handshakePackets = nil
default:
panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel))
}
}
func (h *receivedPacketHandler) GetAlarmTimeout() time.Time {
var initialAlarm, handshakeAlarm time.Time
if h.initialPackets != nil {
initialAlarm = h.initialPackets.GetAlarmTimeout()
}
if h.handshakePackets != nil {
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 {
var ack *wire.AckFrame
switch encLevel {
case protocol.EncryptionInitial:
if h.initialPackets != nil {
ack = h.initialPackets.GetAckFrame()
}
case protocol.EncryptionHandshake:
if h.handshakePackets != nil {
ack = h.handshakePackets.GetAckFrame()
}
case protocol.Encryption1RTT:
return h.oneRTTPackets.GetAckFrame()
default:
return nil
}
// For Initial and Handshake ACKs, the delay time is ignored by the receiver.
// Set it to 0 in order to save bytes.
if ack != nil {
ack.DelayTime = 0
}
return ack
}
You can’t perform that action at this time.