From b032a07f70adf7453084d27593f568424b72c597 Mon Sep 17 00:00:00 2001 From: Lucas Clemente Date: Tue, 30 Aug 2016 21:22:48 +0200 Subject: [PATCH] remove ackhandlerlegacy and frames.AckFrameLegacy --- ackhandler/packet_test.go | 11 +- ackhandlerlegacy/_gen.go | 7 - ackhandlerlegacy/ackhandler_suite_test.go | 13 - ackhandlerlegacy/entropy_accumulator.go | 23 - ackhandlerlegacy/entropy_accumulator_test.go | 41 - ackhandlerlegacy/interfaces.go | 43 - ackhandlerlegacy/packet.go | 55 -- ackhandlerlegacy/packet_linkedlist.go | 214 ----- ackhandlerlegacy/packet_test.go | 101 --- ackhandlerlegacy/received_packet_handler.go | 181 ---- .../received_packet_handler_test.go | 431 ---------- ackhandlerlegacy/sent_packet_handler.go | 358 -------- ackhandlerlegacy/sent_packet_handler_test.go | 808 ------------------ ackhandlerlegacy/stop_waiting_manager.go | 58 -- ackhandlerlegacy/stop_waiting_manager_test.go | 87 -- frames/ack_frame.go | 23 - frames/ack_frame_legacy.go | 304 ------- frames/ack_frame_legacy_test.go | 559 ------------ frames/ack_frame_test.go | 42 - frames/log.go | 5 - packet_packer_test.go | 2 +- packet_unpacker_test.go | 15 +- session_test.go | 8 +- 23 files changed, 11 insertions(+), 3378 deletions(-) delete mode 100644 ackhandlerlegacy/_gen.go delete mode 100644 ackhandlerlegacy/ackhandler_suite_test.go delete mode 100644 ackhandlerlegacy/entropy_accumulator.go delete mode 100644 ackhandlerlegacy/entropy_accumulator_test.go delete mode 100644 ackhandlerlegacy/interfaces.go delete mode 100644 ackhandlerlegacy/packet.go delete mode 100644 ackhandlerlegacy/packet_linkedlist.go delete mode 100644 ackhandlerlegacy/packet_test.go delete mode 100644 ackhandlerlegacy/received_packet_handler.go delete mode 100644 ackhandlerlegacy/received_packet_handler_test.go delete mode 100644 ackhandlerlegacy/sent_packet_handler.go delete mode 100644 ackhandlerlegacy/sent_packet_handler_test.go delete mode 100644 ackhandlerlegacy/stop_waiting_manager.go delete mode 100644 ackhandlerlegacy/stop_waiting_manager_test.go delete mode 100644 frames/ack_frame_legacy.go delete mode 100644 frames/ack_frame_legacy_test.go diff --git a/ackhandler/packet_test.go b/ackhandler/packet_test.go index a09b61f8..f713bf86 100644 --- a/ackhandler/packet_test.go +++ b/ackhandler/packet_test.go @@ -25,16 +25,10 @@ var _ = Describe("Packet", func() { Data: []byte{0xDE, 0xCA, 0xFB, 0xAD}, } ackFrame1 = &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 13, - Entropy: 5, - }, + LargestAcked: 13, } ackFrame2 = &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 333, - Entropy: 17, - }, + LargestAcked: 333, } rstStreamFrame = &frames.RstStreamFrame{ StreamID: 555, @@ -42,7 +36,6 @@ var _ = Describe("Packet", func() { } stopWaitingFrame = &frames.StopWaitingFrame{ LeastUnacked: 7331, - Entropy: 10, } windowUpdateFrame = &frames.WindowUpdateFrame{ StreamID: 999, diff --git a/ackhandlerlegacy/_gen.go b/ackhandlerlegacy/_gen.go deleted file mode 100644 index 154515b2..00000000 --- a/ackhandlerlegacy/_gen.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import ( - _ "github.com/clipperhouse/linkedlist" - _ "github.com/clipperhouse/slice" - _ "github.com/clipperhouse/stringer" -) diff --git a/ackhandlerlegacy/ackhandler_suite_test.go b/ackhandlerlegacy/ackhandler_suite_test.go deleted file mode 100644 index 513d63cf..00000000 --- a/ackhandlerlegacy/ackhandler_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package ackhandlerlegacy - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "testing" -) - -func TestCrypto(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "AckHandler (Legacy) Suite") -} diff --git a/ackhandlerlegacy/entropy_accumulator.go b/ackhandlerlegacy/entropy_accumulator.go deleted file mode 100644 index 6a0838cf..00000000 --- a/ackhandlerlegacy/entropy_accumulator.go +++ /dev/null @@ -1,23 +0,0 @@ -package ackhandlerlegacy - -import "github.com/lucas-clemente/quic-go/protocol" - -// EntropyAccumulator accumulates the entropy according to the QUIC docs -type EntropyAccumulator byte - -// Add the contribution of the entropy flag of a given packet number -func (e *EntropyAccumulator) Add(packetNumber protocol.PacketNumber, entropyFlag bool) { - if entropyFlag { - (*e) ^= 0x01 << (packetNumber % 8) - } -} - -// Subtract the contribution of the entropy flag of a given packet number -func (e *EntropyAccumulator) Subtract(packetNumber protocol.PacketNumber, entropyFlag bool) { - e.Add(packetNumber, entropyFlag) -} - -// Get the byte of entropy -func (e *EntropyAccumulator) Get() byte { - return byte(*e) -} diff --git a/ackhandlerlegacy/entropy_accumulator_test.go b/ackhandlerlegacy/entropy_accumulator_test.go deleted file mode 100644 index ff3427e2..00000000 --- a/ackhandlerlegacy/entropy_accumulator_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package ackhandlerlegacy - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("EntropyAccumulator", func() { - It("initializes as zero", func() { - var e EntropyAccumulator - Expect(e.Get()).To(BeZero()) - }) - - Context("Add", func() { - It("adds entropy", func() { - var e EntropyAccumulator - e.Add(9, true) - Expect(e.Get()).To(Equal(byte(0x02))) - }) - - It("doesn't add entropy for zero entropy flags", func() { - var e EntropyAccumulator - e.Add(9, false) - Expect(e.Get()).To(BeZero()) - }) - }) - - Context("Subtract", func() { - It("calculates the correct entropy", func() { - var e1 EntropyAccumulator - e1.Add(3, true) - - var e2 EntropyAccumulator - e2.Add(1, true) - e2.Add(3, true) - e2.Subtract(1, true) - - Expect(e1).To(Equal(e2)) - }) - }) -}) diff --git a/ackhandlerlegacy/interfaces.go b/ackhandlerlegacy/interfaces.go deleted file mode 100644 index 4e7f9e82..00000000 --- a/ackhandlerlegacy/interfaces.go +++ /dev/null @@ -1,43 +0,0 @@ -package ackhandlerlegacy - -import ( - "time" - - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" -) - -// SentPacketHandler handles ACKs received for outgoing packets -type SentPacketHandler interface { - SentPacket(packet *Packet) error - ReceivedAck(ackFrame *frames.AckFrame, withPacketNumber protocol.PacketNumber) error - - GetStopWaitingFrame(force bool) *frames.StopWaitingFrame - - MaybeQueueRTOs() - DequeuePacketForRetransmission() (packet *Packet) - - BytesInFlight() protocol.ByteCount - GetLeastUnacked() protocol.PacketNumber - - CongestionAllowsSending() bool - CheckForError() error - - TimeOfFirstRTO() time.Time -} - -// ReceivedPacketHandler handles ACKs needed to send for incoming packets -type ReceivedPacketHandler interface { - ReceivedPacket(packetNumber protocol.PacketNumber, entropyBit bool) error - ReceivedStopWaiting(*frames.StopWaitingFrame) error - - GetAckFrame(dequeue bool) (*frames.AckFrame, error) -} - -// StopWaitingManager manages StopWaitings for sent packets -type StopWaitingManager interface { - RegisterPacketForRetransmission(packet *Packet) - GetStopWaitingFrame() *frames.StopWaitingFrame - SentStopWaitingWithPacket(packetNumber protocol.PacketNumber) - ReceivedAckForPacketNumber(packetNumber protocol.PacketNumber) -} diff --git a/ackhandlerlegacy/packet.go b/ackhandlerlegacy/packet.go deleted file mode 100644 index 637401d1..00000000 --- a/ackhandlerlegacy/packet.go +++ /dev/null @@ -1,55 +0,0 @@ -package ackhandlerlegacy - -// TODO: move to ackhandler once we remove support for QUIC 33 - -import ( - "time" - - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" -) - -// A Packet is a packet -// +gen linkedlist -type Packet struct { - PacketNumber protocol.PacketNumber - Frames []frames.Frame - EntropyBit bool - Entropy EntropyAccumulator - Length protocol.ByteCount - - MissingReports uint8 - // TODO: remove this when dropping support for QUIC 33 - Retransmitted bool // has this Packet ever been retransmitted - - SendTime time.Time -} - -// GetStreamFramesForRetransmission gets all the streamframes for retransmission -func (p *Packet) GetStreamFramesForRetransmission() []*frames.StreamFrame { - var streamFrames []*frames.StreamFrame - for _, frame := range p.Frames { - if streamFrame, isStreamFrame := frame.(*frames.StreamFrame); isStreamFrame { - streamFrames = append(streamFrames, streamFrame) - } - } - return streamFrames -} - -// GetControlFramesForRetransmission gets all the control frames for retransmission -func (p *Packet) GetControlFramesForRetransmission() []frames.Frame { - var controlFrames []frames.Frame - for _, frame := range p.Frames { - // omit ACKs - if _, isStreamFrame := frame.(*frames.StreamFrame); isStreamFrame { - continue - } - - _, isAck := frame.(*frames.AckFrame) - _, isStopWaiting := frame.(*frames.StopWaitingFrame) - if !isAck && !isStopWaiting { - controlFrames = append(controlFrames, frame) - } - } - return controlFrames -} diff --git a/ackhandlerlegacy/packet_linkedlist.go b/ackhandlerlegacy/packet_linkedlist.go deleted file mode 100644 index d05eaddb..00000000 --- a/ackhandlerlegacy/packet_linkedlist.go +++ /dev/null @@ -1,214 +0,0 @@ -// Generated by: main -// TypeWriter: linkedlist -// Directive: +gen on Packet - -package ackhandlerlegacy - -// List is a modification of http://golang.org/pkg/container/list/ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// PacketElement is an element of a linked list. -type PacketElement struct { - // Next and previous pointers in the doubly-linked list of elements. - // To simplify the implementation, internally a list l is implemented - // as a ring, such that &l.root is both the next element of the last - // list element (l.Back()) and the previous element of the first list - // element (l.Front()). - next, prev *PacketElement - - // The list to which this element belongs. - list *PacketList - - // The value stored with this element. - Value Packet -} - -// Next returns the next list element or nil. -func (e *PacketElement) Next() *PacketElement { - if p := e.next; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// Prev returns the previous list element or nil. -func (e *PacketElement) Prev() *PacketElement { - if p := e.prev; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// PacketList represents a doubly linked list. -// The zero value for PacketList is an empty list ready to use. -type PacketList struct { - root PacketElement // sentinel list element, only &root, root.prev, and root.next are used - len int // current list length excluding (this) sentinel element -} - -// Init initializes or clears list l. -func (l *PacketList) Init() *PacketList { - l.root.next = &l.root - l.root.prev = &l.root - l.len = 0 - return l -} - -// NewPacketList returns an initialized list. -func NewPacketList() *PacketList { return new(PacketList).Init() } - -// Len returns the number of elements of list l. -// The complexity is O(1). -func (l *PacketList) Len() int { return l.len } - -// Front returns the first element of list l or nil. -func (l *PacketList) Front() *PacketElement { - if l.len == 0 { - return nil - } - return l.root.next -} - -// Back returns the last element of list l or nil. -func (l *PacketList) Back() *PacketElement { - if l.len == 0 { - return nil - } - return l.root.prev -} - -// lazyInit lazily initializes a zero PacketList value. -func (l *PacketList) lazyInit() { - if l.root.next == nil { - l.Init() - } -} - -// insert inserts e after at, increments l.len, and returns e. -func (l *PacketList) insert(e, at *PacketElement) *PacketElement { - n := at.next - at.next = e - e.prev = at - e.next = n - n.prev = e - e.list = l - l.len++ - return e -} - -// insertValue is a convenience wrapper for insert(&PacketElement{Value: v}, at). -func (l *PacketList) insertValue(v Packet, at *PacketElement) *PacketElement { - return l.insert(&PacketElement{Value: v}, at) -} - -// remove removes e from its list, decrements l.len, and returns e. -func (l *PacketList) remove(e *PacketElement) *PacketElement { - e.prev.next = e.next - e.next.prev = e.prev - e.next = nil // avoid memory leaks - e.prev = nil // avoid memory leaks - e.list = nil - l.len-- - return e -} - -// Remove removes e from l if e is an element of list l. -// It returns the element value e.Value. -func (l *PacketList) Remove(e *PacketElement) Packet { - if e.list == l { - // if e.list == l, l must have been initialized when e was inserted - // in l or l == nil (e is a zero PacketElement) and l.remove will crash - l.remove(e) - } - return e.Value -} - -// PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *PacketList) PushFront(v Packet) *PacketElement { - l.lazyInit() - return l.insertValue(v, &l.root) -} - -// PushBack inserts a new element e with value v at the back of list l and returns e. -func (l *PacketList) PushBack(v Packet) *PacketElement { - l.lazyInit() - return l.insertValue(v, l.root.prev) -} - -// InsertBefore inserts a new element e with value v immediately before mark and returns e. -// If mark is not an element of l, the list is not modified. -func (l *PacketList) InsertBefore(v Packet, mark *PacketElement) *PacketElement { - if mark.list != l { - return nil - } - // see comment in PacketList.Remove about initialization of l - return l.insertValue(v, mark.prev) -} - -// InsertAfter inserts a new element e with value v immediately after mark and returns e. -// If mark is not an element of l, the list is not modified. -func (l *PacketList) InsertAfter(v Packet, mark *PacketElement) *PacketElement { - if mark.list != l { - return nil - } - // see comment in PacketList.Remove about initialization of l - return l.insertValue(v, mark) -} - -// MoveToFront moves element e to the front of list l. -// If e is not an element of l, the list is not modified. -func (l *PacketList) MoveToFront(e *PacketElement) { - if e.list != l || l.root.next == e { - return - } - // see comment in PacketList.Remove about initialization of l - l.insert(l.remove(e), &l.root) -} - -// MoveToBack moves element e to the back of list l. -// If e is not an element of l, the list is not modified. -func (l *PacketList) MoveToBack(e *PacketElement) { - if e.list != l || l.root.prev == e { - return - } - // see comment in PacketList.Remove about initialization of l - l.insert(l.remove(e), l.root.prev) -} - -// MoveBefore moves element e to its new position before mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -func (l *PacketList) MoveBefore(e, mark *PacketElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark.prev) -} - -// MoveAfter moves element e to its new position after mark. -// If e is not an element of l, or e == mark, the list is not modified. -func (l *PacketList) MoveAfter(e, mark *PacketElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark) -} - -// PushBackList inserts a copy of an other list at the back of list l. -// The lists l and other may be the same. -func (l *PacketList) PushBackList(other *PacketList) { - l.lazyInit() - for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { - l.insertValue(e.Value, l.root.prev) - } -} - -// PushFrontList inserts a copy of an other list at the front of list l. -// The lists l and other may be the same. -func (l *PacketList) PushFrontList(other *PacketList) { - l.lazyInit() - for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { - l.insertValue(e.Value, &l.root) - } -} diff --git a/ackhandlerlegacy/packet_test.go b/ackhandlerlegacy/packet_test.go deleted file mode 100644 index 7297eb82..00000000 --- a/ackhandlerlegacy/packet_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package ackhandlerlegacy - -import ( - "github.com/lucas-clemente/quic-go/frames" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Packet", func() { - Context("getFramesForRetransmission", func() { - var packet Packet - var streamFrame1, streamFrame2 *frames.StreamFrame - var ackFrame1, ackFrame2 *frames.AckFrame - var stopWaitingFrame *frames.StopWaitingFrame - var rstStreamFrame *frames.RstStreamFrame - var windowUpdateFrame *frames.WindowUpdateFrame - - BeforeEach(func() { - streamFrame1 = &frames.StreamFrame{ - StreamID: 5, - Data: []byte{0x13, 0x37}, - } - streamFrame2 = &frames.StreamFrame{ - StreamID: 6, - Data: []byte{0xDE, 0xCA, 0xFB, 0xAD}, - } - ackFrame1 = &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 13, - Entropy: 5, - }, - } - ackFrame2 = &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 333, - Entropy: 17, - }, - } - rstStreamFrame = &frames.RstStreamFrame{ - StreamID: 555, - ErrorCode: 1337, - } - stopWaitingFrame = &frames.StopWaitingFrame{ - LeastUnacked: 7331, - Entropy: 10, - } - windowUpdateFrame = &frames.WindowUpdateFrame{ - StreamID: 999, - } - packet = Packet{ - PacketNumber: 1337, - Frames: []frames.Frame{windowUpdateFrame, streamFrame1, ackFrame1, streamFrame2, rstStreamFrame, ackFrame2, stopWaitingFrame}, - } - }) - - It("gets all StreamFrames", func() { - streamFrames := packet.GetStreamFramesForRetransmission() - Expect(streamFrames).To(HaveLen(2)) - Expect(streamFrames).To(ContainElement(streamFrame1)) - Expect(streamFrames).To(ContainElement(streamFrame2)) - }) - - It("gets all control frames", func() { - controlFrames := packet.GetControlFramesForRetransmission() - Expect(controlFrames).To(HaveLen(2)) - Expect(controlFrames).To(ContainElement(rstStreamFrame)) - Expect(controlFrames).To(ContainElement(windowUpdateFrame)) - }) - - It("does not return any ACK frames", func() { - controlFrames := packet.GetControlFramesForRetransmission() - Expect(controlFrames).ToNot(ContainElement(ackFrame1)) - Expect(controlFrames).ToNot(ContainElement(ackFrame2)) - }) - - It("does not return any ACK frames", func() { - controlFrames := packet.GetControlFramesForRetransmission() - Expect(controlFrames).ToNot(ContainElement(stopWaitingFrame)) - }) - - It("returns an empty slice of StreamFrames if no StreamFrames are queued", func() { - // overwrite the globally defined packet here - packet := Packet{ - PacketNumber: 1337, - Frames: []frames.Frame{ackFrame1, rstStreamFrame}, - } - streamFrames := packet.GetStreamFramesForRetransmission() - Expect(streamFrames).To(BeEmpty()) - }) - - It("returns an empty slice of control frames if no applicable control frames are queued", func() { - // overwrite the globally defined packet here - packet := Packet{ - PacketNumber: 1337, - Frames: []frames.Frame{streamFrame1, ackFrame1, stopWaitingFrame}, - } - controlFrames := packet.GetControlFramesForRetransmission() - Expect(controlFrames).To(BeEmpty()) - }) - }) -}) diff --git a/ackhandlerlegacy/received_packet_handler.go b/ackhandlerlegacy/received_packet_handler.go deleted file mode 100644 index 4248f321..00000000 --- a/ackhandlerlegacy/received_packet_handler.go +++ /dev/null @@ -1,181 +0,0 @@ -package ackhandlerlegacy - -import ( - "errors" - "time" - - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" - "github.com/lucas-clemente/quic-go/qerr" -) - -var ( - // ErrDuplicatePacket occurres when a duplicate packet is received - ErrDuplicatePacket = errors.New("ReceivedPacketHandler: Duplicate Packet") - // ErrPacketSmallerThanLastStopWaiting occurs when a packet arrives with a packet number smaller than the largest LeastUnacked of a StopWaitingFrame. If this error occurs, the packet should be ignored - ErrPacketSmallerThanLastStopWaiting = errors.New("ReceivedPacketHandler: Packet number smaller than highest StopWaiting") -) - -var ( - errInvalidPacketNumber = errors.New("ReceivedPacketHandler: Invalid packet number") - errTooManyOutstandingReceivedPackets = qerr.Error(qerr.TooManyOutstandingReceivedPackets, "") -) - -type packetHistoryEntry struct { - EntropyBit bool - TimeReceived time.Time -} - -type receivedPacketHandler struct { - highestInOrderObserved protocol.PacketNumber - highestInOrderObservedEntropy EntropyAccumulator - largestObserved protocol.PacketNumber - ignorePacketsBelow protocol.PacketNumber - currentAckFrame *frames.AckFrame - stateChanged bool // has an ACK for this state already been sent? Will be set to false every time a new packet arrives, and to false every time an ACK is sent - - packetHistory map[protocol.PacketNumber]packetHistoryEntry - smallestInPacketHistory protocol.PacketNumber -} - -// NewReceivedPacketHandler creates a new receivedPacketHandler -func NewReceivedPacketHandler() ReceivedPacketHandler { - return &receivedPacketHandler{ - packetHistory: make(map[protocol.PacketNumber]packetHistoryEntry), - } -} - -func (h *receivedPacketHandler) ReceivedPacket(packetNumber protocol.PacketNumber, entropyBit bool) error { - if packetNumber == 0 { - return errInvalidPacketNumber - } - - // if the packet number is smaller than the largest LeastUnacked value of a StopWaiting we received, we cannot detect if this packet has a duplicate number - // the packet has to be ignored anyway - if packetNumber <= h.ignorePacketsBelow { - return ErrPacketSmallerThanLastStopWaiting - } - - _, ok := h.packetHistory[packetNumber] - if packetNumber <= h.highestInOrderObserved || ok { - return ErrDuplicatePacket - } - - h.stateChanged = true - h.currentAckFrame = nil - - if packetNumber > h.largestObserved { - h.largestObserved = packetNumber - } - - h.packetHistory[packetNumber] = packetHistoryEntry{ - EntropyBit: entropyBit, - TimeReceived: time.Now(), - } - - // Try to increase highestInOrderObserved as far as possible - for { - p, ok := h.packetHistory[h.highestInOrderObserved+1] - if !ok { - break - } - h.highestInOrderObserved++ - h.highestInOrderObservedEntropy.Add(h.highestInOrderObserved, p.EntropyBit) - } - - h.garbageCollect() - - if uint32(len(h.packetHistory)) > protocol.MaxTrackedReceivedPackets { - return errTooManyOutstandingReceivedPackets - } - - return nil -} - -func (h *receivedPacketHandler) ReceivedStopWaiting(f *frames.StopWaitingFrame) error { - // ignore if StopWaiting is unneeded, because we already received a StopWaiting with a higher LeastUnacked - if h.ignorePacketsBelow >= f.LeastUnacked { - return nil - } - - h.ignorePacketsBelow = f.LeastUnacked - 1 - - // ignore if StopWaiting is unneeded, since all packets below have already been received - if h.highestInOrderObserved >= f.LeastUnacked { - return nil - } - - // the LeastUnacked is the smallest packet number of any packet for which the sender is still awaiting an ack. So the highestInOrderObserved is one less than that - h.highestInOrderObserved = f.LeastUnacked - 1 - h.highestInOrderObservedEntropy = EntropyAccumulator(f.Entropy) - - h.garbageCollect() - - return nil -} - -// getNackRanges gets all the NACK ranges -func (h *receivedPacketHandler) getNackRanges() ([]frames.NackRange, EntropyAccumulator) { - // TODO: use a better data structure here - var ranges []frames.NackRange - inRange := false - entropy := h.highestInOrderObservedEntropy - for i := h.largestObserved; i > h.highestInOrderObserved; i-- { - p, ok := h.packetHistory[i] - if !ok { - if !inRange { - r := frames.NackRange{ - FirstPacketNumber: i, - LastPacketNumber: i, - } - ranges = append(ranges, r) - inRange = true - } else { - ranges[len(ranges)-1].FirstPacketNumber-- - } - } else { - inRange = false - entropy.Add(i, p.EntropyBit) - } - } - return ranges, entropy -} - -func (h *receivedPacketHandler) GetAckFrame(dequeue bool) (*frames.AckFrame, error) { - if !h.stateChanged { - return nil, nil - } - - if dequeue { - h.stateChanged = false - } - - if h.currentAckFrame != nil { - return h.currentAckFrame, nil - } - - p, ok := h.packetHistory[h.largestObserved] - if !ok { - return nil, ErrMapAccess - } - packetReceivedTime := p.TimeReceived - - nackRanges, entropy := h.getNackRanges() - h.currentAckFrame = &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: h.largestObserved, - Entropy: byte(entropy), - NackRanges: nackRanges, - PacketReceivedTime: packetReceivedTime, - }, - } - - return h.currentAckFrame, nil -} - -func (h *receivedPacketHandler) garbageCollect() { - for i := h.smallestInPacketHistory; i < h.highestInOrderObserved; i++ { - delete(h.packetHistory, i) - } - h.smallestInPacketHistory = h.highestInOrderObserved -} diff --git a/ackhandlerlegacy/received_packet_handler_test.go b/ackhandlerlegacy/received_packet_handler_test.go deleted file mode 100644 index 6de99d2b..00000000 --- a/ackhandlerlegacy/received_packet_handler_test.go +++ /dev/null @@ -1,431 +0,0 @@ -package ackhandlerlegacy - -import ( - "time" - - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("receivedPacketHandler", func() { - var ( - handler *receivedPacketHandler - expectedEntropy EntropyAccumulator - ) - - BeforeEach(func() { - handler = NewReceivedPacketHandler().(*receivedPacketHandler) - expectedEntropy = EntropyAccumulator(0) - }) - - Context("accepting packets", func() { - It("handles a packet that arrives late", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(1), false) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1))) - err = handler.ReceivedPacket(protocol.PacketNumber(3), false) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - err = handler.ReceivedPacket(protocol.PacketNumber(2), false) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - }) - - It("rejects packets with packet number 0", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(0), false) - Expect(err).To(MatchError(errInvalidPacketNumber)) - }) - - It("rejects a duplicate package with PacketNumber equal to LargestObserved", func() { - for i := 1; i < 5; i++ { - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) - Expect(err).ToNot(HaveOccurred()) - } - err := handler.ReceivedPacket(4, false) - Expect(err).To(MatchError(ErrDuplicatePacket)) - }) - - It("rejects a duplicate package with PacketNumber less than the LargestObserved", func() { - for i := 1; i < 5; i++ { - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) - Expect(err).ToNot(HaveOccurred()) - } - err := handler.ReceivedPacket(2, false) - Expect(err).To(MatchError(ErrDuplicatePacket)) - }) - - It("ignores a packet with PacketNumber less than the LeastUnacked of a previously received StopWaiting", func() { - err := handler.ReceivedPacket(5, false) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: 10}) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(9, false) - Expect(err).To(MatchError(ErrPacketSmallerThanLastStopWaiting)) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(9))) - }) - - It("does not ignore a packet with PacketNumber equal to LeastUnacked of a previously received StopWaiting", func() { - err := handler.ReceivedPacket(5, false) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: 10}) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(10, false) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(10))) - }) - - It("saves the time when each packet arrived", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(3), false) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - Expect(handler.packetHistory[3].TimeReceived).To(BeTemporally("~", time.Now(), 10*time.Millisecond)) - }) - - It("doesn't store more than MaxTrackedReceivedPackets packets", func() { - for i := uint32(0); i < protocol.MaxTrackedReceivedPackets; i++ { - packetNumber := protocol.PacketNumber(1 + 2*i) - err := handler.ReceivedPacket(packetNumber, true) - Expect(err).ToNot(HaveOccurred()) - } - err := handler.ReceivedPacket(protocol.PacketNumber(3*protocol.MaxTrackedReceivedPackets), true) - Expect(err).To(MatchError(errTooManyOutstandingReceivedPackets)) - }) - }) - - Context("Entropy calculation", func() { - It("calculates the entropy for continuously received packets", func() { - for i := 1; i < 100; i++ { - entropyBit := false - if i%3 == 0 || i%5 == 0 { - entropyBit = true - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.highestInOrderObservedEntropy).To(Equal(expectedEntropy)) - }) - - It("calculates the entropy if there is a NACK range", func() { - for i := 1; i < 100; i++ { - entropyBit := false - if i%3 == 0 || i%5 == 0 { - entropyBit = true - } - - if i == 10 || i == 11 || i == 12 { - continue - } - if i < 10 { - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - } - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.highestInOrderObservedEntropy).To(Equal(expectedEntropy)) - }) - }) - - Context("NACK range calculation", func() { - It("Returns no NACK ranges for continuously received packets", func() { - for i := 1; i < 100; i++ { - entropyBit := false - if i%2 == 0 { - entropyBit = true - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(99))) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(99))) - nackRanges, entropy := handler.getNackRanges() - Expect(nackRanges).To(BeEmpty()) - Expect(entropy).To(Equal(expectedEntropy)) - }) - - It("handles a single lost package", func() { - for i := 1; i < 10; i++ { - entropyBit := true - if i == 5 { - continue - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges, entropy := handler.getNackRanges() - Expect(nackRanges).To(HaveLen(1)) - Expect(nackRanges[0]).To(Equal(frames.NackRange{FirstPacketNumber: 5, LastPacketNumber: 5})) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(4))) - Expect(entropy).To(Equal(expectedEntropy)) - }) - - It("handles two consecutive lost packages", func() { - for i := 1; i < 12; i++ { - entropyBit := false - if i%2 == 0 || i == 5 { - entropyBit = true - } - if i == 5 || i == 6 { - continue - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(11))) - nackRanges, entropy := handler.getNackRanges() - Expect(nackRanges).To(HaveLen(1)) - Expect(nackRanges[0]).To(Equal(frames.NackRange{FirstPacketNumber: 5, LastPacketNumber: 6})) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(4))) - Expect(entropy).To(Equal(expectedEntropy)) - }) - - It("handles two non-consecutively lost packages", func() { - for i := 1; i < 10; i++ { - entropyBit := false - if i%2 != 0 { - entropyBit = true - } - if i == 3 || i == 7 { - continue - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges, entropy := handler.getNackRanges() - Expect(nackRanges).To(HaveLen(2)) - Expect(nackRanges[0]).To(Equal(frames.NackRange{FirstPacketNumber: 7, LastPacketNumber: 7})) - Expect(nackRanges[1]).To(Equal(frames.NackRange{FirstPacketNumber: 3, LastPacketNumber: 3})) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(2))) - Expect(entropy).To(Equal(expectedEntropy)) - }) - - It("handles two sequences of lost packages", func() { - for i := 1; i < 10; i++ { - entropyBit := true - if i == 2 || i == 3 || i == 4 || i == 7 || i == 8 { - continue - } - expectedEntropy.Add(protocol.PacketNumber(i), entropyBit) - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.largestObserved).To(Equal(protocol.PacketNumber(9))) - nackRanges, entropy := handler.getNackRanges() - Expect(nackRanges).To(HaveLen(2)) - Expect(nackRanges[0]).To(Equal(frames.NackRange{FirstPacketNumber: 7, LastPacketNumber: 8})) - Expect(nackRanges[1]).To(Equal(frames.NackRange{FirstPacketNumber: 2, LastPacketNumber: 4})) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(1))) - Expect(entropy).To(Equal(expectedEntropy)) - }) - }) - - Context("handling STOP_WAITING frames", func() { - It("resets the entropy", func() { - // We simulate 20 packets, numbers 10, 11 and 12 lost - expectedAfterStopWaiting := EntropyAccumulator(0) - for i := 1; i < 20; i++ { - entropyBit := false - if i%3 == 0 || i%5 == 0 { - entropyBit = true - } - - if i == 10 || i == 11 || i == 12 { - continue - } - if i > 12 { - expectedAfterStopWaiting.Add(protocol.PacketNumber(i), entropyBit) - } - err := handler.ReceivedPacket(protocol.PacketNumber(i), entropyBit) - Expect(err).ToNot(HaveOccurred()) - } - err := handler.ReceivedStopWaiting(&frames.StopWaitingFrame{Entropy: 42, LeastUnacked: protocol.PacketNumber(12)}) - Expect(err).ToNot(HaveOccurred()) - _, e := handler.getNackRanges() - Expect(e).To(Equal(42 ^ expectedAfterStopWaiting)) - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(11))) - Expect(handler.highestInOrderObservedEntropy).To(Equal(EntropyAccumulator(42))) - }) - - It("does not emit NACK ranges after STOP_WAITING", func() { - err := handler.ReceivedPacket(10, false) - Expect(err).ToNot(HaveOccurred()) - ranges, _ := handler.getNackRanges() - Expect(ranges).To(HaveLen(1)) - err = handler.ReceivedStopWaiting(&frames.StopWaitingFrame{Entropy: 0, LeastUnacked: protocol.PacketNumber(10)}) - Expect(err).ToNot(HaveOccurred()) - ranges, _ = handler.getNackRanges() - Expect(ranges).To(BeEmpty()) - }) - - It("increases the ignorePacketsBelow number", func() { - err := handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: protocol.PacketNumber(12)}) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.ignorePacketsBelow).To(Equal(protocol.PacketNumber(11))) - }) - - It("increase the ignorePacketsBelow number, even if all packets below the LeastUnacked were already acked", func() { - for i := 1; i < 20; i++ { - err := handler.ReceivedPacket(protocol.PacketNumber(i), false) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.highestInOrderObserved).To(Equal(protocol.PacketNumber(19))) - err := handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: protocol.PacketNumber(12)}) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.ignorePacketsBelow).To(Equal(protocol.PacketNumber(11))) - }) - - It("does not decrease the ignorePacketsBelow number when an out-of-order StopWaiting arrives", func() { - err := handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: protocol.PacketNumber(12)}) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.ignorePacketsBelow).To(Equal(protocol.PacketNumber(11))) - err = handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: protocol.PacketNumber(6)}) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.ignorePacketsBelow).To(Equal(protocol.PacketNumber(11))) - }) - }) - - Context("ACK package generation", func() { - It("generates a simple ACK frame", func() { - entropy := EntropyAccumulator(0) - entropy.Add(1, true) - entropy.Add(2, true) - err := handler.ReceivedPacket(protocol.PacketNumber(1), true) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(protocol.PacketNumber(2), true) - Expect(err).ToNot(HaveOccurred()) - ack, err := handler.GetAckFrame(true) - Expect(err).ToNot(HaveOccurred()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(2))) - Expect(ack.AckFrameLegacy.Entropy).To(Equal(byte(entropy))) - }) - - It("generates an ACK frame with a NACK range", func() { - entropy := EntropyAccumulator(0) - entropy.Add(1, true) - entropy.Add(4, true) - err := handler.ReceivedPacket(protocol.PacketNumber(1), true) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(protocol.PacketNumber(4), true) - Expect(err).ToNot(HaveOccurred()) - ack, err := handler.GetAckFrame(true) - Expect(err).ToNot(HaveOccurred()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(4))) - Expect(ack.AckFrameLegacy.Entropy).To(Equal(byte(entropy))) - Expect(ack.AckFrameLegacy.NackRanges).To(Equal([]frames.NackRange{{FirstPacketNumber: 2, LastPacketNumber: 3}})) - }) - - It("does not generate an ACK if an ACK has already been sent for the largest Packet", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(1), false) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(protocol.PacketNumber(2), false) - Expect(err).ToNot(HaveOccurred()) - ack, err := handler.GetAckFrame(true) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).ToNot(BeNil()) - ack, err = handler.GetAckFrame(true) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).To(BeNil()) - }) - - It("does not dequeue an ACK frame if told so", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(2), false) - Expect(err).ToNot(HaveOccurred()) - ack, err := handler.GetAckFrame(false) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).ToNot(BeNil()) - ack, err = handler.GetAckFrame(false) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).ToNot(BeNil()) - ack, err = handler.GetAckFrame(false) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).ToNot(BeNil()) - }) - - It("returns a cached ACK frame if the ACK was not dequeued", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(2), false) - Expect(err).ToNot(HaveOccurred()) - ack, err := handler.GetAckFrame(false) - Expect(err).ToNot(HaveOccurred()) - Expect(ack).ToNot(BeNil()) - ack2, err := handler.GetAckFrame(false) - Expect(err).ToNot(HaveOccurred()) - Expect(ack2).ToNot(BeNil()) - Expect(&ack).To(Equal(&ack2)) - }) - - It("generates a new ACK (and deletes the cached one) when a new packet arrives", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(1), false) - Expect(err).ToNot(HaveOccurred()) - ack, _ := handler.GetAckFrame(true) - Expect(ack).ToNot(BeNil()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(1))) - err = handler.ReceivedPacket(protocol.PacketNumber(3), false) - Expect(err).ToNot(HaveOccurred()) - ack, _ = handler.GetAckFrame(true) - Expect(ack).ToNot(BeNil()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(3))) - }) - - It("generates a new ACK when an out-of-order packet arrives", func() { - err := handler.ReceivedPacket(protocol.PacketNumber(1), false) - Expect(err).ToNot(HaveOccurred()) - err = handler.ReceivedPacket(protocol.PacketNumber(3), false) - Expect(err).ToNot(HaveOccurred()) - ack, _ := handler.GetAckFrame(true) - Expect(ack).ToNot(BeNil()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.NackRanges).To(HaveLen(1)) - err = handler.ReceivedPacket(protocol.PacketNumber(2), false) - Expect(err).ToNot(HaveOccurred()) - ack, _ = handler.GetAckFrame(true) - Expect(ack).ToNot(BeNil()) - Expect(ack.AckFrameLegacy).ToNot(BeNil()) - Expect(ack.AckFrameLegacy.NackRanges).To(BeEmpty()) - }) - }) - - Context("Garbage Collector", func() { - It("only keeps packets with packet numbers higher than the highestInOrderObserved in packetHistory", func() { - handler.ReceivedPacket(1, true) - handler.ReceivedPacket(2, true) - handler.ReceivedPacket(4, true) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(4))) - }) - - It("garbage collects packetHistory after receiving a StopWaiting", func() { - handler.ReceivedPacket(1, true) - handler.ReceivedPacket(2, true) - handler.ReceivedPacket(4, true) - swf := frames.StopWaitingFrame{LeastUnacked: 4} - handler.ReceivedStopWaiting(&swf) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(1))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(4))) - }) - - It("garbage collects after receiving out-of-order packets without STOP_WAITING", func() { - handler.ReceivedPacket(2, true) - handler.ReceivedPacket(1, true) - handler.ReceivedPacket(3, true) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(1))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - }) - }) -}) diff --git a/ackhandlerlegacy/sent_packet_handler.go b/ackhandlerlegacy/sent_packet_handler.go deleted file mode 100644 index c2e59719..00000000 --- a/ackhandlerlegacy/sent_packet_handler.go +++ /dev/null @@ -1,358 +0,0 @@ -package ackhandlerlegacy - -import ( - "errors" - "time" - - "github.com/lucas-clemente/quic-go/congestion" - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" - "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/utils" -) - -var ( - // ErrDuplicateOrOutOfOrderAck occurs when a duplicate or an out-of-order ACK is received - ErrDuplicateOrOutOfOrderAck = errors.New("SentPacketHandler: Duplicate or out-of-order ACK") - // 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") - // ErrTooManyTrackedSentPackets occurs when the sentPacketHandler has to keep track of too many packets - ErrTooManyTrackedSentPackets = errors.New("Too many outstanding non-acked and non-retransmitted packets") - errAckForUnsentPacket = qerr.Error(qerr.InvalidAckData, "Received ACK for an unsent package") -) - -var ( - errDuplicatePacketNumber = errors.New("Packet number already exists in Packet History") - errWrongPacketNumberIncrement = errors.New("Packet number must be increased by exactly 1") -) - -type sentPacketHandler struct { - lastSentPacketNumber protocol.PacketNumber - lastSentPacketEntropy EntropyAccumulator - lastSentPacketTime time.Time - highestInOrderAckedPacketNumber protocol.PacketNumber - LargestObserved protocol.PacketNumber - LargestObservedEntropy EntropyAccumulator - - largestReceivedPacketWithAck protocol.PacketNumber - - // TODO: Move into separate class as in chromium - packetHistory map[protocol.PacketNumber]*Packet - - retransmissionQueue []*Packet - stopWaitingManager StopWaitingManager - - bytesInFlight protocol.ByteCount - - rttStats *congestion.RTTStats - congestion congestion.SendAlgorithm -} - -// NewSentPacketHandler creates a new sentPacketHandler -func NewSentPacketHandler(stopWaitingManager StopWaitingManager) SentPacketHandler { - rttStats := &congestion.RTTStats{} - - congestion := congestion.NewCubicSender( - congestion.DefaultClock{}, - rttStats, - false, /* don't use reno since chromium doesn't (why?) */ - protocol.InitialCongestionWindow, - protocol.DefaultMaxCongestionWindow, - ) - - return &sentPacketHandler{ - packetHistory: make(map[protocol.PacketNumber]*Packet), - stopWaitingManager: stopWaitingManager, - rttStats: rttStats, - congestion: congestion, - } -} - -func (h *sentPacketHandler) ackPacket(packetNumber protocol.PacketNumber) *Packet { - packet, ok := h.packetHistory[packetNumber] - if ok && !packet.Retransmitted { - h.bytesInFlight -= packet.Length - } - delete(h.packetHistory, packetNumber) - - h.stopWaitingManager.ReceivedAckForPacketNumber(packetNumber) - - return packet -} - -func (h *sentPacketHandler) nackPacket(packetNumber protocol.PacketNumber) (*Packet, error) { - packet, ok := h.packetHistory[packetNumber] - if !ok { - return nil, ErrMapAccess - } - - // If the packet has already been retransmitted, do nothing. - // We're probably only receiving another NACK for this packet because the - // retransmission has not yet arrived at the client. - if packet.Retransmitted { - return nil, nil - } - - packet.MissingReports++ - - if packet.MissingReports > protocol.RetransmissionThreshold { - utils.Debugf("\tQueueing packet 0x%x for retransmission (fast)", packet.PacketNumber) - h.queuePacketForRetransmission(packet) - return packet, nil - } - return nil, nil -} - -func (h *sentPacketHandler) queuePacketForRetransmission(packet *Packet) { - h.bytesInFlight -= packet.Length - h.retransmissionQueue = append(h.retransmissionQueue, packet) - packet.Retransmitted = true -} - -func (h *sentPacketHandler) SentPacket(packet *Packet) error { - _, ok := h.packetHistory[packet.PacketNumber] - if ok { - return errDuplicatePacketNumber - } - if h.lastSentPacketNumber+1 != packet.PacketNumber { - return errWrongPacketNumberIncrement - } - now := time.Now() - h.lastSentPacketTime = now - packet.SendTime = now - if packet.Length == 0 { - return errors.New("SentPacketHandler: packet cannot be empty") - } - h.bytesInFlight += packet.Length - - h.lastSentPacketEntropy.Add(packet.PacketNumber, packet.EntropyBit) - packet.Entropy = h.lastSentPacketEntropy - h.lastSentPacketNumber = packet.PacketNumber - h.packetHistory[packet.PacketNumber] = packet - - h.congestion.OnPacketSent( - time.Now(), - h.BytesInFlight(), - packet.PacketNumber, - packet.Length, - true, /* TODO: is retransmittable */ - ) - - return nil -} - -func (h *sentPacketHandler) calculateExpectedEntropy(ackFrame *frames.AckFrameLegacy) (EntropyAccumulator, error) { - var expectedEntropy EntropyAccumulator - if ackFrame.LargestObserved == h.LargestObserved { - expectedEntropy = h.LargestObservedEntropy - } else { - packet, ok := h.packetHistory[ackFrame.LargestObserved] - if !ok { - return 0, ErrMapAccess - } - expectedEntropy = packet.Entropy - } - - if ackFrame.HasNACK() { // if the packet has NACKs, the entropy value has to be calculated - nackRangeIndex := 0 - nackRange := ackFrame.NackRanges[nackRangeIndex] - for i := ackFrame.LargestObserved; i > ackFrame.GetHighestInOrderPacketNumber(); i-- { - if i < nackRange.FirstPacketNumber { - nackRangeIndex++ - if nackRangeIndex < len(ackFrame.NackRanges) { - nackRange = ackFrame.NackRanges[nackRangeIndex] - } - } - if nackRange.ContainsPacketNumber(i) { - packet, ok := h.packetHistory[i] - if !ok { - return 0, ErrMapAccess - } - expectedEntropy.Subtract(i, packet.EntropyBit) - } - } - } - - return expectedEntropy, nil -} - -// TODO: Simplify return types -func (h *sentPacketHandler) ReceivedAck(ackFrameOrig *frames.AckFrame, withPacketNumber protocol.PacketNumber) error { - ackFrame := ackFrameOrig.AckFrameLegacy - if ackFrame.LargestObserved > h.lastSentPacketNumber { - return errAckForUnsentPacket - } - - // duplicate or out-of-order ACK - if withPacketNumber <= h.largestReceivedPacketWithAck { - return ErrDuplicateOrOutOfOrderAck - } - - h.largestReceivedPacketWithAck = withPacketNumber - - // ignore repeated ACK (ACKs that don't have a higher LargestObserved than the last ACK) - if ackFrame.LargestObserved <= h.highestInOrderAckedPacketNumber { - return nil - } - - expectedEntropy, err := h.calculateExpectedEntropy(ackFrame) - if err != nil { - return err - } - - if byte(expectedEntropy) != ackFrame.Entropy { - return ErrEntropy - } - - // Entropy ok. Now actually process the ACK packet - h.LargestObserved = ackFrame.LargestObserved - highestInOrderAckedPacketNumber := ackFrame.GetHighestInOrderPacketNumber() - - packet, ok := h.packetHistory[h.LargestObserved] - if ok { - h.LargestObservedEntropy = packet.Entropy - - // Update the RTT - timeDelta := time.Now().Sub(packet.SendTime) - // TODO: Don't always update RTT - h.rttStats.UpdateRTT(timeDelta, ackFrame.DelayTime, time.Now()) - if utils.Debug() { - utils.Debugf("\tEstimated RTT: %dms", h.rttStats.SmoothedRTT()/time.Millisecond) - } - } - - var ackedPackets congestion.PacketVector - var lostPackets congestion.PacketVector - - // ACK all packets below the highestInOrderAckedPacketNumber - for i := h.highestInOrderAckedPacketNumber; i <= highestInOrderAckedPacketNumber; i++ { - p := h.ackPacket(i) - if p != nil { - ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length}) - } - } - - if ackFrame.HasNACK() { - nackRangeIndex := 0 - nackRange := ackFrame.NackRanges[nackRangeIndex] - for i := ackFrame.LargestObserved; i > ackFrame.GetHighestInOrderPacketNumber(); i-- { - if i < nackRange.FirstPacketNumber { - nackRangeIndex++ - if nackRangeIndex < len(ackFrame.NackRanges) { - nackRange = ackFrame.NackRanges[nackRangeIndex] - } - } - if nackRange.ContainsPacketNumber(i) { - p, err := h.nackPacket(i) - if err != nil { - return err - } - if p != nil { - lostPackets = append(lostPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length}) - } - } else { - p := h.ackPacket(i) - if p != nil { - ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length}) - } - } - } - } - - h.highestInOrderAckedPacketNumber = highestInOrderAckedPacketNumber - - h.congestion.OnCongestionEvent( - true, /* TODO: rtt updated */ - h.BytesInFlight(), - ackedPackets, - lostPackets, - ) - - return nil -} - -func (h *sentPacketHandler) DequeuePacketForRetransmission() (packet *Packet) { - if len(h.retransmissionQueue) == 0 { - return nil - } - - for len(h.retransmissionQueue) > 0 { - queueLen := len(h.retransmissionQueue) - // packets are usually NACKed in descending order. So use the slice as a stack - packet = h.retransmissionQueue[queueLen-1] - h.retransmissionQueue = h.retransmissionQueue[:queueLen-1] - - // check if the packet was ACKed after it was already queued for retransmission - // if so, it doesn't exist in the packetHistory anymore. Skip it then - _, ok := h.packetHistory[packet.PacketNumber] - if !ok { - continue - } - return packet - } - - return nil -} - -func (h *sentPacketHandler) BytesInFlight() protocol.ByteCount { - return h.bytesInFlight -} - -func (h *sentPacketHandler) GetLeastUnacked() protocol.PacketNumber { - return h.highestInOrderAckedPacketNumber + 1 -} - -func (h *sentPacketHandler) GetStopWaitingFrame(force bool) *frames.StopWaitingFrame { - panic("Legacy AckHandler should use StopWaitingManager") -} - -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) MaybeQueueRTOs() { - if time.Now().Before(h.TimeOfFirstRTO()) { - return - } - for p := h.highestInOrderAckedPacketNumber + 1; p <= h.lastSentPacketNumber; p++ { - packet := h.packetHistory[p] - if packet != nil && !packet.Retransmitted { - packetsLost := congestion.PacketVector{congestion.PacketInfo{ - Number: packet.PacketNumber, - Length: packet.Length, - }} - h.congestion.OnCongestionEvent(false, h.BytesInFlight(), nil, packetsLost) - h.congestion.OnRetransmissionTimeout(true) - utils.Debugf("\tQueueing packet 0x%x for retransmission (RTO)", packet.PacketNumber) - h.queuePacketForRetransmission(packet) - // Reset the RTO timer here, since it's not clear that this packet contained any retransmittable frames - h.lastSentPacketTime = time.Now() - return - } - } -} - -func (h *sentPacketHandler) getRTO() time.Duration { - rto := h.congestion.RetransmissionDelay() - if rto == 0 { - rto = protocol.DefaultRetransmissionTime - } - return utils.MaxDuration(rto, protocol.MinRetransmissionTime) -} - -func (h *sentPacketHandler) TimeOfFirstRTO() time.Time { - if h.lastSentPacketTime.IsZero() { - return time.Time{} - } - return h.lastSentPacketTime.Add(h.getRTO()) -} diff --git a/ackhandlerlegacy/sent_packet_handler_test.go b/ackhandlerlegacy/sent_packet_handler_test.go deleted file mode 100644 index aa48a117..00000000 --- a/ackhandlerlegacy/sent_packet_handler_test.go +++ /dev/null @@ -1,808 +0,0 @@ -package ackhandlerlegacy - -import ( - "time" - - "github.com/lucas-clemente/quic-go/congestion" - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -type mockCongestion struct { - nCalls int - argsOnPacketSent []interface{} - argsOnCongestionEvent []interface{} - onRetransmissionTimeout bool -} - -func (m *mockCongestion) TimeUntilSend(now time.Time, bytesInFlight protocol.ByteCount) time.Duration { - panic("not implemented") -} - -func (m *mockCongestion) OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) bool { - m.nCalls++ - m.argsOnPacketSent = []interface{}{sentTime, bytesInFlight, packetNumber, bytes, isRetransmittable} - return false -} - -func (m *mockCongestion) GetCongestionWindow() protocol.ByteCount { - m.nCalls++ - return protocol.DefaultTCPMSS -} - -func (m *mockCongestion) OnCongestionEvent(rttUpdated bool, bytesInFlight protocol.ByteCount, ackedPackets congestion.PacketVector, lostPackets congestion.PacketVector) { - m.nCalls++ - m.argsOnCongestionEvent = []interface{}{rttUpdated, bytesInFlight, ackedPackets, lostPackets} -} - -func (m *mockCongestion) OnRetransmissionTimeout(packetsRetransmitted bool) { - m.nCalls++ - m.onRetransmissionTimeout = true -} - -func (m *mockCongestion) RetransmissionDelay() time.Duration { - return protocol.DefaultRetransmissionTime -} - -func (m *mockCongestion) SetNumEmulatedConnections(n int) { panic("not implemented") } -func (m *mockCongestion) OnConnectionMigration() { panic("not implemented") } -func (m *mockCongestion) SetSlowStartLargeReduction(enabled bool) { panic("not implemented") } - -type mockStopWaiting struct { - receivedAckForPacketNumber protocol.PacketNumber -} - -func (m *mockStopWaiting) RegisterPacketForRetransmission(packet *Packet) { panic("not implemented") } -func (m *mockStopWaiting) GetStopWaitingFrame() *frames.StopWaitingFrame { panic("not implemented") } -func (m *mockStopWaiting) SentStopWaitingWithPacket(packetNumber protocol.PacketNumber) { - panic("not implemented") -} -func (m *mockStopWaiting) ReceivedAckForPacketNumber(packetNumber protocol.PacketNumber) { - m.receivedAckForPacketNumber = packetNumber -} - -var _ = Describe("SentPacketHandler", func() { - var ( - handler *sentPacketHandler - streamFrame frames.StreamFrame - ) - - BeforeEach(func() { - stopWaitingManager := &mockStopWaiting{} - handler = NewSentPacketHandler(stopWaitingManager).(*sentPacketHandler) - streamFrame = frames.StreamFrame{ - StreamID: 5, - Data: []byte{0x13, 0x37}, - } - }) - - It("informs the StopWaitingManager about ACKs received", func() { - handler.ackPacket(2) - Expect(handler.stopWaitingManager.(*mockStopWaiting).receivedAckForPacketNumber).To(Equal(protocol.PacketNumber(2))) - }) - - Context("SentPacket", func() { - It("accepts two consecutive packets", func() { - entropy := EntropyAccumulator(0) - packet1 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - packet2 := Packet{PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 2} - err := handler.SentPacket(&packet1) - Expect(err).ToNot(HaveOccurred()) - err = handler.SentPacket(&packet2) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2))) - entropy.Add(packet1.PacketNumber, packet1.EntropyBit) - Expect(handler.packetHistory[1].PacketNumber).To(Equal(protocol.PacketNumber(1))) - Expect(handler.packetHistory[1].Entropy).To(Equal(entropy)) - entropy.Add(packet2.PacketNumber, packet2.EntropyBit) - Expect(handler.packetHistory[2].PacketNumber).To(Equal(protocol.PacketNumber(2))) - Expect(handler.packetHistory[2].Entropy).To(Equal(entropy)) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - }) - - It("rejects packets with the same packet number", func() { - packet1 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - packet2 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 2} - err := handler.SentPacket(&packet1) - Expect(err).ToNot(HaveOccurred()) - err = handler.SentPacket(&packet2) - Expect(err).To(MatchError(errDuplicatePacketNumber)) - Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1))) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - }) - - It("rejects non-consecutive packets", func() { - packet1 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - packet2 := Packet{PacketNumber: 3, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 2} - err := handler.SentPacket(&packet1) - Expect(err).ToNot(HaveOccurred()) - err = handler.SentPacket(&packet2) - Expect(err).To(MatchError(errWrongPacketNumberIncrement)) - Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - }) - - It("correctly calculates the entropy, even if the last packet has already been ACKed", func() { - packet1 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - packet2 := Packet{PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 2} - err := handler.SentPacket(&packet1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - entropy := EntropyAccumulator(0) - entropy.Add(packet1.PacketNumber, packet1.EntropyBit) - ack := frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 1, - Entropy: byte(entropy), - }, - } - err = handler.ReceivedAck(&ack, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(0))) - err = handler.SentPacket(&packet2) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(2))) - Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2))) - entropy.Add(packet2.PacketNumber, packet2.EntropyBit) - Expect(handler.packetHistory[2].Entropy).To(Equal(entropy)) - }) - - It("stores the sent time", func() { - packet := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - err := handler.SentPacket(&packet) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.packetHistory[1].SendTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1)) - }) - - It("updates the last sent time", func() { - packet := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1} - err := handler.SentPacket(&packet) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.lastSentPacketTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1)) - }) - }) - - 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 - - BeforeEach(func() { - entropy = EntropyAccumulator(0) - packets = []*Packet{ - {PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - {PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - {PacketNumber: 3, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - {PacketNumber: 4, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - {PacketNumber: 5, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - {PacketNumber: 6, Frames: []frames.Frame{&streamFrame}, EntropyBit: true, Length: 1}, - } - for _, packet := range packets { - handler.SentPacket(packet) - } - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(6))) - }) - - It("no NACK ranges", func() { - largestObserved := 5 - for i := 0; i < largestObserved; i++ { - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack := frames.AckFrameLegacy{LargestObserved: protocol.PacketNumber(largestObserved)} - calculatedEntropy, err := handler.calculateExpectedEntropy(&ack) - Expect(err).ToNot(HaveOccurred()) - Expect(calculatedEntropy).To(Equal(entropy)) - }) - - It("one NACK ranges", func() { - largestObserved := 5 - for i := 0; i < largestObserved; i++ { - if i == 2 || i == 3 { // skip Packet 3 and 4 - continue - } - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - NackRanges: []frames.NackRange{{FirstPacketNumber: 3, LastPacketNumber: 4}}, - } - calculatedEntropy, err := handler.calculateExpectedEntropy(&ack) - Expect(err).ToNot(HaveOccurred()) - Expect(calculatedEntropy).To(Equal(entropy)) - }) - - It("one NACK ranges, when some packages have already been ACKed", func() { - largestObserved := 6 - for i := 0; i < largestObserved; i++ { - if i == 2 || i == 3 { // skip Packet 3 and 4 - continue - } - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - handler.ackPacket(1) - handler.ackPacket(2) - handler.ackPacket(5) - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - NackRanges: []frames.NackRange{{FirstPacketNumber: 3, LastPacketNumber: 4}}, - } - calculatedEntropy, err := handler.calculateExpectedEntropy(&ack) - Expect(err).ToNot(HaveOccurred()) - Expect(calculatedEntropy).To(Equal(entropy)) - }) - - It("multiple NACK ranges", func() { - largestObserved := 5 - for i := 0; i < largestObserved; i++ { - if i == 1 || i == 3 { // skip Packet 2 and 4 - continue - } - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - NackRanges: []frames.NackRange{ - {FirstPacketNumber: 4, LastPacketNumber: 4}, - {FirstPacketNumber: 2, LastPacketNumber: 2}, - }, - } - calculatedEntropy, err := handler.calculateExpectedEntropy(&ack) - Expect(err).ToNot(HaveOccurred()) - Expect(calculatedEntropy).To(Equal(entropy)) - }) - - It("actually rejects an ACK with the wrong entropy", func() { - ack := frames.AckFrameLegacy{ - LargestObserved: 4, - Entropy: 1, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).To(MatchError(ErrEntropy)) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(6))) - }) - - It("completely processes an ACK without a NACK range", func() { - entropy := EntropyAccumulator(0) - largestObserved := 4 - for i := 0; i < largestObserved; i++ { - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - Entropy: byte(entropy), - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(2))) - Expect(handler.LargestObserved).To(Equal(protocol.PacketNumber(largestObserved))) - Expect(handler.LargestObservedEntropy).To(Equal(entropy)) - Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(largestObserved))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(largestObserved - 1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(largestObserved + 1))) - }) - - It("completely processes an ACK with a NACK range", func() { - var entropy EntropyAccumulator - var largestObservedEntropy EntropyAccumulator - largestObserved := 6 - for i := 0; i < largestObserved; i++ { - largestObservedEntropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - if i == 2 || i == 4 { // Packet Number 3 and 5 missing - continue - } - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - Entropy: byte(entropy), - NackRanges: []frames.NackRange{ - {FirstPacketNumber: 5, LastPacketNumber: 5}, - {FirstPacketNumber: 3, LastPacketNumber: 3}, - }, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(2))) - Expect(handler.LargestObserved).To(Equal(protocol.PacketNumber(largestObserved))) - Expect(handler.LargestObservedEntropy).To(Equal(largestObservedEntropy)) - Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(2))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(4))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(5))) - Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(6))) - }) - - It("processes an ACK frame that would be sent after a late arrival of a packet", func() { - entropy := EntropyAccumulator(0) - largestObserved := 6 - for i := 0; i < largestObserved; i++ { - if i == 2 || i == 3 { // Packet Number 3 and 4 - continue - } - entropy.Add(packets[i].PacketNumber, packets[i].EntropyBit) - } - ack1 := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - Entropy: byte(entropy), - NackRanges: []frames.NackRange{ - {FirstPacketNumber: 3, LastPacketNumber: 4}, - }, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack1}, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(2))) - entropy.Add(packets[2].PacketNumber, packets[2].EntropyBit) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3))) - ack2 := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - Entropy: byte(entropy), - NackRanges: []frames.NackRange{ - {FirstPacketNumber: 4, LastPacketNumber: 4}, - }, - } - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack2}, 2) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(4))) - }) - }) - - Context("ACK processing", func() { // in all these tests, the EntropyBit of each Packet is set to false, so that the resulting EntropyByte will always be 0 - var packets []*Packet - - BeforeEach(func() { - packets = []*Packet{ - {PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 3, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 4, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 5, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 6, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - } - for _, packet := range packets { - handler.SentPacket(packet) - } - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(6))) - }) - - Context("ACK validation", func() { - It("rejects duplicate ACKs", func() { - largestObserved := 3 - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).To(MatchError(ErrDuplicateOrOutOfOrderAck)) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - }) - - It("rejects out of order ACKs", func() { - largestObserved := 3 - ack := frames.AckFrameLegacy{ - LargestObserved: protocol.PacketNumber(largestObserved), - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 2) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).To(MatchError(ErrDuplicateOrOutOfOrderAck)) - Expect(handler.LargestObserved).To(Equal(protocol.PacketNumber(largestObserved))) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - }) - - It("ignores repeated ACKs", func() { - ack := frames.AckFrameLegacy{ - LargestObserved: 3, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1337) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1337+1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.LargestObserved).To(Equal(protocol.PacketNumber(3))) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - }) - - It("rejects ACKs with a too high LargestObserved packet number", func() { - ack := frames.AckFrameLegacy{ - LargestObserved: packets[len(packets)-1].PacketNumber + 1337, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).To(MatchError(errAckForUnsentPacket)) - Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(0))) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(6))) - }) - - It("correctly treats a belated ACK for a packet that has already been RTO retransmitted", func() { - // lose packet by NACKing it often enough - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - packet := handler.DequeuePacketForRetransmission() - Expect(packet).ToNot(BeNil()) - // this is the belated ACK - ack := frames.AckFrameLegacy{LargestObserved: 3} - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(handler.LargestObserved).To(Equal(protocol.PacketNumber(3))) - Expect(err).ToNot(HaveOccurred()) - }) - }) - - Context("calculating RTT", func() { - It("calculates the RTT", func() { - now := time.Now() - // First, fake the sent times of the first, second and last packet - handler.packetHistory[1].SendTime = now.Add(-10 * time.Minute) - handler.packetHistory[2].SendTime = now.Add(-5 * time.Minute) - handler.packetHistory[6].SendTime = now.Add(-1 * time.Minute) - // Now, check that the proper times are used when calculating the deltas - ack := frames.AckFrameLegacy{LargestObserved: 1} - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 10*time.Minute, 1*time.Second)) - ack = frames.AckFrameLegacy{LargestObserved: 2} - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 2) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second)) - ack = frames.AckFrameLegacy{LargestObserved: 6} - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 3) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 1*time.Minute, 1*time.Second)) - }) - - It("uses the DelayTime in the ack frame", func() { - now := time.Now() - handler.packetHistory[1].SendTime = now.Add(-10 * time.Minute) - ack := frames.AckFrameLegacy{ - LargestObserved: 1, - DelayTime: 5 * time.Minute, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second)) - }) - }) - }) - - Context("Retransmission handler", func() { - var packets []*Packet - - BeforeEach(func() { - packets = []*Packet{ - {PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 3, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 4, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 5, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - {PacketNumber: 6, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1}, - } - for _, packet := range packets { - handler.SentPacket(packet) - } - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(6))) - }) - - It("does not dequeue a packet if no packet has been nacked", func() { - for i := uint8(0); i < protocol.RetransmissionThreshold; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - handler.MaybeQueueRTOs() - Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) - }) - - It("queues a packet for retransmission", func() { - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - handler.MaybeQueueRTOs() - Expect(handler.retransmissionQueue).To(HaveLen(1)) - Expect(handler.retransmissionQueue[0].PacketNumber).To(Equal(protocol.PacketNumber(2))) - }) - - It("dequeues a packet for retransmission", func() { - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(3) - Expect(err).ToNot(HaveOccurred()) - } - packet := handler.DequeuePacketForRetransmission() - Expect(packet).ToNot(BeNil()) - Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(3))) - Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) - }) - - It("keeps the packets in the right order", func() { - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(4) - Expect(err).ToNot(HaveOccurred()) - } - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - packet := handler.DequeuePacketForRetransmission() - Expect(packet).ToNot(BeNil()) - Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(2))) - packet = handler.DequeuePacketForRetransmission() - Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(4))) - }) - - It("only queues each packet once, regardless of the number of NACKs", func() { - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(4) - Expect(err).ToNot(HaveOccurred()) - } - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(4) - Expect(err).ToNot(HaveOccurred()) - } - packet := handler.DequeuePacketForRetransmission() - Expect(packet).ToNot(BeNil()) - packet = handler.DequeuePacketForRetransmission() - Expect(packet).ToNot(BeNil()) - Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) - }) - - It("does not change the highestInOrderAckedPacketNumber after queueing a retransmission", func() { - ack := frames.AckFrameLegacy{ - LargestObserved: 4, - NackRanges: []frames.NackRange{{FirstPacketNumber: 3, LastPacketNumber: 3}}, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).ToNot(HaveOccurred()) - Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(2))) - handler.nackPacket(3) // this is the second NACK for this packet - Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(2))) - }) - - It("does not retransmit a packet if a belated ACK was received", func() { - // lose packet by NACKing it often enough - for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ { - _, err := handler.nackPacket(2) - Expect(err).ToNot(HaveOccurred()) - } - // this is the belated ACK - handler.ackPacket(2) - handler.MaybeQueueRTOs() - Expect(handler.DequeuePacketForRetransmission()).To(BeNil()) - }) - }) - - Context("calculating bytes in flight", func() { - It("works in a typical retransmission scenarios", func() { - packet1 := Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 1} - packet2 := Packet{PacketNumber: 2, Frames: []frames.Frame{&streamFrame}, EntropyBit: false, Length: 2} - err := handler.SentPacket(&packet1) - Expect(err).NotTo(HaveOccurred()) - err = handler.SentPacket(&packet2) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3))) - - // ACK 2, NACK 1 - ack := frames.AckFrameLegacy{ - LargestObserved: 2, - NackRanges: []frames.NackRange{{FirstPacketNumber: 1, LastPacketNumber: 1}}, - } - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - - // Simulate protocol.RetransmissionThreshold more NACKs - for i := uint8(0); i < protocol.RetransmissionThreshold; i++ { - _, err = handler.nackPacket(1) - Expect(err).ToNot(HaveOccurred()) - } - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(0))) - - // Retransmission - packet3 := Packet{PacketNumber: 3, EntropyBit: false, Length: 1} - err = handler.SentPacket(&packet3) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1))) - - // ACK - ack = frames.AckFrameLegacy{ - LargestObserved: 3, - } - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 2) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(0))) - }) - }) - - Context("congestion", func() { - var ( - cong *mockCongestion - ) - - BeforeEach(func() { - cong = &mockCongestion{} - handler.congestion = cong - }) - - It("should call OnSent", func() { - p := &Packet{ - PacketNumber: 1, - Frames: []frames.Frame{&frames.StreamFrame{StreamID: 5}}, - Length: 42, - } - err := handler.SentPacket(p) - Expect(err).NotTo(HaveOccurred()) - Expect(cong.nCalls).To(Equal(1)) - Expect(cong.argsOnPacketSent[1]).To(Equal(protocol.ByteCount(42))) - Expect(cong.argsOnPacketSent[2]).To(Equal(protocol.PacketNumber(1))) - Expect(cong.argsOnPacketSent[3]).To(Equal(protocol.ByteCount(42))) - Expect(cong.argsOnPacketSent[4]).To(BeTrue()) - }) - - It("should call OnCongestionEvent", func() { - handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1}) - handler.SentPacket(&Packet{PacketNumber: 2, Frames: []frames.Frame{}, Length: 2}) - handler.SentPacket(&Packet{PacketNumber: 3, Frames: []frames.Frame{}, Length: 3}) - ack := frames.AckFrameLegacy{ - LargestObserved: 3, - NackRanges: []frames.NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2}}, - } - err := handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, 1) - Expect(err).NotTo(HaveOccurred()) - Expect(cong.nCalls).To(Equal(4)) // 3 * SentPacket + 1 * ReceivedAck - // rttUpdated, bytesInFlight, ackedPackets, lostPackets - Expect(cong.argsOnCongestionEvent[0]).To(BeTrue()) - Expect(cong.argsOnCongestionEvent[1]).To(Equal(protocol.ByteCount(2))) - Expect(cong.argsOnCongestionEvent[2]).To(Equal(congestion.PacketVector{{Number: 1, Length: 1}, {Number: 3, Length: 3}})) - Expect(cong.argsOnCongestionEvent[3]).To(BeEmpty()) - - // Loose the packet - var packetNumber protocol.PacketNumber - for i := uint8(0); i < protocol.RetransmissionThreshold; i++ { - packetNumber = protocol.PacketNumber(4 + i) - handler.SentPacket(&Packet{PacketNumber: packetNumber, Frames: []frames.Frame{}, Length: protocol.ByteCount(packetNumber)}) - ack := frames.AckFrameLegacy{ - LargestObserved: packetNumber, - NackRanges: []frames.NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2}}, - } - err = handler.ReceivedAck(&frames.AckFrame{AckFrameLegacy: &ack}, protocol.PacketNumber(2+i)) - Expect(err).NotTo(HaveOccurred()) - } - - Expect(cong.argsOnCongestionEvent[2]).To(Equal(congestion.PacketVector{{Number: packetNumber, Length: protocol.ByteCount(packetNumber)}})) - Expect(cong.argsOnCongestionEvent[3]).To(Equal(congestion.PacketVector{{Number: 2, Length: 2}})) - }) - - It("allows or denies sending", func() { - Expect(handler.CongestionAllowsSending()).To(BeTrue()) - err := handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: protocol.DefaultTCPMSS + 1}) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.CongestionAllowsSending()).To(BeFalse()) - }) - - It("should call OnRetransmissionTimeout", func() { - err := handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1}) - Expect(err).NotTo(HaveOccurred()) - handler.lastSentPacketTime = time.Now().Add(-time.Second) - handler.MaybeQueueRTOs() - Expect(cong.nCalls).To(Equal(3)) - // rttUpdated, bytesInFlight, ackedPackets, lostPackets - Expect(cong.argsOnCongestionEvent[0]).To(BeFalse()) - Expect(cong.argsOnCongestionEvent[1]).To(Equal(protocol.ByteCount(1))) - Expect(cong.argsOnCongestionEvent[2]).To(BeEmpty()) - Expect(cong.argsOnCongestionEvent[3]).To(Equal(congestion.PacketVector{{Number: 1, Length: 1}})) - - Expect(cong.onRetransmissionTimeout).To(BeTrue()) - }) - }) - - Context("calculating RTO", func() { - It("uses default RTO", func() { - Expect(handler.getRTO()).To(Equal(protocol.DefaultRetransmissionTime)) - }) - - It("uses RTO from rttStats", func() { - rtt := time.Second - expected := rtt + rtt/2*4 - handler.rttStats.UpdateRTT(rtt, 0, time.Now()) - Expect(handler.getRTO()).To(Equal(expected)) - }) - - It("limits RTO min", func() { - rtt := time.Millisecond - handler.rttStats.UpdateRTT(rtt, 0, time.Now()) - Expect(handler.getRTO()).To(Equal(protocol.MinRetransmissionTime)) - }) - }) - - Context("RTO retransmission", func() { - Context("calculating the time to first RTO", func() { - It("defaults to zero", func() { - Expect(handler.TimeOfFirstRTO().IsZero()).To(BeTrue()) - }) - - It("returns time to RTO", func() { - err := handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1}) - Expect(err).NotTo(HaveOccurred()) - Expect(handler.TimeOfFirstRTO().Sub(time.Now())).To(BeNumerically("~", protocol.DefaultRetransmissionTime, time.Millisecond)) - }) - - It("ignores nil packets", func() { - handler.packetHistory[1] = nil - handler.MaybeQueueRTOs() - Expect(handler.TimeOfFirstRTO().IsZero()).To(BeTrue()) - }) - }) - - Context("queuing packets due to RTO", func() { - It("does nothing if not required", func() { - err := handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1}) - Expect(err).NotTo(HaveOccurred()) - handler.MaybeQueueRTOs() - Expect(handler.retransmissionQueue).To(BeEmpty()) - }) - - It("queues a packet if RTO expired", func() { - p := &Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1} - err := handler.SentPacket(p) - Expect(err).NotTo(HaveOccurred()) - handler.lastSentPacketTime = time.Now().Add(-time.Second) - handler.MaybeQueueRTOs() - Expect(handler.retransmissionQueue).To(HaveLen(1)) - Expect(handler.retransmissionQueue[0]).To(Equal(p)) - Expect(time.Now().Sub(handler.lastSentPacketTime)).To(BeNumerically("<", time.Second/2)) - }) - - It("does not queue retransmittedpackets", func() { - p := &Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1, Retransmitted: true} - err := handler.SentPacket(p) - Expect(err).NotTo(HaveOccurred()) - handler.lastSentPacketTime = time.Now().Add(-time.Second) - handler.MaybeQueueRTOs() - Expect(handler.retransmissionQueue).To(BeEmpty()) - }) - - It("ignores nil packets", func() { - handler.packetHistory[1] = nil - handler.MaybeQueueRTOs() - Expect(handler.retransmissionQueue).To(BeEmpty()) - }) - }) - - It("works with DequeuePacketForRetransmission", func() { - p := &Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1} - err := handler.SentPacket(p) - Expect(err).NotTo(HaveOccurred()) - handler.lastSentPacketTime = time.Now().Add(-time.Second) - handler.MaybeQueueRTOs() - Expect(handler.DequeuePacketForRetransmission()).To(Equal(p)) - }) - }) -}) diff --git a/ackhandlerlegacy/stop_waiting_manager.go b/ackhandlerlegacy/stop_waiting_manager.go deleted file mode 100644 index 4621b613..00000000 --- a/ackhandlerlegacy/stop_waiting_manager.go +++ /dev/null @@ -1,58 +0,0 @@ -package ackhandlerlegacy - -import ( - "github.com/lucas-clemente/quic-go/frames" - "github.com/lucas-clemente/quic-go/protocol" -) - -// StopWaitingManager manages StopWaitingFrames -type stopWaitingManager struct { - // sentStopWaitings map[protocol.PacketNumber]protocol.PacketNumber // map[LeastUnacked]stopWaitingSentWithPacketNumber - lastNewStopWaitingFirstSentWithPacketNumber protocol.PacketNumber - maxRetransmittedPacketNumber protocol.PacketNumber - currentStopWaitingFrame *frames.StopWaitingFrame - currentStopWaitingFrameSent bool -} - -// NewStopWaitingManager creates a new StopWaitingManager -func NewStopWaitingManager() StopWaitingManager { - return &stopWaitingManager{ - currentStopWaitingFrame: nil, - } -} - -// RegisterPacketForRetransmission prepares the StopWaitingFrame, if necessary -func (h *stopWaitingManager) RegisterPacketForRetransmission(packet *Packet) { - // out-of-order retransmission. A StopWaitingFrame with a higher LeastUnacked was already queued (or sent in the past), no need to send another one again - if packet.PacketNumber < h.maxRetransmittedPacketNumber { - return - } - if h.currentStopWaitingFrame == nil || h.currentStopWaitingFrame.LeastUnacked <= packet.PacketNumber { // <= because for StopWaitingFrames LeastUnacked = packet.PacketNumber + 1 - h.currentStopWaitingFrame = &frames.StopWaitingFrame{ - LeastUnacked: packet.PacketNumber + 1, - Entropy: byte(packet.Entropy), - } - h.maxRetransmittedPacketNumber = packet.PacketNumber - h.currentStopWaitingFrameSent = false - } -} - -// GetStopWaitingFrame gets the StopWaitingFrame that needs to be sent. It returns nil if no StopWaitingFrame needs to be sent -func (h *stopWaitingManager) GetStopWaitingFrame() *frames.StopWaitingFrame { - return h.currentStopWaitingFrame -} - -// SentStopWaitingWithPacket must be called after sending out a StopWaitingFrame with a packet -func (h *stopWaitingManager) SentStopWaitingWithPacket(packetNumber protocol.PacketNumber) { - if !h.currentStopWaitingFrameSent { - h.lastNewStopWaitingFirstSentWithPacketNumber = packetNumber - } - h.currentStopWaitingFrameSent = true -} - -// ReceivedAckForPacketNumber should be called after receiving an ACK -func (h *stopWaitingManager) ReceivedAckForPacketNumber(packetNumber protocol.PacketNumber) { - if packetNumber >= h.lastNewStopWaitingFirstSentWithPacketNumber { - h.currentStopWaitingFrame = nil - } -} diff --git a/ackhandlerlegacy/stop_waiting_manager_test.go b/ackhandlerlegacy/stop_waiting_manager_test.go deleted file mode 100644 index 47b80bb1..00000000 --- a/ackhandlerlegacy/stop_waiting_manager_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package ackhandlerlegacy - -import ( - "github.com/lucas-clemente/quic-go/protocol" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("StopWaitingManager", func() { - var manager *stopWaitingManager - BeforeEach(func() { - manager = NewStopWaitingManager().(*stopWaitingManager) - }) - - It("returns nil in the beginning", func() { - Expect(manager.GetStopWaitingFrame()).To(BeNil()) - }) - - It("gets a StopWaitingFrame after a packet has been registered for retransmission", func() { - leastUnacked := protocol.PacketNumber(10) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked, Entropy: 10}) - swf := manager.GetStopWaitingFrame() - Expect(swf).ToNot(BeNil()) - Expect(swf.LeastUnacked).To(Equal(leastUnacked + 1)) - Expect(swf.Entropy).To(Equal(byte(10))) - }) - - It("always gets the StopWaitingFrame for the highest retransmitted packet number", func() { - leastUnacked := protocol.PacketNumber(10) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked, Entropy: 10}) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked - 1, Entropy: 8}) - swf := manager.GetStopWaitingFrame() - Expect(swf).ToNot(BeNil()) - Expect(swf.LeastUnacked).To(Equal(leastUnacked + 1)) - Expect(swf.Entropy).To(Equal(byte(10))) - }) - - It("updates the StopWaitingFrame when a packet with a higher packet number is retransmitted", func() { - leastUnacked := protocol.PacketNumber(10) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked - 1, Entropy: 10}) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked, Entropy: 8}) - swf := manager.GetStopWaitingFrame() - Expect(swf).ToNot(BeNil()) - Expect(swf.LeastUnacked).To(Equal(leastUnacked + 1)) - Expect(swf.Entropy).To(Equal(byte(8))) - }) - - It("does not create a new StopWaitingFrame for an out-of-order retransmission", func() { - leastUnacked := protocol.PacketNumber(10) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked, Entropy: 8}) - manager.SentStopWaitingWithPacket(12) - manager.ReceivedAckForPacketNumber(12) - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: leastUnacked - 1, Entropy: 10}) - swf := manager.GetStopWaitingFrame() - Expect(swf).To(BeNil()) - }) - - Context("ACK handling", func() { - It("removes the current StopWaitingFrame when the first packet it was sent with is ACKed", func() { - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: 10}) - manager.SentStopWaitingWithPacket(13) - manager.SentStopWaitingWithPacket(14) - manager.SentStopWaitingWithPacket(15) - Expect(manager.GetStopWaitingFrame()).ToNot(BeNil()) - manager.ReceivedAckForPacketNumber(13) - Expect(manager.GetStopWaitingFrame()).To(BeNil()) - }) - - It("removes the current StopWaitingFrame when any packet it was sent with is ACKed", func() { - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: 10}) - manager.SentStopWaitingWithPacket(13) - manager.SentStopWaitingWithPacket(14) - manager.SentStopWaitingWithPacket(15) - Expect(manager.GetStopWaitingFrame()).ToNot(BeNil()) - manager.ReceivedAckForPacketNumber(14) - Expect(manager.GetStopWaitingFrame()).To(BeNil()) - }) - - It("does not remove the current StopWaitingFrame when a packet before the one containing the StopWaitingFrame is ACKed", func() { - manager.RegisterPacketForRetransmission(&Packet{PacketNumber: 10}) - manager.SentStopWaitingWithPacket(13) - Expect(manager.GetStopWaitingFrame()).ToNot(BeNil()) - manager.ReceivedAckForPacketNumber(12) - Expect(manager.GetStopWaitingFrame()).ToNot(BeNil()) - }) - }) -}) diff --git a/frames/ack_frame.go b/frames/ack_frame.go index f96e38c6..2690770f 100644 --- a/frames/ack_frame.go +++ b/frames/ack_frame.go @@ -23,8 +23,6 @@ var ( // An AckFrame is an ACK frame in QUIC type AckFrame struct { - AckFrameLegacy *AckFrameLegacy - LargestAcked protocol.PacketNumber LowestAcked protocol.PacketNumber AckRanges []AckRange // has to be ordered. The ACK range with the highest FirstPacketNumber goes first, the ACK range with the lowest FirstPacketNumber goes last @@ -37,15 +35,6 @@ type AckFrame struct { func ParseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame, error) { frame := &AckFrame{} - if version != protocol.VersionWhatever && version <= protocol.Version33 { - var err error - frame.AckFrameLegacy, err = ParseAckFrameLegacy(r, version) - if err != nil { - return nil, err - } - return frame, nil - } - typeByte, err := r.ReadByte() if err != nil { return nil, err @@ -197,10 +186,6 @@ func ParseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame, // Write writes an ACK frame. func (f *AckFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { - if f.AckFrameLegacy != nil { - return f.AckFrameLegacy.Write(b, version) - } - largestAckedLen := protocol.GetPacketNumberLength(f.LargestAcked) typeByte := uint8(0x40) @@ -341,10 +326,6 @@ func (f *AckFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error // MinLength of a written frame func (f *AckFrame) MinLength(version protocol.VersionNumber) (protocol.ByteCount, error) { - if f.AckFrameLegacy != nil { - return f.AckFrameLegacy.MinLength(version) - } - var length protocol.ByteCount length = 1 + 2 + 1 // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestAcked)) @@ -364,10 +345,6 @@ func (f *AckFrame) MinLength(version protocol.VersionNumber) (protocol.ByteCount // HasMissingRanges returns if this frame reports any missing packets func (f *AckFrame) HasMissingRanges() bool { - if f.AckFrameLegacy != nil { - panic("HasMissingRanges() should not be called on an AckFrameLegacy") - } - if len(f.AckRanges) > 0 { return true } diff --git a/frames/ack_frame_legacy.go b/frames/ack_frame_legacy.go deleted file mode 100644 index 74567578..00000000 --- a/frames/ack_frame_legacy.go +++ /dev/null @@ -1,304 +0,0 @@ -package frames - -import ( - "bytes" - "errors" - "time" - - "github.com/lucas-clemente/quic-go/protocol" - "github.com/lucas-clemente/quic-go/utils" -) - -var ( - errInvalidNackRanges = errors.New("AckFrame: ACK frame contains invalid NACK ranges") - errTooManyNackRanges = errors.New("AckFrame: Too many NACK ranges. Truncating not implemented.") -) - -// An AckFrameLegacy is an ACK Frame in legacy format (ACK frame for QUIC <= 33) -type AckFrameLegacy struct { - LargestObserved protocol.PacketNumber - Entropy byte - NackRanges []NackRange // has to be ordered. The NACK range with the highest FirstPacketNumber goes first, the NACK range with the lowest FirstPacketNumber goes last - Truncated bool - - DelayTime time.Duration - PacketReceivedTime time.Time // only for received packets. Will not be modified for received ACKs frames -} - -// Write writes an ACK frame. -func (f *AckFrameLegacy) Write(b *bytes.Buffer, version protocol.VersionNumber) error { - largestObservedLen := protocol.GetPacketNumberLength(f.LargestObserved) - - typeByte := uint8(0x40) - - if largestObservedLen != protocol.PacketNumberLen1 { - typeByte ^= (uint8(largestObservedLen / 2)) << 2 - } - - if f.HasNACK() { - typeByte |= (0x20 | 0x03) - } - - f.DelayTime = time.Now().Sub(f.PacketReceivedTime) - - b.WriteByte(typeByte) - b.WriteByte(f.Entropy) - - switch largestObservedLen { - case protocol.PacketNumberLen1: - b.WriteByte(uint8(f.LargestObserved)) - case protocol.PacketNumberLen2: - utils.WriteUint16(b, uint16(f.LargestObserved)) - case protocol.PacketNumberLen4: - utils.WriteUint32(b, uint32(f.LargestObserved)) - case protocol.PacketNumberLen6: - utils.WriteUint48(b, uint64(f.LargestObserved)) - } - - utils.WriteUfloat16(b, uint64(f.DelayTime/time.Microsecond)) - b.WriteByte(0x01) // Just one timestamp - b.WriteByte(0x00) // Delta Largest observed - utils.WriteUint32(b, 0) // First timestamp - - if f.HasNACK() { - numRanges := f.numWrittenNackRanges() - if numRanges > 0xFF { - return errTooManyNackRanges - } - b.WriteByte(uint8(numRanges)) - - rangeCounter := uint8(0) - for i, nackRange := range f.NackRanges { - var missingPacketSequenceNumberDelta uint64 - if i == 0 { - if nackRange.LastPacketNumber > f.LargestObserved { - return errors.New("AckFrame: Invalid NACK ranges") - } - missingPacketSequenceNumberDelta = uint64(f.LargestObserved) - uint64(nackRange.LastPacketNumber) - } else { - lastNackRange := f.NackRanges[i-1] - missingPacketSequenceNumberDelta = uint64(lastNackRange.FirstPacketNumber) - uint64(nackRange.LastPacketNumber) - 1 - } - rangeLength := nackRange.Len() - - utils.WriteUint48(b, missingPacketSequenceNumberDelta) - b.WriteByte(uint8(rangeLength % 0x100)) - rangeCounter++ - - rangeLength = rangeLength - (rangeLength % 0x100) - for rangeLength > 0 { - rangeCounter++ - utils.WriteUint48(b, 0) - b.WriteByte(uint8(0xFF)) - rangeLength -= 0x100 - } - } - - if rangeCounter != uint8(numRanges) { - return errors.New("BUG: Inconsistent number of NACK ranges written") - } - } - - return nil -} - -// MinLength of a written frame -func (f *AckFrameLegacy) MinLength(version protocol.VersionNumber) (protocol.ByteCount, error) { - l := 1 + 1 + 2 + 1 + 1 + 4 // 1 TypeByte, 1 Entropy, 2 ACK delay time, 1 Num Timestamp, 1 Delta Largest Observed, 4 FirstTimestamp - l += int(protocol.GetPacketNumberLength(f.LargestObserved)) - l += (1 + 2) * 0 /* TODO: num_timestamps */ - if f.HasNACK() { - l += 1 + (6+1)*int(f.numWrittenNackRanges()) - } - return protocol.ByteCount(l), nil -} - -// HasNACK returns if the frame has NACK ranges -func (f *AckFrameLegacy) HasNACK() bool { - if len(f.NackRanges) > 0 { - return true - } - return false -} - -// GetHighestInOrderPacketNumber gets the highest in order packet number that is confirmed by this ACK -func (f *AckFrameLegacy) GetHighestInOrderPacketNumber() protocol.PacketNumber { - if f.HasNACK() { - return (f.NackRanges[len(f.NackRanges)-1].FirstPacketNumber - 1) - } - return f.LargestObserved -} - -// ParseAckFrameLegacy reads a legacy ACK frame -func ParseAckFrameLegacy(r *bytes.Reader, version protocol.VersionNumber) (*AckFrameLegacy, error) { - frame := &AckFrameLegacy{} - - typeByte, err := r.ReadByte() - if err != nil { - return nil, err - } - - hasNACK := false - if typeByte&0x20 == 0x20 { - hasNACK = true - } - frame.Truncated = typeByte&0x10 > 0 - - largestObservedLen := 2 * ((typeByte & 0x0C) >> 2) - if largestObservedLen == 0 { - largestObservedLen = 1 - } - - missingSequenceNumberDeltaLen := 2 * (typeByte & 0x03) - if missingSequenceNumberDeltaLen == 0 { - missingSequenceNumberDeltaLen = 1 - } - - frame.Entropy, err = r.ReadByte() - if err != nil { - return nil, err - } - - largestObserved, err := utils.ReadUintN(r, largestObservedLen) - if err != nil { - return nil, err - } - frame.LargestObserved = protocol.PacketNumber(largestObserved) - - delay, err := utils.ReadUfloat16(r) - if err != nil { - return nil, err - } - frame.DelayTime = time.Duration(delay) * time.Microsecond - - if !frame.Truncated { - var numTimestampByte byte - numTimestampByte, err = r.ReadByte() - if err != nil { - return nil, err - } - numTimestamp := uint8(numTimestampByte) - - // Delta Largest observed - _, err = r.ReadByte() - if err != nil { - return nil, err - } - // First Timestamp - _, err = utils.ReadUint32(r) - if err != nil { - return nil, err - } - - for i := 0; i < int(numTimestamp)-1; i++ { - // Delta Largest observed - _, err = r.ReadByte() - if err != nil { - return nil, err - } - // Time Since Previous Timestamp - _, err = utils.ReadUint16(r) - if err != nil { - return nil, err - } - } - } - - // Invalid NACK Handling: - // NACKs contain a lot of offsets that require subtractions of PacketNumbers. If an ACK contains invalid data, it is possible to underflow the uint64 used to store the PacketNumber - // TODO: handle uint64 overflows - if hasNACK { - var numRanges uint8 - numRanges, err = r.ReadByte() - if err != nil { - return nil, err - } - - for i := uint8(0); i < numRanges; i++ { - missingPacketSequenceNumberDelta, err := utils.ReadUintN(r, missingSequenceNumberDeltaLen) - if err != nil { - return nil, err - } - - rangeLengthByte, err := r.ReadByte() - if err != nil { - return nil, err - } - rangeLength := uint8(rangeLengthByte) - - // contiguous NACK range - if i > 0 && missingPacketSequenceNumberDelta == 0 { - nackRange := &frame.NackRanges[len(frame.NackRanges)-1] - if uint64(nackRange.FirstPacketNumber) <= uint64(rangeLength)+1 { - return nil, errInvalidNackRanges - } - nackRange.FirstPacketNumber = protocol.PacketNumber(uint64(nackRange.FirstPacketNumber) - uint64(rangeLength) - 1) - } else { - nackRange := NackRange{} - if i == 0 { - if uint64(frame.LargestObserved) < missingPacketSequenceNumberDelta+uint64(rangeLength) { - return nil, errInvalidNackRanges - } - nackRange.FirstPacketNumber = frame.LargestObserved - protocol.PacketNumber(missingPacketSequenceNumberDelta+uint64(rangeLength)) - } else { - lastNackRange := frame.NackRanges[len(frame.NackRanges)-1] - if uint64(lastNackRange.FirstPacketNumber) <= missingPacketSequenceNumberDelta+uint64(rangeLength) { - return nil, errInvalidNackRanges - } - nackRange.FirstPacketNumber = lastNackRange.FirstPacketNumber - protocol.PacketNumber(missingPacketSequenceNumberDelta+uint64(rangeLength)) - 1 - } - nackRange.LastPacketNumber = protocol.PacketNumber(uint64(nackRange.FirstPacketNumber) + uint64(rangeLength)) - frame.NackRanges = append(frame.NackRanges, nackRange) - } - } - } - - if !frame.validateNackRanges() { - return nil, errInvalidNackRanges - } - - return frame, nil -} - -// numWrittenNackRanges calculates the number of NackRanges that are about to be written -// this number is different from len(f.NackRanges) for the case of contiguous NACK ranges -func (f *AckFrameLegacy) numWrittenNackRanges() uint64 { - var numRanges uint64 - for _, nackRange := range f.NackRanges { - rangeLength := nackRange.Len() - numRanges += rangeLength/0xFF + 1 - if rangeLength > 0 && rangeLength%0xFF == 0 { - numRanges-- - } - } - - return numRanges -} - -func (f *AckFrameLegacy) validateNackRanges() bool { - // check the validity of every single NACK range - for _, nackRange := range f.NackRanges { - if nackRange.FirstPacketNumber > nackRange.LastPacketNumber { - return false - } - if nackRange.LastPacketNumber > f.LargestObserved { - return false - } - } - - // check the consistency for ACK with multiple NACK ranges - for i, nackRange := range f.NackRanges { - if i == 0 { - continue - } - lastNackRange := f.NackRanges[i-1] - if lastNackRange.FirstPacketNumber <= nackRange.FirstPacketNumber { - return false - } - if lastNackRange.FirstPacketNumber <= nackRange.LastPacketNumber { - return false - } - } - - return true -} diff --git a/frames/ack_frame_legacy_test.go b/frames/ack_frame_legacy_test.go deleted file mode 100644 index e148abf0..00000000 --- a/frames/ack_frame_legacy_test.go +++ /dev/null @@ -1,559 +0,0 @@ -package frames - -import ( - "bytes" - "time" - - "github.com/lucas-clemente/quic-go/protocol" - "github.com/lucas-clemente/quic-go/utils" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("AckFrame", func() { - Context("when parsing", func() { - It("accepts sample frame", func() { - b := bytes.NewReader([]byte{0x40, 0xA4, 0x03, 0x23, 0x45, 0x01, 0x02, 0xFF, 0xEE, 0xDD, 0xCC}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.Entropy).To(Equal(byte(0xA4))) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(0x03))) - Expect(frame.DelayTime).To(Equal(430464 * time.Microsecond)) - Expect(frame.HasNACK()).To(Equal(false)) - Expect(b.Len()).To(Equal(0)) - }) - - It("parses a frame with a 48 bit packet number", func() { - b := bytes.NewReader([]byte{0x4C, 0xA4, 0x37, 0x13, 0xAD, 0xFB, 0xCA, 0xDE, 0x23, 0x45, 0x01, 0x02, 0xFF, 0xEE, 0xDD, 0xCC}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(0xDECAFBAD1337))) - Expect(b.Len()).To(Equal(0)) - }) - - It("completely parses a frame with multiple timestamps", func() { - b := bytes.NewReader([]byte{0x40, 0xA4, 0x03, 0x23, 0x45, 0x03, 0x02, 0xFF, 0xEE, 0xDD, 0xCC, 0x12, 0x34, 0x56, 0x78, 0x90, 0xA0}) - _, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(b.Len()).To(Equal(0)) - }) - - It("parses a frame containing one NACK range", func() { - b := bytes.NewReader([]byte{0x60, 0x8, 0x3, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x1, 0x1, 0x1}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.HasNACK()).To(Equal(true)) - Expect(frame.NackRanges).To(HaveLen(1)) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(3))) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 1, LastPacketNumber: 2})) - Expect(b.Len()).To(Equal(0)) - }) - - It("parses a frame containing one NACK range with a 48 bit LargestObserved and missingPacketSequenceNumberDelta", func() { - var rangeLength uint64 = 3 - b := bytes.NewReader([]byte{(0x4C | 0x20 | 0x03), 0x08, 0x37, 0x13, 0xAD, 0xFB, 0xCA, 0xDE, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x1, 0xFE, 0xCA, 0xEF, 0xBE, 0xAD, 0xDE, byte(rangeLength)}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(0xDECAFBAD1337))) - Expect(frame.HasNACK()).To(Equal(true)) - Expect(frame.NackRanges).To(HaveLen(1)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: protocol.PacketNumber(0xDECAFBAD1337 - 0xDEADBEEFCAFE - rangeLength), LastPacketNumber: 0xDECAFBAD1337 - 0xDEADBEEFCAFE})) - Expect(b.Len()).To(Equal(0)) - }) - - It("parses a frame containing multiple NACK ranges", func() { - // sent packets 1, 3, 7, 15 - b := bytes.NewReader([]byte{0x60, 0x2, 0xf, 0xb8, 0x1, 0x1, 0x0, 0xe5, 0x58, 0x4, 0x0, 0x3, 0x1, 0x6, 0x1, 0x2, 0x1, 0x0}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.HasNACK()).To(Equal(true)) - Expect(frame.NackRanges).To(HaveLen(3)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 8, LastPacketNumber: 14})) - Expect(frame.NackRanges[1]).To(Equal(NackRange{FirstPacketNumber: 4, LastPacketNumber: 6})) - Expect(frame.NackRanges[2]).To(Equal(NackRange{FirstPacketNumber: 2, LastPacketNumber: 2})) - Expect(b.Len()).To(Equal(0)) - }) - - It("rejects a packet with an invalid NACK range", func() { - // LargestObserved: 8, NackRange: (8-7-3) to (8-7) - b := bytes.NewReader([]byte{0x60, 0x8, 0x7, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x1, 0x7, 0x3}) - _, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).To(MatchError(errInvalidNackRanges)) - }) - - It("accepts truncated acks", func() { - b := bytes.NewReader([]byte{0x50, 0xA4, 0x03, 0x23, 0x45}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.Truncated).To(BeTrue()) - Expect(b.Len()).To(BeZero()) - }) - - It("parses a frame with the largest observed missing", func() { - b := bytes.NewReader([]byte{0x60, 0x2, 0xf, 0xb8, 0x1, 0x1, 0x0, 0xe5, 0x58, 0x4, 0x0, 0x1, 0x0, 0x0}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.HasNACK()).To(Equal(true)) - Expect(frame.NackRanges).To(HaveLen(1)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 15, LastPacketNumber: 15})) - Expect(b.Len()).To(Equal(0)) - }) - - Context("contiguous NACK ranges", func() { - It("parses a frame with a contiguous NACK range spanning two fields", func() { - b := bytes.NewReader([]byte{0x64, 0x8, 0x2E, 0x01, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x2, 0x1, 0x2b, 0x0, 0xff}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(302))) - Expect(frame.NackRanges).To(HaveLen(1)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 2, LastPacketNumber: 301})) - }) - - It("parses a frame with a contiguous NACK range spanning more than two fields", func() { - b := bytes.NewReader([]byte{0x64, 0x8, 0x16, 0x05, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x6, 0x1, 0x13, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(1302))) - Expect(frame.NackRanges).To(HaveLen(1)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 2, LastPacketNumber: 1301})) - }) - - It("parses a frame with two contiguous NACK ranges", func() { - b := bytes.NewReader([]byte{0x64, 0x8, 0x23, 0x03, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x4, 0x1, 0x8f, 0x0, 0xff, 0x1, 0x8f, 0x0, 0xff}) - frame, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(protocol.PacketNumber(803))) - Expect(frame.NackRanges).To(HaveLen(2)) - Expect(frame.NackRanges[0]).To(Equal(NackRange{FirstPacketNumber: 403, LastPacketNumber: 802})) - Expect(frame.NackRanges[1]).To(Equal(NackRange{FirstPacketNumber: 2, LastPacketNumber: 401})) - }) - - It("rejects a frame with an invalid NACK range", func() { - // LargestObserved: 280, but NACK range is 301 packets long - b := bytes.NewReader([]byte{0x64, 0x8, 0x18, 0x01, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x2, 0x1, 0x2b, 0x0, 0xff}) - _, err := ParseAckFrameLegacy(b, protocol.VersionWhatever) - Expect(err).To(MatchError(errInvalidNackRanges)) - }) - }) - - It("errors on EOFs", func() { - data := []byte{0x64, 0x8, 0x23, 0x03, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x4, 0x1, 0x8f, 0x0, 0xff, 0x1, 0x8f, 0x0, 0xff} - _, err := ParseAckFrameLegacy(bytes.NewReader(data), 0) - Expect(err).NotTo(HaveOccurred()) - for i := range data { - _, err := ParseAckFrameLegacy(bytes.NewReader(data[0:i]), 0) - Expect(err).To(HaveOccurred()) - } - }) - }) - - Context("GetHighestInOrderPacket", func() { - It("gets the highest in order packet number for an ACK without NACK ranges", func() { - frame := AckFrameLegacy{LargestObserved: 5} - Expect(frame.GetHighestInOrderPacketNumber()).To(Equal(protocol.PacketNumber(5))) - }) - - It("gets the highest in order packet number for an ACK with one NACK ranges", func() { - nackRange := NackRange{FirstPacketNumber: 3, LastPacketNumber: 4} - frame := AckFrameLegacy{ - LargestObserved: 6, - NackRanges: []NackRange{nackRange}, - } - Expect(frame.GetHighestInOrderPacketNumber()).To(Equal(protocol.PacketNumber(2))) - }) - - It("gets the highest in order packet number for an ACK with one NACK ranges", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 9, LastPacketNumber: 11}, - {FirstPacketNumber: 7, LastPacketNumber: 7}, - {FirstPacketNumber: 4, LastPacketNumber: 5}, - } - frame := &AckFrameLegacy{ - LargestObserved: 15, - NackRanges: nackRanges, - } - Expect(frame.GetHighestInOrderPacketNumber()).To(Equal(protocol.PacketNumber(3))) - }) - }) - - Context("NACK range validator", func() { - It("rejects NACKs with FirstPacketNumber greater than LastPacketNumber", func() { - nackRange := NackRange{FirstPacketNumber: 7, LastPacketNumber: 6} - ack := AckFrameLegacy{ - LargestObserved: 10, - NackRanges: []NackRange{nackRange}, - } - Expect(ack.validateNackRanges()).To(BeFalse()) - }) - - It("rejects NACKs with FirstPacketNumber greater than LargestObserved", func() { - nackRange := NackRange{FirstPacketNumber: 6, LastPacketNumber: 6} - ack := AckFrameLegacy{ - LargestObserved: 5, - NackRanges: []NackRange{nackRange}, - } - Expect(ack.validateNackRanges()).To(BeFalse()) - }) - - It("does not reject NACKs with LasterPacketNumber equal to LargestObserved", func() { - nackRange := NackRange{FirstPacketNumber: 7, LastPacketNumber: 7} - ack := AckFrameLegacy{ - LargestObserved: 7, - NackRanges: []NackRange{nackRange}, - } - Expect(ack.validateNackRanges()).To(BeTrue()) - }) - - It("rejects NACKs with NackRanges in the wrong order", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 2, LastPacketNumber: 2}, - {FirstPacketNumber: 6, LastPacketNumber: 6}, - } - ack := AckFrameLegacy{ - LargestObserved: 7, - NackRanges: nackRanges, - } - Expect(ack.validateNackRanges()).To(BeFalse()) - }) - - It("rejects NACKs with overlapping NackRanges", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 5, LastPacketNumber: 6}, - {FirstPacketNumber: 2, LastPacketNumber: 5}, - } - ack := AckFrameLegacy{ - LargestObserved: 7, - NackRanges: nackRanges, - } - Expect(ack.validateNackRanges()).To(BeFalse()) - }) - - It("accepts an ACK without NACK Ranges", func() { - ack := AckFrameLegacy{LargestObserved: 7} - Expect(ack.validateNackRanges()).To(BeTrue()) - }) - - It("accepts an ACK with one NACK Ranges", func() { - nackRange := NackRange{FirstPacketNumber: 6, LastPacketNumber: 8} - ack := AckFrameLegacy{ - LargestObserved: 10, - NackRanges: []NackRange{nackRange}, - } - Expect(ack.validateNackRanges()).To(BeTrue()) - }) - - It("accepts an ACK with multiple NACK Ranges", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 6, LastPacketNumber: 7}, - {FirstPacketNumber: 2, LastPacketNumber: 4}, - } - ack := AckFrameLegacy{ - LargestObserved: 10, - NackRanges: nackRanges, - } - Expect(ack.validateNackRanges()).To(BeTrue()) - }) - }) - - Context("when writing", func() { - var b *bytes.Buffer - BeforeEach(func() { - b = &bytes.Buffer{} - }) - - It("writes simple frames without NACK ranges", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 1, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - // check all values except the DelayTime - Expect(b.Bytes()[0:3]).To(Equal([]byte{0x40, 0x02, 0x01})) - Expect(b.Bytes()[5:]).To(Equal([]byte{1, 0, 0, 0, 0, 0})) - }) - - It("calculates the DelayTime", func() { - frame := AckFrameLegacy{ - LargestObserved: 5, - PacketReceivedTime: time.Now().Add(-750 * time.Millisecond), - } - frame.Write(b, protocol.VersionWhatever) - Expect(frame.DelayTime).To(BeNumerically("~", 750*time.Millisecond, 10*time.Millisecond)) - delayTime := frame.DelayTime - var b2 bytes.Buffer - utils.WriteUfloat16(&b2, uint64(delayTime/time.Microsecond)) - Expect(b.Bytes()[3:5]).To(Equal(b2.Bytes())) - }) - - It("writes a frame with one NACK range", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 4, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2}}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-8:] - Expect(missingPacketBytes[0]).To(Equal(uint8(1))) // numRanges - Expect(missingPacketBytes[7]).To(Equal(uint8(0))) // rangeLength - packetNumber := make([]byte, 6) - copy(packetNumber, missingPacketBytes[1:6]) - Expect(packetNumber).To(BeEquivalentTo([]byte{2, 0, 0, 0, 0, 0})) - }) - - It("writes a frame with multiple NACK ranges", func() { - nackRange1 := NackRange{FirstPacketNumber: 4, LastPacketNumber: 6} - nackRange2 := NackRange{FirstPacketNumber: 2, LastPacketNumber: 2} - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 7, - NackRanges: []NackRange{nackRange1, nackRange2}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+2*7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(2))) // numRanges - Expect(missingPacketBytes[7]).To(Equal(uint8(3 - 1))) // rangeLength #1 - Expect(missingPacketBytes[14]).To(Equal(uint8(1 - 1))) // rangeLength #2 - packetNumber1 := make([]byte, 6) - packetNumber2 := make([]byte, 6) - copy(packetNumber1, missingPacketBytes[1:6]) - copy(packetNumber2, missingPacketBytes[8:13]) - Expect(packetNumber1).To(BeEquivalentTo([]byte{1, 0, 0, 0, 0, 0})) - Expect(packetNumber2).To(BeEquivalentTo([]byte{1, 0, 0, 0, 0, 0})) - }) - - Context("contiguous NACK ranges", func() { - It("writes the largest possible NACK range that does not require to be written in contiguous form", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 258, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 257}}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(1))) // numRanges - Expect(missingPacketBytes[1:7]).To(Equal([]byte{1, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta - Expect(missingPacketBytes[7]).To(Equal(uint8(0xFF))) // rangeLength - }) - - It("writes a frame with a contiguous NACK range", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 302, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 301}}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+2*7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(2))) // numRanges - Expect(missingPacketBytes[1:7]).To(Equal([]byte{1, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #1 - Expect(missingPacketBytes[7]).To(Equal(uint8(43))) // rangeLength #1 - Expect(missingPacketBytes[8:14]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #2 - Expect(missingPacketBytes[14]).To(Equal(uint8(0xFF))) // rangeLength #2 - }) - - It("writes a frame with the smallest NACK ranges that requires a contiguous NACK range", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 259, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 258}}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+2*7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(2))) // numRanges - Expect(missingPacketBytes[1:7]).To(Equal([]byte{1, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #1 - Expect(missingPacketBytes[7]).To(Equal(uint8(0))) // rangeLength #1 - Expect(missingPacketBytes[8:14]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #2 - Expect(missingPacketBytes[14]).To(Equal(uint8(0xFF))) // rangeLength #2 - }) - - It("writes a frame with a long contiguous NACK range", func() { - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 603, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 601}}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+3*7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(3))) // numRanges - Expect(missingPacketBytes[1:7]).To(Equal([]byte{2, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #1 - Expect(missingPacketBytes[7]).To(Equal(uint8(87))) // rangeLength #1 - Expect(missingPacketBytes[8:14]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #2 - Expect(missingPacketBytes[14]).To(Equal(uint8(0xFF))) // rangeLength #2 - Expect(missingPacketBytes[15:21]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #3 - Expect(missingPacketBytes[21]).To(Equal(uint8(0xFF))) // rangeLength #3 - }) - - It("writes a frame with two contiguous NACK range", func() { - nackRange1 := NackRange{FirstPacketNumber: 2, LastPacketNumber: 351} - nackRange2 := NackRange{FirstPacketNumber: 355, LastPacketNumber: 654} - frame := AckFrameLegacy{ - Entropy: 2, - LargestObserved: 655, - NackRanges: []NackRange{nackRange2, nackRange1}, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - missingPacketBytes := b.Bytes()[b.Len()-(1+4*7):] - Expect(missingPacketBytes[0]).To(Equal(uint8(4))) // numRanges - Expect(missingPacketBytes[1:7]).To(Equal([]byte{1, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #1 - Expect(missingPacketBytes[7]).To(Equal(uint8(43))) // rangeLength #1 - Expect(missingPacketBytes[8:14]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #2 - Expect(missingPacketBytes[14]).To(Equal(uint8(0xFF))) // rangeLength #2 - Expect(missingPacketBytes[15:21]).To(Equal([]byte{3, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #3 - Expect(missingPacketBytes[21]).To(Equal(uint8(93))) // rangeLength #3 - Expect(missingPacketBytes[22:28]).To(Equal([]byte{0, 0, 0, 0, 0, 0})) // missingPacketSequenceNumberDelta #4 - Expect(missingPacketBytes[28]).To(Equal(uint8(0xFF))) // rangeLength #4 - }) - - Context("LargestObserved length", func() { - It("writes a 1 byte LargestObserved value", func() { - frame := AckFrameLegacy{ - LargestObserved: 7, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(b.Bytes()[0] & 0x4C).To(Equal(uint8(0x40))) - Expect(b.Bytes()[2]).To(Equal(uint8(7))) - }) - - It("writes a 2 byte LargestObserved value", func() { - frame := AckFrameLegacy{ - LargestObserved: 0x1337, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(b.Bytes()[0] & 0x4C).To(Equal(uint8(0x44))) - Expect(b.Bytes()[2:4]).To(Equal([]byte{0x37, 0x13})) - }) - - It("writes a 4 byte LargestObserved value", func() { - frame := AckFrameLegacy{ - LargestObserved: 0xDECAFBAD, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(b.Bytes()[0] & 0x4C).To(Equal(uint8(0x48))) - Expect(b.Bytes()[2:6]).To(Equal([]byte{0xAD, 0xFB, 0xCA, 0xDE})) - }) - - It("writes a 6 byte LargestObserved value", func() { - frame := AckFrameLegacy{ - LargestObserved: 0xDEADBEEFCAFE, - } - err := frame.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(b.Bytes()[0] & 0x4C).To(Equal(uint8(0x4C))) - Expect(b.Bytes()[2:8]).To(Equal([]byte{0xFE, 0xCA, 0xEF, 0xBE, 0xAD, 0xDE})) - }) - }) - }) - - Context("min length", func() { - It("has proper min length", func() { - f := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 1, - } - f.Write(b, 2) - Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len()))) - }) - - It("has proper min length with a large LargestObserved", func() { - f := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 0xDEADBEEFCAFE, - } - f.Write(b, 2) - Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len()))) - }) - - It("has proper min length with NACK ranges", func() { - f := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 4, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2}}, - } - err := f.Write(b, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len()))) - }) - - It("has proper min length with a continuous NACK ranges", func() { - f := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 3000, - NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2000}}, - } - err := f.Write(b, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len()))) - }) - }) - }) - - Context("self-consistency checks", func() { - var b *bytes.Buffer - BeforeEach(func() { - b = &bytes.Buffer{} - }) - - It("is self-consistent for ACK frames without NACK ranges", func() { - frameOrig := &AckFrameLegacy{ - Entropy: 0xDE, - LargestObserved: 6789, - } - err := frameOrig.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - frame, err := ParseAckFrameLegacy(bytes.NewReader(b.Bytes()), protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.Entropy).To(Equal(frameOrig.Entropy)) - Expect(frame.LargestObserved).To(Equal(frameOrig.LargestObserved)) - }) - - It("is self-consistent for ACK frames with NACK ranges", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 9, LastPacketNumber: 11}, - {FirstPacketNumber: 7, LastPacketNumber: 7}, - {FirstPacketNumber: 2, LastPacketNumber: 3}, - } - frameOrig := &AckFrameLegacy{ - LargestObserved: 15, - NackRanges: nackRanges, - } - err := frameOrig.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - r := bytes.NewReader(b.Bytes()) - frame, err := ParseAckFrameLegacy(r, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(frameOrig.LargestObserved)) - Expect(frame.NackRanges).To(HaveLen(len(frameOrig.NackRanges))) - Expect(frame.NackRanges).To(Equal(frameOrig.NackRanges)) - }) - - It("is self-consistent for ACK frames with contiguous NACK ranges", func() { - nackRanges := []NackRange{ - {FirstPacketNumber: 500, LastPacketNumber: 1500}, - {FirstPacketNumber: 350, LastPacketNumber: 351}, - {FirstPacketNumber: 2, LastPacketNumber: 306}, - } - frameOrig := &AckFrameLegacy{ - LargestObserved: 1600, - NackRanges: nackRanges, - } - err := frameOrig.Write(b, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - r := bytes.NewReader(b.Bytes()) - frame, err := ParseAckFrameLegacy(r, protocol.VersionWhatever) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LargestObserved).To(Equal(frameOrig.LargestObserved)) - Expect(frame.NackRanges).To(HaveLen(len(frameOrig.NackRanges))) - Expect(frame.NackRanges).To(Equal(frameOrig.NackRanges)) - }) - }) -}) diff --git a/frames/ack_frame_test.go b/frames/ack_frame_test.go index 27f0d394..e6c20772 100644 --- a/frames/ack_frame_test.go +++ b/frames/ack_frame_test.go @@ -879,46 +879,4 @@ var _ = Describe("AckFrame", func() { Expect(f.AcksPacket(21)).To(BeFalse()) }) }) - - Context("Legacy AckFrame wrapping", func() { - It("parses a ACK frame", func() { - b := bytes.NewReader([]byte{0x40, 0xA4, 0x03, 0x23, 0x45, 0x01, 0x02, 0xFF, 0xEE, 0xDD, 0xCC}) - frame, err := ParseAckFrame(b, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.AckFrameLegacy).ToNot(BeNil()) - Expect(frame.AckFrameLegacy.Entropy).To(Equal(byte(0xA4))) - Expect(frame.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(0x03))) - Expect(frame.LargestAcked).To(BeZero()) - Expect(frame.LowestAcked).To(BeZero()) - Expect(b.Len()).To(Equal(0)) - }) - - It("writes an ACK frame", func() { - b1 := &bytes.Buffer{} - b2 := &bytes.Buffer{} - ackLegacy := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 1, - } - frame := AckFrame{ - AckFrameLegacy: ackLegacy, - } - err := frame.Write(b1, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - err = ackLegacy.Write(b2, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(b1.Bytes()).To(Equal(b2.Bytes())) - }) - - It("determines the minLength", func() { - ackLegacy := &AckFrameLegacy{ - Entropy: 2, - LargestObserved: 1, - } - ack := AckFrame{AckFrameLegacy: ackLegacy} - minLengthLegacy, _ := ackLegacy.MinLength(0) - minLength, _ := ack.MinLength(0) - Expect(minLength).To(Equal(minLengthLegacy)) - }) - }) }) diff --git a/frames/log.go b/frames/log.go index ef3f6900..ac548c64 100644 --- a/frames/log.go +++ b/frames/log.go @@ -15,10 +15,5 @@ func LogFrame(frame Frame, sent bool) { utils.Debugf("\t%s &frames.StreamFrame{StreamID: %d, FinBit: %t, Offset: 0x%x, Data length: 0x%x, Offset + Data length: 0x%x}", dir, sf.StreamID, sf.FinBit, sf.Offset, sf.DataLen(), sf.Offset+sf.DataLen()) return } - if ack, ok := frame.(*AckFrame); ok { - if ack.AckFrameLegacy != nil { - frame = ack.AckFrameLegacy - } - } utils.Debugf("\t%s %#v", dir, frame) } diff --git a/packet_packer_test.go b/packet_packer_test.go index 28d71d70..8675ae73 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -158,7 +158,7 @@ var _ = Describe("Packet packer", func() { }) It("packs many control frames into 1 packets", func() { - f := &frames.AckFrameLegacy{LargestObserved: 1} + f := &frames.AckFrame{LargestAcked: 1} b := &bytes.Buffer{} f.Write(b, protocol.VersionWhatever) maxFramesPerPacket := int(protocol.MaxFrameAndPublicHeaderSize-publicHeaderLen) / b.Len() diff --git a/packet_unpacker_test.go b/packet_unpacker_test.go index 302f9a82..cc43221c 100644 --- a/packet_unpacker_test.go +++ b/packet_unpacker_test.go @@ -81,23 +81,20 @@ var _ = Describe("Packet unpacker", func() { }) It("unpacks ACK frames", func() { + unpacker.version = protocol.Version34 f := &frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 0x13, - Entropy: 0x37, - }, + LargestAcked: 0x13, + LowestAcked: 1, } - err := f.Write(buf, protocol.Version33) + err := f.Write(buf, protocol.Version34) Expect(err).ToNot(HaveOccurred()) setData(buf.Bytes()) - unpacker.version = protocol.Version33 packet, err := unpacker.Unpack(hdrBin, hdr, data) Expect(err).ToNot(HaveOccurred()) Expect(packet.frames).To(HaveLen(1)) readFrame := packet.frames[0].(*frames.AckFrame) - Expect(readFrame.AckFrameLegacy).ToNot(BeNil()) - Expect(readFrame.AckFrameLegacy.LargestObserved).To(Equal(protocol.PacketNumber(0x13))) - Expect(readFrame.AckFrameLegacy.Entropy).To(Equal(byte(0x37))) + Expect(readFrame).ToNot(BeNil()) + Expect(readFrame.LargestAcked).To(Equal(protocol.PacketNumber(0x13))) }) It("errors on CONGESTION_FEEDBACK frames", func() { diff --git a/session_test.go b/session_test.go index 748978a3..ede4cb5c 100644 --- a/session_test.go +++ b/session_test.go @@ -850,15 +850,11 @@ var _ = Describe("Session", func() { Length: 1, }) err := session.handleFrames([]frames.Frame{&frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 1, - }, + LargestAcked: 1, }}) Expect(err).NotTo(HaveOccurred()) err = session.handleFrames([]frames.Frame{&frames.AckFrame{ - AckFrameLegacy: &frames.AckFrameLegacy{ - LargestObserved: 1, - }, + LargestAcked: 1, }}) Expect(err).NotTo(HaveOccurred()) })