refactor sent packet handler tests

This commit is contained in:
Marten Seemann
2018-03-13 22:17:00 +01:00
parent 6a80d50fb9
commit dc4a9b1d86

View File

@@ -1,6 +1,7 @@
package ackhandler package ackhandler
import ( import (
"sort"
"time" "time"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
@@ -34,6 +35,20 @@ func handshakePacket(num protocol.PacketNumber) *Packet {
} }
} }
func createAck(ranges []wire.AckRange) *wire.AckFrame {
sort.Slice(ranges, func(i, j int) bool {
return ranges[i].First > ranges[j].First
})
ack := &wire.AckFrame{
LowestAcked: ranges[len(ranges)-1].First,
LargestAcked: ranges[0].Last,
}
if len(ranges) > 1 {
ack.AckRanges = ranges
}
return ack
}
var _ = Describe("SentPacketHandler", func() { var _ = Describe("SentPacketHandler", func() {
var ( var (
handler *sentPacketHandler handler *sentPacketHandler
@@ -72,76 +87,65 @@ var _ = Describe("SentPacketHandler", func() {
Context("registering sent packets", func() { Context("registering sent packets", func() {
It("accepts two consecutive packets", func() { It("accepts two consecutive packets", func() {
packet1 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(1))
packet2 := Packet{PacketNumber: 2, Frames: []wire.Frame{&streamFrame}, Length: 2} handler.SentPacket(retransmittablePacket(2))
handler.SentPacket(&packet1)
handler.SentPacket(&packet2)
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2))) Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2)))
expectInPacketHistory([]protocol.PacketNumber{1, 2}) expectInPacketHistory([]protocol.PacketNumber{1, 2})
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(3))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
Expect(handler.skippedPackets).To(BeEmpty()) Expect(handler.skippedPackets).To(BeEmpty())
}) })
It("accepts packet number 0", func() { It("accepts packet number 0", func() {
packet1 := Packet{PacketNumber: 0, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(0))
packet2 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 2}
handler.SentPacket(&packet1)
Expect(handler.lastSentPacketNumber).To(BeZero()) Expect(handler.lastSentPacketNumber).To(BeZero())
handler.SentPacket(&packet2) handler.SentPacket(retransmittablePacket(1))
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1))) Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1)))
expectInPacketHistory([]protocol.PacketNumber{0, 1}) expectInPacketHistory([]protocol.PacketNumber{0, 1})
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(3))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
Expect(handler.skippedPackets).To(BeEmpty()) Expect(handler.skippedPackets).To(BeEmpty())
}) })
It("stores the sent time", func() { It("stores the sent time", func() {
packet := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(1))
handler.SentPacket(&packet)
Expect(getPacket(1).sendTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1)) Expect(getPacket(1).sendTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1))
}) })
It("does not store non-retransmittable packets", func() { It("does not store non-retransmittable packets", func() {
handler.SentPacket(&Packet{PacketNumber: 1, Length: 1}) handler.SentPacket(nonRetransmittablePacket(1))
Expect(handler.packetHistory.Len()).To(BeZero()) Expect(handler.packetHistory.Len()).To(BeZero())
}) })
Context("skipped packet numbers", func() { Context("skipped packet numbers", func() {
It("works with non-consecutive packet numbers", func() { It("works with non-consecutive packet numbers", func() {
packet1 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(1))
packet2 := Packet{PacketNumber: 3, Frames: []wire.Frame{&streamFrame}, Length: 2} handler.SentPacket(retransmittablePacket(3))
handler.SentPacket(&packet1)
handler.SentPacket(&packet2)
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(3))) Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(3)))
expectInPacketHistory([]protocol.PacketNumber{1, 3}) expectInPacketHistory([]protocol.PacketNumber{1, 3})
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(3))) Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2}))
Expect(handler.skippedPackets).To(HaveLen(1)) })
Expect(handler.skippedPackets[0]).To(Equal(protocol.PacketNumber(2)))
It("works with non-retransmittable packets", func() {
handler.SentPacket(nonRetransmittablePacket(1))
handler.SentPacket(nonRetransmittablePacket(3))
Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2}))
}) })
It("recognizes multiple skipped packets", func() { It("recognizes multiple skipped packets", func() {
packet1 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(1))
packet2 := Packet{PacketNumber: 3, Frames: []wire.Frame{&streamFrame}, Length: 2} handler.SentPacket(retransmittablePacket(3))
packet3 := Packet{PacketNumber: 5, Frames: []wire.Frame{&streamFrame}, Length: 2} handler.SentPacket(retransmittablePacket(5))
handler.SentPacket(&packet1)
handler.SentPacket(&packet2)
handler.SentPacket(&packet3)
Expect(handler.skippedPackets).To(HaveLen(2))
Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2, 4})) Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2, 4}))
}) })
It("recognizes multiple consecutive skipped packets", func() { It("recognizes multiple consecutive skipped packets", func() {
packet1 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(1))
packet2 := Packet{PacketNumber: 4, Frames: []wire.Frame{&streamFrame}, Length: 2} handler.SentPacket(retransmittablePacket(4))
handler.SentPacket(&packet1)
handler.SentPacket(&packet2)
Expect(handler.skippedPackets).To(HaveLen(2))
Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2, 3})) Expect(handler.skippedPackets).To(Equal([]protocol.PacketNumber{2, 3}))
}) })
It("limits the lengths of the skipped packet slice", func() { It("limits the lengths of the skipped packet slice", func() {
for i := 0; i < protocol.MaxTrackedSkippedPackets+5; i++ { for i := 0; i < protocol.MaxTrackedSkippedPackets+5; i++ {
packet := Packet{PacketNumber: protocol.PacketNumber(2*i + 1), Frames: []wire.Frame{&streamFrame}, Length: 1} handler.SentPacket(retransmittablePacket(protocol.PacketNumber(2*i + 1)))
handler.SentPacket(&packet)
} }
Expect(handler.skippedPackets).To(HaveLen(protocol.MaxUndecryptablePackets)) Expect(handler.skippedPackets).To(HaveLen(protocol.MaxUndecryptablePackets))
Expect(handler.skippedPackets[0]).To(Equal(protocol.PacketNumber(10))) Expect(handler.skippedPackets[0]).To(Equal(protocol.PacketNumber(10)))
@@ -170,284 +174,176 @@ var _ = Describe("SentPacketHandler", func() {
Expect(handler.skippedPackets).To(BeEmpty()) Expect(handler.skippedPackets).To(BeEmpty())
}) })
}) })
Context("ACK handling", func() {
BeforeEach(func() {
handler.SentPacket(retransmittablePacket(10))
handler.SentPacket(retransmittablePacket(12))
})
It("rejects ACKs for skipped packets", func() {
ack := createAck([]wire.AckRange{{First: 10, Last: 12}})
err := handler.ReceivedAck(ack, 1337, protocol.EncryptionForwardSecure, time.Now())
Expect(err).To(MatchError("InvalidAckData: Received an ACK for a skipped packet number"))
})
It("accepts an ACK that correctly nacks a skipped packet", func() {
ack := createAck([]wire.AckRange{{First: 10, Last: 10}, {First: 12, Last: 12}})
err := handler.ReceivedAck(ack, 1337, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).ToNot(BeZero())
})
})
}) })
}) })
Context("ACK processing", func() { Context("ACK processing", func() {
var packets []*Packet
BeforeEach(func() { BeforeEach(func() {
packets = []*Packet{ for i := protocol.PacketNumber(0); i < 10; i++ {
{PacketNumber: 0, Frames: []wire.Frame{&streamFrame}, Length: 1}, handler.SentPacket(retransmittablePacket(i))
{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 2, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 3, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 4, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 5, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 6, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 7, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 8, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 9, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 10, Frames: []wire.Frame{&streamFrame}, Length: 1},
{PacketNumber: 12, Frames: []wire.Frame{&streamFrame}, Length: 1},
}
for _, packet := range packets {
handler.SentPacket(packet)
} }
// Increase RTT, because the tests would be flaky otherwise // Increase RTT, because the tests would be flaky otherwise
handler.rttStats.UpdateRTT(time.Hour, 0, time.Now()) handler.rttStats.UpdateRTT(time.Hour, 0, time.Now())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets)))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(10)))
}) })
Context("ACK validation", func() { Context("ACK validation", func() {
It("accepts ACKs sent in packet 0", func() { It("accepts ACKs sent in packet 0", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 0, Last: 5}})
LargestAcked: 5, err := handler.ReceivedAck(ack, 0, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
}
err := handler.ReceivedAck(&ack, 0, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(5))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(5)))
}) })
It("rejects duplicate ACKs", func() { It("rejects duplicate ACKs", func() {
ack1 := wire.AckFrame{LargestAcked: 3} ack1 := createAck([]wire.AckRange{{First: 0, Last: 3}})
ack2 := wire.AckFrame{LargestAcked: 4} ack2 := createAck([]wire.AckRange{{First: 0, Last: 4}})
err := handler.ReceivedAck(&ack1, 1337, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(ack1, 1337, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3)))
// this wouldn't happen in practice // this wouldn't happen in practice
// for testing purposes, we pretend send a different ACK frame in a duplicated packet, to be able to verify that it actually doesn't get processed // for testing purposes, we pretend send a different ACK frame in a duplicated packet, to be able to verify that it actually doesn't get processed
err = handler.ReceivedAck(&ack2, 1337, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(ack2, 1337, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3)))
}) })
It("rejects out of order ACKs", func() { It("rejects out of order ACKs", func() {
// acks packets 0, 1, 2, 3 // acks packets 0, 1, 2, 3
ack1 := wire.AckFrame{LargestAcked: 3} ack1 := createAck([]wire.AckRange{{First: 0, Last: 3}})
ack2 := wire.AckFrame{LargestAcked: 4} ack2 := createAck([]wire.AckRange{{First: 0, Last: 4}})
err := handler.ReceivedAck(&ack1, 1337, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(ack1, 1337, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
// this wouldn't happen in practive // this wouldn't happen in practive
// a receiver wouldn't send an ACK for a lower largest acked in a packet sent later // a receiver wouldn't send an ACK for a lower largest acked in a packet sent later
err = handler.ReceivedAck(&ack2, 1337-1, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(ack2, 1337-1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3)))
}) })
It("rejects ACKs with a too high LargestAcked packet number", func() { It("rejects ACKs with a too high LargestAcked packet number", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 0, Last: 9999}})
LargestAcked: packets[len(packets)-1].PacketNumber + 1337, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).To(MatchError("InvalidAckData: Received ACK for an unsent package")) Expect(err).To(MatchError("InvalidAckData: Received ACK for an unsent package"))
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets)))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(10)))
}) })
It("ignores repeated ACKs", func() { It("ignores repeated ACKs", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 1, Last: 3}})
LargestAcked: 3, err := handler.ReceivedAck(ack, 1337, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
}
err := handler.ReceivedAck(&ack, 1337, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 3))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(7)))
err = handler.ReceivedAck(&ack, 1337+1, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(ack, 1337+1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(3)))
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 3))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(7)))
})
It("rejects ACKs for skipped packets", func() {
ack := wire.AckFrame{
LargestAcked: 12,
LowestAcked: 5,
}
err := handler.ReceivedAck(&ack, 1337, protocol.EncryptionUnencrypted, time.Now())
Expect(err).To(MatchError("InvalidAckData: Received an ACK for a skipped packet number"))
})
It("accepts an ACK that correctly nacks a skipped packet", func() {
ack := wire.AckFrame{
LargestAcked: 12,
LowestAcked: 5,
AckRanges: []wire.AckRange{
{First: 12, Last: 12},
{First: 5, Last: 10},
},
}
err := handler.ReceivedAck(&ack, 1337, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).ToNot(BeZero())
}) })
}) })
Context("acks and nacks the right packets", func() { Context("acks and nacks the right packets", func() {
It("adjusts the LargestAcked", func() { It("adjusts the LargestAcked", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 0, Last: 5}})
LargestAcked: 5, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 0,
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(5))) Expect(handler.largestAcked).To(Equal(protocol.PacketNumber(5)))
Expect(handler.packetHistory.Len()).To(Equal(6)) // 6, 7, 8, 9, 10, 12 expectInPacketHistory([]protocol.PacketNumber{6, 7, 8, 9})
for i := protocol.PacketNumber(6); i <= 10; i++ {
Expect(getPacket(i)).ToNot(BeNil())
}
Expect(getPacket(12)).ToNot(BeNil())
})
It("rejects an ACK that acks packets with a higher encryption level", func() {
handler.SentPacket(&Packet{
PacketNumber: 13,
EncryptionLevel: protocol.EncryptionForwardSecure,
Frames: []wire.Frame{&streamFrame},
Length: 1,
})
ack := wire.AckFrame{
LargestAcked: 13,
LowestAcked: 13,
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionSecure, time.Now())
Expect(err).To(MatchError("Received ACK with encryption level encrypted (not forward-secure) that acks a packet 13 (encryption level forward-secure)"))
})
It("acks all packets for an ACK frame with no missing packets", func() {
ack := wire.AckFrame{
LargestAcked: 8,
LowestAcked: 1,
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.packetHistory.Len()).To(Equal(4)) // 0, 9, 10, 12
Expect(getPacket(0)).ToNot(BeNil())
Expect(getPacket(9)).ToNot(BeNil())
Expect(getPacket(10)).ToNot(BeNil())
Expect(getPacket(12)).ToNot(BeNil())
}) })
It("acks packet 0", func() { It("acks packet 0", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 0, Last: 0}})
LargestAcked: 0, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 0,
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(getPacket(0)).To(BeNil()) Expect(getPacket(0)).To(BeNil())
Expect(handler.packetHistory.Len()).To(Equal(11)) // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 expectInPacketHistory([]protocol.PacketNumber{1, 2, 3, 4, 5, 6, 7, 8, 9})
}) })
It("handles an ACK frame with one missing packet range", func() { It("handles an ACK frame with one missing packet range", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 1, Last: 3}, {First: 6, Last: 9}}) // lose 4 and 5
LargestAcked: 9, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
AckRanges: []wire.AckRange{ // packets 4 and 5 were lost
{First: 6, Last: 9},
{First: 1, Last: 3},
},
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
expectInPacketHistory([]protocol.PacketNumber{0, 4, 5, 10, 12}) expectInPacketHistory([]protocol.PacketNumber{0, 4, 5})
}) })
It("does not ack packets below the LowestAcked", func() { It("does not ack packets below the LowestAcked", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{{First: 3, Last: 8}})
LargestAcked: 8, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 3,
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
expectInPacketHistory([]protocol.PacketNumber{0, 1, 2, 9, 10, 12}) expectInPacketHistory([]protocol.PacketNumber{0, 1, 2, 9})
}) })
It("handles an ACK with multiple missing packet ranges", func() { It("handles an ACK with multiple missing packet ranges", func() {
ack := wire.AckFrame{ ack := createAck([]wire.AckRange{ // packets 2, 4 and 5, and 8 were lost
LargestAcked: 9, {First: 9, Last: 9},
LowestAcked: 1, {First: 6, Last: 7},
AckRanges: []wire.AckRange{ // packets 2, 4 and 5, and 8 were lost {First: 3, Last: 3},
{First: 9, Last: 9}, {First: 1, Last: 1},
{First: 6, Last: 7}, })
{First: 3, Last: 3}, err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
{First: 1, Last: 1},
},
}
err := handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
expectInPacketHistory([]protocol.PacketNumber{0, 2, 4, 5, 8, 10, 12}) expectInPacketHistory([]protocol.PacketNumber{0, 2, 4, 5, 8})
}) })
It("processes an ACK frame that would be sent after a late arrival of a packet", func() { It("processes an ACK frame that would be sent after a late arrival of a packet", func() {
largestObserved := 6 ack1 := createAck([]wire.AckRange{{First: 1, Last: 2}, {First: 4, Last: 6}}) // 3 lost
ack1 := wire.AckFrame{ err := handler.ReceivedAck(ack1, 1, protocol.EncryptionForwardSecure, time.Now())
LargestAcked: protocol.PacketNumber(largestObserved),
LowestAcked: 1,
AckRanges: []wire.AckRange{
{First: 4, Last: protocol.PacketNumber(largestObserved)},
{First: 1, Last: 2},
},
}
err := handler.ReceivedAck(&ack1, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 5))) expectInPacketHistory([]protocol.PacketNumber{0, 3, 7, 8, 9})
expectInPacketHistory([]protocol.PacketNumber{0, 3, 7, 8, 9, 10, 12}) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(5)))
ack2 := wire.AckFrame{ ack2 := createAck([]wire.AckRange{{First: 1, Last: 6}}) // now ack 3
LargestAcked: protocol.PacketNumber(largestObserved), err = handler.ReceivedAck(ack2, 2, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
}
err = handler.ReceivedAck(&ack2, 2, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 6))) expectInPacketHistory([]protocol.PacketNumber{0, 7, 8, 9})
expectInPacketHistory([]protocol.PacketNumber{0, 7, 8, 9, 10, 12}) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(4)))
}) })
It("processes an ACK frame that would be sent after a late arrival of a packet and another packet", func() { It("processes an ACK frame that would be sent after a late arrival of a packet and another packet", func() {
ack1 := wire.AckFrame{ ack1 := createAck([]wire.AckRange{{First: 0, Last: 2}, {First: 4, Last: 6}})
LargestAcked: 6, err := handler.ReceivedAck(ack1, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 0,
AckRanges: []wire.AckRange{
{First: 4, Last: 6},
{First: 0, Last: 2},
},
}
err := handler.ReceivedAck(&ack1, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 6))) expectInPacketHistory([]protocol.PacketNumber{3, 7, 8, 9})
expectInPacketHistory([]protocol.PacketNumber{3, 7, 8, 9, 10, 12}) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(4)))
ack2 := wire.AckFrame{ ack2 := createAck([]wire.AckRange{{First: 1, Last: 7}})
LargestAcked: 7, err = handler.ReceivedAck(ack2, 2, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
}
err = handler.ReceivedAck(&ack2, 2, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 8))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
expectInPacketHistory([]protocol.PacketNumber{8, 9, 10, 12}) expectInPacketHistory([]protocol.PacketNumber{8, 9})
}) })
It("processes an ACK that contains old ACK ranges", func() { It("processes an ACK that contains old ACK ranges", func() {
ack1 := wire.AckFrame{ ack1 := createAck([]wire.AckRange{{First: 1, Last: 6}})
LargestAcked: 6, err := handler.ReceivedAck(ack1, 1, protocol.EncryptionForwardSecure, time.Now())
LowestAcked: 1,
}
err := handler.ReceivedAck(&ack1, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
expectInPacketHistory([]protocol.PacketNumber{0, 7, 8, 9, 10, 12}) expectInPacketHistory([]protocol.PacketNumber{0, 7, 8, 9})
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 6))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(4)))
ack2 := wire.AckFrame{ ack2 := createAck([]wire.AckRange{
LargestAcked: 10, {First: 1, Last: 1},
LowestAcked: 1, {First: 3, Last: 3},
AckRanges: []wire.AckRange{ {First: 8, Last: 8},
{First: 8, Last: 10}, })
{First: 3, Last: 3}, err = handler.ReceivedAck(ack2, 2, protocol.EncryptionForwardSecure, time.Now())
{First: 1, Last: 1},
},
}
err = handler.ReceivedAck(&ack2, 2, protocol.EncryptionUnencrypted, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(len(packets) - 6 - 3))) expectInPacketHistory([]protocol.PacketNumber{0, 7, 9})
expectInPacketHistory([]protocol.PacketNumber{0, 7, 12}) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(3)))
}) })
}) })
@@ -459,13 +355,13 @@ var _ = Describe("SentPacketHandler", func() {
getPacket(2).sendTime = now.Add(-5 * time.Minute) getPacket(2).sendTime = now.Add(-5 * time.Minute)
getPacket(6).sendTime = now.Add(-1 * time.Minute) getPacket(6).sendTime = now.Add(-1 * time.Minute)
// Now, check that the proper times are used when calculating the deltas // Now, check that the proper times are used when calculating the deltas
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1}, 1, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 10*time.Minute, 1*time.Second)) Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 10*time.Minute, 1*time.Second))
err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2}, 2, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2}, 2, protocol.EncryptionForwardSecure, time.Now())
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second)) Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second))
err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 6}, 3, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 6}, 3, protocol.EncryptionForwardSecure, time.Now())
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 1*time.Minute, 1*time.Second)) Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 1*time.Minute, 1*time.Second))
}) })
@@ -475,7 +371,7 @@ var _ = Describe("SentPacketHandler", func() {
// make sure the rttStats have a min RTT, so that the delay is used // make sure the rttStats have a min RTT, so that the delay is used
handler.rttStats.UpdateRTT(5*time.Minute, 0, time.Now()) handler.rttStats.UpdateRTT(5*time.Minute, 0, time.Now())
getPacket(1).sendTime = now.Add(-10 * time.Minute) getPacket(1).sendTime = now.Add(-10 * time.Minute)
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1, DelayTime: 5 * time.Minute}, 1, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1, DelayTime: 5 * time.Minute}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second)) Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second))
}) })
@@ -494,25 +390,25 @@ var _ = Describe("SentPacketHandler", func() {
}) })
It("determines which ACK we have received an ACK for", func() { It("determines which ACK we have received an ACK for", func() {
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 15, LowestAcked: 12}, 1, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(createAck([]wire.AckRange{{First: 13, Last: 15}}), 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201))) Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201)))
}) })
It("doesn't do anything when the acked packet didn't contain an ACK", func() { It("doesn't do anything when the acked packet didn't contain an ACK", func() {
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 13, LowestAcked: 13}, 1, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(createAck([]wire.AckRange{{First: 13, Last: 13}}), 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(101))) Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(101)))
err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 15, LowestAcked: 15}, 2, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(createAck([]wire.AckRange{{First: 15, Last: 15}}), 2, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(101))) Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(101)))
}) })
It("doesn't decrease the value", func() { It("doesn't decrease the value", func() {
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 14, LowestAcked: 14}, 1, protocol.EncryptionUnencrypted, time.Now()) err := handler.ReceivedAck(createAck([]wire.AckRange{{First: 14, Last: 14}}), 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201))) Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201)))
err = handler.ReceivedAck(&wire.AckFrame{LargestAcked: 13, LowestAcked: 13}, 2, protocol.EncryptionUnencrypted, time.Now()) err = handler.ReceivedAck(createAck([]wire.AckRange{{First: 13, Last: 13}}), 2, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201))) Expect(handler.GetLowestPacketNotConfirmedAcked()).To(Equal(protocol.PacketNumber(201)))
}) })
@@ -520,107 +416,30 @@ var _ = Describe("SentPacketHandler", func() {
}) })
Context("Retransmission handling", func() { Context("Retransmission handling", func() {
var packets []*Packet
BeforeEach(func() {
packets = []*Packet{
{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionUnencrypted},
{PacketNumber: 2, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionUnencrypted},
{PacketNumber: 3, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionUnencrypted},
{PacketNumber: 4, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionSecure},
{PacketNumber: 5, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionSecure},
{PacketNumber: 6, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionForwardSecure},
{PacketNumber: 7, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.EncryptionForwardSecure},
}
for _, packet := range packets {
handler.SentPacket(packet)
}
// Increase RTT, because the tests would be flaky otherwise
handler.rttStats.UpdateRTT(time.Minute, 0, time.Now())
// Ack a single packet so that we have non-RTO timings
handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2, LowestAcked: 2}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(6)))
})
It("does not dequeue a packet if no ack has been received", func() { It("does not dequeue a packet if no ack has been received", func() {
Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) handler.SentPacket(retransmittablePacket(1))
})
It("dequeues a packet for retransmission", func() {
getPacket(1).sendTime = time.Now().Add(-time.Hour)
handler.OnAlarm()
Expect(getPacket(1)).To(BeNil())
Expect(handler.retransmissionQueue).To(HaveLen(1))
Expect(handler.retransmissionQueue[0].PacketNumber).To(Equal(protocol.PacketNumber(1)))
packet := handler.DequeuePacketForRetransmission()
Expect(packet).ToNot(BeNil())
Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(1)))
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
})
It("deletes non forward-secure packets when the handshake completes", func() {
for i := protocol.PacketNumber(1); i <= 7; i++ {
if i == 2 { // packet 2 was already acked in BeforeEach
continue
}
handler.queuePacketForRetransmission(getPacket(i))
}
Expect(handler.retransmissionQueue).To(HaveLen(6))
handler.SetHandshakeComplete()
packet := handler.DequeuePacketForRetransmission()
Expect(packet).ToNot(BeNil())
Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(6)))
packet = handler.DequeuePacketForRetransmission()
Expect(packet).ToNot(BeNil())
Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(7)))
Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
}) })
Context("STOP_WAITINGs", func() { Context("STOP_WAITINGs", func() {
It("gets a STOP_WAITING frame", func() { It("gets a STOP_WAITING frame", func() {
ack := wire.AckFrame{LargestAcked: 5, LowestAcked: 5} handler.SentPacket(retransmittablePacket(1))
handler.SentPacket(retransmittablePacket(2))
handler.SentPacket(retransmittablePacket(3))
ack := wire.AckFrame{LargestAcked: 3, LowestAcked: 3}
err := handler.ReceivedAck(&ack, 2, protocol.EncryptionForwardSecure, time.Now()) err := handler.ReceivedAck(&ack, 2, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(handler.GetStopWaitingFrame(false)).To(Equal(&wire.StopWaitingFrame{LeastUnacked: 6})) Expect(handler.GetStopWaitingFrame(false)).To(Equal(&wire.StopWaitingFrame{LeastUnacked: 4}))
}) })
It("gets a STOP_WAITING frame after queueing a retransmission", func() { It("gets a STOP_WAITING frame after queueing a retransmission", func() {
handler.SentPacket(retransmittablePacket(5))
handler.queuePacketForRetransmission(getPacket(5)) handler.queuePacketForRetransmission(getPacket(5))
Expect(handler.GetStopWaitingFrame(false)).To(Equal(&wire.StopWaitingFrame{LeastUnacked: 6})) Expect(handler.GetStopWaitingFrame(false)).To(Equal(&wire.StopWaitingFrame{LeastUnacked: 6}))
}) })
}) })
}) })
It("calculates bytes in flight", func() {
packet1 := Packet{PacketNumber: 1, Frames: []wire.Frame{&streamFrame}, Length: 1}
packet2 := Packet{PacketNumber: 2, Frames: []wire.Frame{&streamFrame}, Length: 2}
packet3 := Packet{PacketNumber: 3, Frames: []wire.Frame{&streamFrame}, Length: 3}
handler.SentPacket(&packet1)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(1)))
handler.SentPacket(&packet2)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(1 + 2)))
handler.SentPacket(&packet3)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(1 + 2 + 3)))
// Increase RTT, because the tests would be flaky otherwise
handler.rttStats.UpdateRTT(time.Minute, 0, time.Now())
// ACK 1 and 3, NACK 2
ack := wire.AckFrame{
LargestAcked: 3,
LowestAcked: 1,
AckRanges: []wire.AckRange{
{First: 3, Last: 3},
{First: 1, Last: 1},
},
}
handler.ReceivedAck(&ack, 1, protocol.EncryptionUnencrypted, time.Now())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
getPacket(2).sendTime = time.Now().Add(-time.Hour)
handler.OnAlarm()
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(0)))
})
Context("congestion", func() { Context("congestion", func() {
var cong *mocks.MockSendAlgorithm var cong *mocks.MockSendAlgorithm
@@ -743,7 +562,7 @@ var _ = Describe("SentPacketHandler", func() {
}) })
}) })
Context("calculating RTO", func() { Context("RTOs", func() {
It("uses default RTO", func() { It("uses default RTO", func() {
Expect(handler.computeRTOTimeout()).To(Equal(defaultRTOTimeout)) Expect(handler.computeRTOTimeout()).To(Equal(defaultRTOTimeout))
}) })
@@ -775,83 +594,7 @@ var _ = Describe("SentPacketHandler", func() {
handler.rtoCount = 2 handler.rtoCount = 2
Expect(handler.computeRTOTimeout()).To(Equal(4 * defaultRTOTimeout)) Expect(handler.computeRTOTimeout()).To(Equal(4 * defaultRTOTimeout))
}) })
})
Context("Delay-based loss detection", func() {
It("detects a packet as lost", func() {
handler.SentPacket(retransmittablePacket(1))
handler.SentPacket(retransmittablePacket(2))
Expect(handler.lossTime.IsZero()).To(BeTrue())
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2, LowestAcked: 2}, 1, protocol.EncryptionForwardSecure, time.Now().Add(time.Hour))
Expect(err).NotTo(HaveOccurred())
Expect(handler.lossTime.IsZero()).To(BeFalse())
// RTT is around 1h now.
// The formula is (1+1/8) * RTT, so this should be around that number
Expect(time.Until(handler.lossTime)).To(BeNumerically("~", time.Hour*9/8, time.Minute))
Expect(time.Until(handler.GetAlarmTimeout())).To(BeNumerically("~", time.Hour*9/8, time.Minute))
getPacket(1).sendTime = time.Now().Add(-2 * time.Hour)
handler.OnAlarm()
Expect(handler.DequeuePacketForRetransmission()).NotTo(BeNil())
})
It("does not detect packets as lost without ACKs", func() {
handler.SentPacket(nonRetransmittablePacket(1))
handler.SentPacket(retransmittablePacket(2))
handler.SentPacket(retransmittablePacket(3))
Expect(handler.lossTime.IsZero()).To(BeTrue())
now := time.Now().Add(time.Hour)
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1, LowestAcked: 1}, 1, protocol.EncryptionUnencrypted, now)
Expect(err).NotTo(HaveOccurred())
Expect(handler.lossTime.IsZero()).To(BeTrue())
Expect(handler.GetAlarmTimeout().Sub(now)).To(BeNumerically("~", handler.computeRTOTimeout(), time.Minute))
// This means RTO, so both packets should be lost
handler.OnAlarm()
Expect(handler.DequeuePacketForRetransmission()).ToNot(BeNil())
Expect(handler.DequeuePacketForRetransmission()).ToNot(BeNil())
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
})
})
Context("retransmission for handshake packets", func() {
BeforeEach(func() {
handler.handshakeComplete = false
})
It("detects the handshake timeout", func() {
// send handshake packets: 1, 2, 4
// send a forward-secure packet: 3
handler.SentPacket(handshakePacket(1))
handler.SentPacket(handshakePacket(2))
handler.SentPacket(retransmittablePacket(3))
handler.SentPacket(handshakePacket(4))
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 1, LowestAcked: 1}, 1, protocol.EncryptionSecure, time.Now())
Expect(err).NotTo(HaveOccurred())
Expect(handler.lossTime.IsZero()).To(BeTrue())
handshakeTimeout := handler.computeHandshakeTimeout()
Expect(time.Until(handler.GetAlarmTimeout())).To(BeNumerically("~", handshakeTimeout, time.Minute))
handler.OnAlarm()
p := handler.DequeuePacketForRetransmission()
Expect(p).ToNot(BeNil())
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(2)))
p = handler.DequeuePacketForRetransmission()
Expect(p).ToNot(BeNil())
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(4)))
Expect(handler.packetHistory.Len()).To(Equal(1))
Expect(getPacket(3)).ToNot(BeNil())
Expect(handler.handshakeCount).To(BeEquivalentTo(1))
// make sure the exponential backoff is used
Expect(handler.computeHandshakeTimeout()).To(BeNumerically("~", 2*handshakeTimeout, time.Minute))
})
})
Context("RTO retransmission", func() {
It("queues two packets if RTO expires", func() { It("queues two packets if RTO expires", func() {
handler.SentPacket(retransmittablePacket(1)) handler.SentPacket(retransmittablePacket(1))
handler.SentPacket(retransmittablePacket(2)) handler.SentPacket(retransmittablePacket(2))
@@ -871,4 +614,106 @@ var _ = Describe("SentPacketHandler", func() {
Expect(handler.rtoCount).To(BeEquivalentTo(1)) Expect(handler.rtoCount).To(BeEquivalentTo(1))
}) })
}) })
Context("Delay-based loss detection", func() {
It("immediately detects old packets as lost when receiving an ACK", func() {
now := time.Now()
handler.SentPacket(retransmittablePacket(1))
getPacket(1).sendTime = now.Add(-time.Hour)
handler.SentPacket(retransmittablePacket(2))
getPacket(2).sendTime = now.Add(-time.Second)
Expect(handler.lossTime.IsZero()).To(BeTrue())
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2, LowestAcked: 2}, 1, protocol.EncryptionForwardSecure, now)
Expect(err).NotTo(HaveOccurred())
Expect(handler.DequeuePacketForRetransmission()).ToNot(BeNil())
// no need to set an alarm, since packet 1 was already declared lost
Expect(handler.lossTime.IsZero()).To(BeTrue())
})
It("sets the early retransmit alarm", func() {
now := time.Now()
handler.SentPacket(retransmittablePacket(1))
getPacket(1).sendTime = now.Add(-2 * time.Second)
handler.SentPacket(retransmittablePacket(2))
getPacket(2).sendTime = now.Add(-2 * time.Second)
handler.SentPacket(retransmittablePacket(3))
getPacket(3).sendTime = now.Add(-time.Second)
Expect(handler.lossTime.IsZero()).To(BeTrue())
err := handler.ReceivedAck(&wire.AckFrame{LargestAcked: 2, LowestAcked: 2}, 1, protocol.EncryptionForwardSecure, now.Add(-time.Second))
Expect(err).NotTo(HaveOccurred())
Expect(handler.rttStats.SmoothedRTT()).To(Equal(time.Second))
// Packet 1 should be considered lost (1+1/8) RTTs after it was sent.
Expect(handler.lossTime.IsZero()).To(BeFalse())
Expect(handler.lossTime.Sub(getPacket(1).sendTime)).To(Equal(time.Second * 9 / 8))
// Expect(time.Until(handler.GetAlarmTimeout())).To(BeNumerically("~", time.Hour*9/8, time.Minute))
handler.OnAlarm()
Expect(handler.DequeuePacketForRetransmission()).NotTo(BeNil())
// make sure this is not an RTO: only packet 1 is retransmissted
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
})
})
Context("handshake packets", func() {
BeforeEach(func() {
handler.handshakeComplete = false
})
It("detects the handshake timeout", func() {
// send handshake packets: 1, 2, 4
// send a forward-secure packet: 3
handler.SentPacket(handshakePacket(1))
handler.SentPacket(handshakePacket(2))
handler.SentPacket(retransmittablePacket(3))
handler.SentPacket(handshakePacket(4))
err := handler.ReceivedAck(createAck([]wire.AckRange{{First: 1, Last: 1}}), 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).NotTo(HaveOccurred())
Expect(handler.lossTime.IsZero()).To(BeTrue())
handshakeTimeout := handler.computeHandshakeTimeout()
Expect(time.Until(handler.GetAlarmTimeout())).To(BeNumerically("~", handshakeTimeout, time.Minute))
handler.OnAlarm()
p := handler.DequeuePacketForRetransmission()
Expect(p).ToNot(BeNil())
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(2)))
p = handler.DequeuePacketForRetransmission()
Expect(p).ToNot(BeNil())
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(4)))
Expect(handler.packetHistory.Len()).To(Equal(1))
Expect(getPacket(3)).ToNot(BeNil())
Expect(handler.handshakeCount).To(BeEquivalentTo(1))
// make sure the exponential backoff is used
Expect(handler.computeHandshakeTimeout()).To(BeNumerically("~", 2*handshakeTimeout, time.Minute))
})
It("rejects an ACK that acks packets with a higher encryption level", func() {
handler.SentPacket(&Packet{
PacketNumber: 13,
EncryptionLevel: protocol.EncryptionForwardSecure,
Frames: []wire.Frame{&streamFrame},
Length: 1,
})
ack := createAck([]wire.AckRange{{First: 13, Last: 13}})
err := handler.ReceivedAck(ack, 1, protocol.EncryptionSecure, time.Now())
Expect(err).To(MatchError("Received ACK with encryption level encrypted (not forward-secure) that acks a packet 13 (encryption level forward-secure)"))
})
It("deletes non forward-secure packets when the handshake completes", func() {
for i := protocol.PacketNumber(1); i <= 6; i++ {
p := retransmittablePacket(i)
p.EncryptionLevel = protocol.EncryptionSecure
handler.SentPacket(p)
}
handler.queuePacketForRetransmission(getPacket(1))
handler.queuePacketForRetransmission(getPacket(3))
handler.SetHandshakeComplete()
Expect(handler.packetHistory.Len()).To(BeZero())
packet := handler.DequeuePacketForRetransmission()
Expect(packet).To(BeNil())
})
})
}) })