limit number of packets stored in SentPacketHandler

fixes #140
This commit is contained in:
Marten Seemann
2016-05-24 16:06:48 +07:00
parent 931687e9a4
commit e2254f1bbd
7 changed files with 52 additions and 2 deletions

View File

@@ -19,6 +19,7 @@ type SentPacketHandler interface {
GetLargestObserved() protocol.PacketNumber
CongestionAllowsSending() bool
CheckForError() error
TimeToFirstRTO() time.Duration
}

View File

@@ -17,8 +17,10 @@ var (
// ErrEntropy occurs when an ACK with incorrect entropy is received
ErrEntropy = qerr.Error(qerr.InvalidAckData, "wrong entropy")
// ErrMapAccess occurs when a NACK contains invalid NACK ranges
ErrMapAccess = qerr.Error(qerr.InvalidAckData, "Packet does not exist in PacketHistory")
errAckForUnsentPacket = qerr.Error(qerr.InvalidAckData, "Received ACK for an unsent package")
ErrMapAccess = qerr.Error(qerr.InvalidAckData, "Packet does not exist in PacketHistory")
// ErrTooManyTrackedSentPackets occurs when the sentPacketHandler has to keep track of too many packets
ErrTooManyTrackedSentPackets = errors.New("To many outstanding not-acked and not retransmitted packets.")
errAckForUnsentPacket = qerr.Error(qerr.InvalidAckData, "Received ACK for an unsent package")
)
var (
@@ -103,6 +105,8 @@ func (h *sentPacketHandler) queuePacketForRetransmission(packet *Packet) {
h.bytesInFlight -= packet.Length
h.retransmissionQueue = append(h.retransmissionQueue, packet)
packet.Retransmitted = true
// TODO: delete from packetHistory once we drop support for version smaller than QUIC 33
}
func (h *sentPacketHandler) SentPacket(packet *Packet) error {
@@ -278,6 +282,14 @@ func (h *sentPacketHandler) CongestionAllowsSending() bool {
return h.BytesInFlight() <= h.congestion.GetCongestionWindow()
}
func (h *sentPacketHandler) CheckForError() error {
length := len(h.retransmissionQueue) + len(h.packetHistory)
if uint32(length) > protocol.MaxTrackedSentPackets {
return ErrTooManyTrackedSentPackets
}
return nil
}
func (h *sentPacketHandler) getRTO() time.Duration {
rto := h.congestion.RetransmissionDelay()
if rto == 0 {

View File

@@ -162,6 +162,20 @@ var _ = Describe("SentPacketHandler", func() {
})
})
Context("DOS mitigation", func() {
It("checks the size of the packet history, for unacked packets", func() {
for i := uint32(1); i < protocol.MaxTrackedSentPackets+10; i++ {
packet := Packet{PacketNumber: protocol.PacketNumber(i), Frames: []frames.Frame{&streamFrame}, Length: 1}
err := handler.SentPacket(&packet)
Expect(err).ToNot(HaveOccurred())
}
err := handler.CheckForError()
Expect(err).To(MatchError(ErrTooManyTrackedSentPackets))
})
// TODO: add a test that the length of the retransmission queue is considered, even if packets have already been ACKed. Relevant once we drop support for QUIC 33 and earlier
})
Context("ACK entropy calculations", func() {
var packets []*Packet
var entropy EntropyAccumulator