mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
use linked list to store sent packets in new AckHandler
This commit is contained in:
parent
fe531dd65e
commit
cba965cc0c
6 changed files with 434 additions and 255 deletions
|
@ -34,8 +34,7 @@ type sentPacketHandler struct {
|
||||||
|
|
||||||
largestReceivedPacketWithAck protocol.PacketNumber
|
largestReceivedPacketWithAck protocol.PacketNumber
|
||||||
|
|
||||||
// TODO: Move into separate class as in chromium
|
packetHistory *ackhandlerlegacy.PacketList
|
||||||
packetHistory map[protocol.PacketNumber]*ackhandlerlegacy.Packet
|
|
||||||
stopWaitingManager stopWaitingManager
|
stopWaitingManager stopWaitingManager
|
||||||
|
|
||||||
retransmissionQueue []*ackhandlerlegacy.Packet
|
retransmissionQueue []*ackhandlerlegacy.Packet
|
||||||
|
@ -59,76 +58,70 @@ func NewSentPacketHandler() SentPacketHandler {
|
||||||
)
|
)
|
||||||
|
|
||||||
return &sentPacketHandler{
|
return &sentPacketHandler{
|
||||||
packetHistory: make(map[protocol.PacketNumber]*ackhandlerlegacy.Packet),
|
packetHistory: ackhandlerlegacy.NewPacketList(),
|
||||||
stopWaitingManager: stopWaitingManager{},
|
stopWaitingManager: stopWaitingManager{},
|
||||||
rttStats: rttStats,
|
rttStats: rttStats,
|
||||||
congestion: congestion,
|
congestion: congestion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) ackPacket(packetNumber protocol.PacketNumber) *ackhandlerlegacy.Packet {
|
func (h *sentPacketHandler) ackPacket(packetElement *ackhandlerlegacy.PacketElement) *ackhandlerlegacy.Packet {
|
||||||
packet, ok := h.packetHistory[packetNumber]
|
packet := &packetElement.Value
|
||||||
if ok && !packet.Retransmitted {
|
|
||||||
h.bytesInFlight -= packet.Length
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.LargestInOrderAcked == packetNumber-1 {
|
h.bytesInFlight -= packet.Length
|
||||||
|
|
||||||
|
if h.LargestInOrderAcked == packet.PacketNumber-1 {
|
||||||
h.LargestInOrderAcked++
|
h.LargestInOrderAcked++
|
||||||
|
|
||||||
|
if next := packetElement.Next(); next != nil {
|
||||||
|
h.LargestInOrderAcked = next.Value.PacketNumber - 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(h.packetHistory, packetNumber)
|
h.packetHistory.Remove(packetElement)
|
||||||
|
|
||||||
return packet
|
return packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) nackPacket(packetNumber protocol.PacketNumber) (*ackhandlerlegacy.Packet, error) {
|
func (h *sentPacketHandler) nackPacket(packetElement *ackhandlerlegacy.PacketElement) (*ackhandlerlegacy.Packet, error) {
|
||||||
packet, ok := h.packetHistory[packetNumber]
|
packet := &packetElement.Value
|
||||||
// This means that 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 !ok {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if packet.Retransmitted {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.MissingReports++
|
packet.MissingReports++
|
||||||
|
|
||||||
if packet.MissingReports > protocol.RetransmissionThreshold {
|
if packet.MissingReports > protocol.RetransmissionThreshold {
|
||||||
h.queuePacketForRetransmission(packet)
|
h.queuePacketForRetransmission(packetElement)
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) queuePacketForRetransmission(packet *ackhandlerlegacy.Packet) {
|
// does NOT set packet.Retransmitted. This variable is not needed anymore
|
||||||
|
func (h *sentPacketHandler) queuePacketForRetransmission(packetElement *ackhandlerlegacy.PacketElement) {
|
||||||
|
packet := &packetElement.Value
|
||||||
|
utils.Debugf("\tQueueing packet 0x%x for retransmission", packet.PacketNumber)
|
||||||
h.bytesInFlight -= packet.Length
|
h.bytesInFlight -= packet.Length
|
||||||
h.retransmissionQueue = append(h.retransmissionQueue, packet)
|
h.retransmissionQueue = append(h.retransmissionQueue, packet)
|
||||||
packet.Retransmitted = true
|
|
||||||
|
|
||||||
// If this is the lowest packet that hasn't been acked or retransmitted yet ...
|
// If this is the lowest packet that hasn't been acked or retransmitted yet ...
|
||||||
if packet.PacketNumber == h.LargestInOrderAcked+1 {
|
if packet.PacketNumber == h.LargestInOrderAcked+1 {
|
||||||
// ... increase the LargestInOrderAcked until it's one before the next packet that was not acked and not retransmitted
|
// ... increase the LargestInOrderAcked until it's one before the next packet that was not acked and not retransmitted
|
||||||
for h.LargestInOrderAcked < h.LargestAcked {
|
for el := packetElement; el != nil; el = el.Next() {
|
||||||
if p, notAcked := h.packetHistory[h.LargestInOrderAcked+1]; notAcked && !p.Retransmitted {
|
if h.LargestInOrderAcked == h.LargestAcked {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
h.LargestInOrderAcked++
|
h.LargestInOrderAcked = el.Value.PacketNumber - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.packetHistory.Remove(packetElement)
|
||||||
|
|
||||||
// strictly speaking, this is only necessary for RTO retransmissions
|
// strictly speaking, this is only necessary for RTO retransmissions
|
||||||
// this is because FastRetransmissions are triggered by missing ranges in ACKs, and then the LargestAcked will already be higher than the packet number of the retransmitted packet
|
// this is because FastRetransmissions are triggered by missing ranges in ACKs, and then the LargestAcked will already be higher than the packet number of the retransmitted packet
|
||||||
h.stopWaitingManager.QueuedRetransmissionForPacketNumber(packet.PacketNumber)
|
h.stopWaitingManager.QueuedRetransmissionForPacketNumber(packet.PacketNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) SentPacket(packet *ackhandlerlegacy.Packet) error {
|
func (h *sentPacketHandler) SentPacket(packet *ackhandlerlegacy.Packet) error {
|
||||||
_, ok := h.packetHistory[packet.PacketNumber]
|
// TODO: check for decreasing or duplicate packet numbers
|
||||||
if ok {
|
|
||||||
return errDuplicatePacketNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
h.lastSentPacketTime = now
|
h.lastSentPacketTime = now
|
||||||
|
@ -139,7 +132,7 @@ func (h *sentPacketHandler) SentPacket(packet *ackhandlerlegacy.Packet) error {
|
||||||
h.bytesInFlight += packet.Length
|
h.bytesInFlight += packet.Length
|
||||||
|
|
||||||
h.lastSentPacketNumber = packet.PacketNumber
|
h.lastSentPacketNumber = packet.PacketNumber
|
||||||
h.packetHistory[packet.PacketNumber] = packet
|
h.packetHistory.PushBack(*packet)
|
||||||
|
|
||||||
h.congestion.OnPacketSent(
|
h.congestion.OnPacketSent(
|
||||||
time.Now(),
|
time.Now(),
|
||||||
|
@ -171,48 +164,58 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame, withPacketNum
|
||||||
|
|
||||||
h.LargestAcked = ackFrame.LargestAcked
|
h.LargestAcked = ackFrame.LargestAcked
|
||||||
|
|
||||||
packet, ok := h.packetHistory[h.LargestAcked]
|
|
||||||
if ok {
|
|
||||||
// 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 ackedPackets congestion.PacketVector
|
||||||
var lostPackets congestion.PacketVector
|
var lostPackets congestion.PacketVector
|
||||||
|
|
||||||
// NACK packets below the LowestAcked
|
|
||||||
for i := h.LargestInOrderAcked + 1; i < ackFrame.LowestAcked; 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})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ackRangeIndex := 0
|
ackRangeIndex := 0
|
||||||
for i := ackFrame.LowestAcked; i <= ackFrame.LargestAcked; i++ {
|
|
||||||
|
var el, elNext *ackhandlerlegacy.PacketElement
|
||||||
|
for el = h.packetHistory.Front(); el != nil; el = elNext {
|
||||||
|
// determine the next list element right at the beginning, because el.Next() is not avaible anymore, when the list element is deleted (i.e. when the packet is ACKed)
|
||||||
|
elNext = el.Next()
|
||||||
|
packet := el.Value
|
||||||
|
packetNumber := packet.PacketNumber
|
||||||
|
|
||||||
|
// NACK packets below the LowestAcked
|
||||||
|
if packetNumber < ackFrame.LowestAcked {
|
||||||
|
p, err := h.nackPacket(el)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if p != nil {
|
||||||
|
lostPackets = append(lostPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length})
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the RTT
|
||||||
|
if packetNumber == h.LargestAcked {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if packetNumber > ackFrame.LargestAcked {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if ackFrame.HasMissingRanges() {
|
if ackFrame.HasMissingRanges() {
|
||||||
ackRange := ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
ackRange := ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
||||||
|
|
||||||
if i > ackRange.LastPacketNumber && ackRangeIndex < len(ackFrame.AckRanges)-1 {
|
if packetNumber > ackRange.LastPacketNumber && ackRangeIndex < len(ackFrame.AckRanges)-1 {
|
||||||
ackRangeIndex++
|
ackRangeIndex++
|
||||||
ackRange = ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
ackRange = ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
if i >= ackRange.FirstPacketNumber { // packet i contained in ACK range
|
if packetNumber >= ackRange.FirstPacketNumber { // packet i contained in ACK range
|
||||||
p := h.ackPacket(i)
|
p := h.ackPacket(el)
|
||||||
if p != nil {
|
if p != nil {
|
||||||
ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length})
|
ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p, err := h.nackPacket(i)
|
p, err := h.nackPacket(el)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -221,7 +224,7 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame, withPacketNum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p := h.ackPacket(i)
|
p := h.ackPacket(el)
|
||||||
if p != nil {
|
if p != nil {
|
||||||
ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length})
|
ackedPackets = append(ackedPackets, congestion.PacketInfo{Number: p.PacketNumber, Length: p.Length})
|
||||||
}
|
}
|
||||||
|
@ -245,29 +248,19 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame, withPacketNum
|
||||||
// if a packet has already been queued for retransmission, but a belated ACK is received for this packet, this function will return true, although the packet will not be returend for retransmission by DequeuePacketForRetransmission()
|
// if a packet has already been queued for retransmission, but a belated ACK is received for this packet, this function will return true, although the packet will not be returend for retransmission by DequeuePacketForRetransmission()
|
||||||
func (h *sentPacketHandler) ProbablyHasPacketForRetransmission() bool {
|
func (h *sentPacketHandler) ProbablyHasPacketForRetransmission() bool {
|
||||||
h.maybeQueuePacketsRTO()
|
h.maybeQueuePacketsRTO()
|
||||||
|
|
||||||
return len(h.retransmissionQueue) > 0
|
return len(h.retransmissionQueue) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) DequeuePacketForRetransmission() (packet *ackhandlerlegacy.Packet) {
|
func (h *sentPacketHandler) DequeuePacketForRetransmission() *ackhandlerlegacy.Packet {
|
||||||
if !h.ProbablyHasPacketForRetransmission() {
|
if !h.ProbablyHasPacketForRetransmission() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(h.retransmissionQueue) > 0 {
|
if len(h.retransmissionQueue) > 0 {
|
||||||
queueLen := len(h.retransmissionQueue)
|
queueLen := len(h.retransmissionQueue)
|
||||||
// packets are usually NACKed in descending order. So use the slice as a stack
|
// packets are usually NACKed in descending order. So use the slice as a stack
|
||||||
packet = h.retransmissionQueue[queueLen-1]
|
packet := h.retransmissionQueue[queueLen-1]
|
||||||
h.retransmissionQueue = h.retransmissionQueue[:queueLen-1]
|
h.retransmissionQueue = h.retransmissionQueue[:queueLen-1]
|
||||||
|
|
||||||
// this happens if a belated ACK arrives for this packet
|
|
||||||
// no need to retransmit it
|
|
||||||
_, ok := h.packetHistory[packet.PacketNumber]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(h.packetHistory, packet.PacketNumber)
|
|
||||||
return packet
|
return packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +284,7 @@ func (h *sentPacketHandler) CongestionAllowsSending() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sentPacketHandler) CheckForError() error {
|
func (h *sentPacketHandler) CheckForError() error {
|
||||||
length := len(h.retransmissionQueue) + len(h.packetHistory)
|
length := len(h.retransmissionQueue) + h.packetHistory.Len()
|
||||||
if uint32(length) > protocol.MaxTrackedSentPackets {
|
if uint32(length) > protocol.MaxTrackedSentPackets {
|
||||||
return ErrTooManyTrackedSentPackets
|
return ErrTooManyTrackedSentPackets
|
||||||
}
|
}
|
||||||
|
@ -303,18 +296,21 @@ func (h *sentPacketHandler) maybeQueuePacketsRTO() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for p := h.LargestInOrderAcked + 1; p <= h.lastSentPacketNumber; p++ {
|
for el := h.packetHistory.Front(); el != nil; el = el.Next() {
|
||||||
packet := h.packetHistory[p]
|
packet := &el.Value
|
||||||
if packet != nil && !packet.Retransmitted {
|
if packet.PacketNumber < h.LargestInOrderAcked {
|
||||||
packetsLost := congestion.PacketVector{congestion.PacketInfo{
|
continue
|
||||||
Number: packet.PacketNumber,
|
|
||||||
Length: packet.Length,
|
|
||||||
}}
|
|
||||||
h.congestion.OnCongestionEvent(false, h.BytesInFlight(), nil, packetsLost)
|
|
||||||
h.congestion.OnRetransmissionTimeout(true)
|
|
||||||
h.queuePacketForRetransmission(packet)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 RTO retransmission for packet 0x%x", packet.PacketNumber)
|
||||||
|
h.queuePacketForRetransmission(el)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,15 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
getPacketElement := func(p protocol.PacketNumber) *ackhandlerlegacy.PacketElement {
|
||||||
|
for el := handler.packetHistory.Front(); el != nil; el = el.Next() {
|
||||||
|
if el.Value.PacketNumber == p {
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
It("gets the LargestAcked packet number", func() {
|
It("gets the LargestAcked packet number", func() {
|
||||||
handler.LargestAcked = 0x1337
|
handler.LargestAcked = 0x1337
|
||||||
Expect(handler.GetLargestAcked()).To(Equal(protocol.PacketNumber(0x1337)))
|
Expect(handler.GetLargestAcked()).To(Equal(protocol.PacketNumber(0x1337)))
|
||||||
|
@ -79,14 +88,12 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err = handler.SentPacket(&packet2)
|
err = handler.SentPacket(&packet2)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2)))
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
Expect(handler.packetHistory.Front().Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2)))
|
Expect(handler.packetHistory.Back().Value.PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||||
Expect(handler.packetHistory[1].PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
|
||||||
Expect(handler.packetHistory[2].PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
|
||||||
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("rejects packets with the same packet number", func() {
|
PIt("rejects packets with the same packet number", func() {
|
||||||
packet1 := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 1}
|
packet1 := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 1}
|
||||||
packet2 := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 2}
|
packet2 := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 2}
|
||||||
err := handler.SentPacket(&packet1)
|
err := handler.SentPacket(&packet1)
|
||||||
|
@ -94,7 +101,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err = handler.SentPacket(&packet2)
|
err = handler.SentPacket(&packet2)
|
||||||
Expect(err).To(MatchError(errDuplicatePacketNumber))
|
Expect(err).To(MatchError(errDuplicatePacketNumber))
|
||||||
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1)))
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
Expect(handler.packetHistory.Front().Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(1)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -106,9 +113,10 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err = handler.SentPacket(&packet2)
|
err = handler.SentPacket(&packet2)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(3)))
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
el := handler.packetHistory.Front()
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3)))
|
el = el.Next()
|
||||||
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||||
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(3)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -116,7 +124,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
packet := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 1}
|
packet := ackhandlerlegacy.Packet{PacketNumber: 1, Frames: []frames.Frame{&streamFrame}, Length: 1}
|
||||||
err := handler.SentPacket(&packet)
|
err := handler.SentPacket(&packet)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.packetHistory[1].SendTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1))
|
Expect(handler.packetHistory.Front().Value.SendTime.Unix()).To(BeNumerically("~", time.Now().Unix(), 1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("updates the last sent time", func() {
|
It("updates the last sent time", func() {
|
||||||
|
@ -168,6 +176,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
largestAcked := 3
|
largestAcked := 3
|
||||||
ack := frames.AckFrame{
|
ack := frames.AckFrame{
|
||||||
LargestAcked: protocol.PacketNumber(largestAcked),
|
LargestAcked: protocol.PacketNumber(largestAcked),
|
||||||
|
LowestAcked: 1,
|
||||||
}
|
}
|
||||||
err := handler.ReceivedAck(&ack, 1337)
|
err := handler.ReceivedAck(&ack, 1337)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
@ -215,8 +224,6 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("acks and nacks the right packets", func() {
|
Context("acks and nacks the right packets", func() {
|
||||||
// if a packet is ACKed, it's removed from the packet history
|
|
||||||
|
|
||||||
It("adjusts the LargestInOrderAcked", func() {
|
It("adjusts the LargestInOrderAcked", func() {
|
||||||
ack := frames.AckFrame{
|
ack := frames.AckFrame{
|
||||||
LargestAcked: 5,
|
LargestAcked: 5,
|
||||||
|
@ -225,13 +232,13 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
||||||
for i := 1; i <= 5; i++ {
|
el := handler.packetHistory.Front()
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(i)))
|
|
||||||
}
|
|
||||||
for i := 6; i <= 10; i++ {
|
for i := 6; i <= 10; i++ {
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(i)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(i)))
|
||||||
Expect(handler.packetHistory[protocol.PacketNumber(i)].MissingReports).To(BeZero())
|
Expect(el.Value.MissingReports).To(BeZero())
|
||||||
|
el = el.Next()
|
||||||
}
|
}
|
||||||
|
Expect(el).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("ACKs all packets for an ACK frame with no missing packets", func() {
|
It("ACKs all packets for an ACK frame with no missing packets", func() {
|
||||||
|
@ -242,14 +249,15 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(0)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(0)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
el := handler.packetHistory.Front()
|
||||||
for i := 2; i <= 8; i++ {
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(i)))
|
el = el.Next()
|
||||||
}
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(9)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(9)))
|
Expect(el.Value.MissingReports).To(BeZero())
|
||||||
Expect(handler.packetHistory[9].MissingReports).To(BeZero())
|
el = el.Next()
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(10)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(10)))
|
||||||
Expect(handler.packetHistory[10].MissingReports).To(BeZero())
|
Expect(el.Value.MissingReports).To(BeZero())
|
||||||
|
Expect(el.Next()).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("handles an ACK frame with one missing packet range", func() {
|
It("handles an ACK frame with one missing packet range", func() {
|
||||||
|
@ -263,20 +271,20 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
}
|
}
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(handler.LargestInOrderAcked).To(BeZero())
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(0)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(0)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
el := handler.packetHistory.Front()
|
||||||
for i := 2; i <= 3; i++ {
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(i)))
|
el = el.Next()
|
||||||
}
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(4)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(4)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
Expect(handler.packetHistory[4].MissingReports).To(Equal(uint8(1)))
|
el = el.Next()
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(5)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
Expect(handler.packetHistory[5].MissingReports).To(Equal(uint8(1)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
for i := 6; i <= 9; i++ {
|
el = el.Next()
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(i)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(10)))
|
||||||
}
|
Expect(el.Value.MissingReports).To(BeZero())
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(10)))
|
Expect(el.Next()).To(BeNil())
|
||||||
Expect(handler.packetHistory[10].MissingReports).To(BeZero())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("NACKs packets below the LowestAcked", func() {
|
It("NACKs packets below the LowestAcked", func() {
|
||||||
|
@ -286,10 +294,14 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
}
|
}
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
Expect(handler.LargestInOrderAcked).To(BeZero())
|
||||||
Expect(handler.packetHistory[1].MissingReports).To(Equal(uint8(1)))
|
el := handler.packetHistory.Front()
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory[2].MissingReports).To(Equal(uint8(1)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
|
el = el.Next()
|
||||||
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||||
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
|
Expect(el.Next().Value.PacketNumber).To(Equal(protocol.PacketNumber(9)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("handles an ACK with multiple missing packet ranges", func() {
|
It("handles an ACK with multiple missing packet ranges", func() {
|
||||||
|
@ -306,20 +318,21 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(1)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(1)))
|
el := handler.packetHistory.Front()
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(3)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(6)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(7)))
|
el = el.Next()
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(9)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(4)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
Expect(handler.packetHistory[2].MissingReports).To(Equal(uint8(1)))
|
el = el.Next()
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(4)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
Expect(handler.packetHistory[4].MissingReports).To(Equal(uint8(1)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(5)))
|
el = el.Next()
|
||||||
Expect(handler.packetHistory[5].MissingReports).To(Equal(uint8(1)))
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(8)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(8)))
|
Expect(el.Value.MissingReports).To(Equal(uint8(1)))
|
||||||
Expect(handler.packetHistory[8].MissingReports).To(Equal(uint8(1)))
|
el = el.Next()
|
||||||
Expect(handler.packetHistory[10].MissingReports).To(BeZero())
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(10)))
|
||||||
|
Expect(el.Value.MissingReports).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("processes an ACK frame that would be sent after a late arrival of a packet", func() {
|
It("processes an ACK frame that would be sent after a late arrival of a packet", func() {
|
||||||
|
@ -328,39 +341,49 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
LargestAcked: protocol.PacketNumber(largestObserved),
|
LargestAcked: protocol.PacketNumber(largestObserved),
|
||||||
LowestAcked: 1,
|
LowestAcked: 1,
|
||||||
AckRanges: []frames.AckRange{
|
AckRanges: []frames.AckRange{
|
||||||
{FirstPacketNumber: 1, LastPacketNumber: 2},
|
|
||||||
{FirstPacketNumber: 4, LastPacketNumber: protocol.PacketNumber(largestObserved)},
|
{FirstPacketNumber: 4, LastPacketNumber: protocol.PacketNumber(largestObserved)},
|
||||||
|
{FirstPacketNumber: 1, LastPacketNumber: 2},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := handler.ReceivedAck(&ack1, 1)
|
err := handler.ReceivedAck(&ack1, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 5)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 5)))
|
||||||
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3)))
|
el := handler.packetHistory.Front()
|
||||||
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||||
ack2 := frames.AckFrame{
|
ack2 := frames.AckFrame{
|
||||||
LargestAcked: protocol.PacketNumber(largestObserved),
|
LargestAcked: protocol.PacketNumber(largestObserved),
|
||||||
LowestAcked: 1,
|
LowestAcked: 1,
|
||||||
}
|
}
|
||||||
err = handler.ReceivedAck(&ack2, 2)
|
err = handler.ReceivedAck(&ack2, 2)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 6)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 6)))
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(largestObserved)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(largestObserved)))
|
||||||
for i := 1; i <= largestObserved; i++ {
|
Expect(handler.packetHistory.Front().Value.PacketNumber).To(Equal(protocol.PacketNumber(7)))
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(i)))
|
})
|
||||||
|
|
||||||
|
It("processes an ACK frame that would be sent after a late arrival of a packet and another packet", func() {
|
||||||
|
ack1 := frames.AckFrame{
|
||||||
|
LargestAcked: 6,
|
||||||
|
LowestAcked: 1,
|
||||||
|
AckRanges: []frames.AckRange{
|
||||||
|
{FirstPacketNumber: 4, LastPacketNumber: 6},
|
||||||
|
{FirstPacketNumber: 1, LastPacketNumber: 2},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
err := handler.ReceivedAck(&ack1, 1)
|
||||||
})
|
|
||||||
|
|
||||||
Context("StopWaitings", func() {
|
|
||||||
It("gets a StopWaitingFrame", func() {
|
|
||||||
ack := frames.AckFrame{LargestAcked: 5, LowestAcked: 5}
|
|
||||||
err := handler.ReceivedAck(&ack, 1)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(handler.GetStopWaitingFrame()).To(Equal(&frames.StopWaitingFrame{LeastUnacked: 6}))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 5)))
|
||||||
})
|
el := handler.packetHistory.Front()
|
||||||
|
Expect(el.Value.PacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||||
It("gets a StopWaitingFrame after queueing a retransmission", func() {
|
ack2 := frames.AckFrame{
|
||||||
handler.queuePacketForRetransmission(&ackhandlerlegacy.Packet{PacketNumber: 5, Frames: []frames.Frame{&streamFrame}, Length: 1})
|
LargestAcked: 7,
|
||||||
Expect(handler.GetStopWaitingFrame()).To(Equal(&frames.StopWaitingFrame{LeastUnacked: 6}))
|
LowestAcked: 1,
|
||||||
|
}
|
||||||
|
err = handler.ReceivedAck(&ack2, 2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(len(packets) - 7)))
|
||||||
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(7)))
|
||||||
|
Expect(handler.packetHistory.Front().Value.PacketNumber).To(Equal(protocol.PacketNumber(8)))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -368,9 +391,9 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
It("calculates the RTT", func() {
|
It("calculates the RTT", func() {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// First, fake the sent times of the first, second and last packet
|
// First, fake the sent times of the first, second and last packet
|
||||||
handler.packetHistory[1].SendTime = now.Add(-10 * time.Minute)
|
getPacketElement(1).Value.SendTime = now.Add(-10 * time.Minute)
|
||||||
handler.packetHistory[2].SendTime = now.Add(-5 * time.Minute)
|
getPacketElement(2).Value.SendTime = now.Add(-5 * time.Minute)
|
||||||
handler.packetHistory[6].SendTime = now.Add(-1 * time.Minute)
|
getPacketElement(6).Value.SendTime = now.Add(-1 * time.Minute)
|
||||||
// Now, check that the proper times are used when calculating the deltas
|
// Now, check that the proper times are used when calculating the deltas
|
||||||
err := handler.ReceivedAck(&frames.AckFrame{LargestAcked: 1}, 1)
|
err := handler.ReceivedAck(&frames.AckFrame{LargestAcked: 1}, 1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
@ -385,7 +408,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
|
|
||||||
It("uses the DelayTime in the ack frame", func() {
|
It("uses the DelayTime in the ack frame", func() {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
handler.packetHistory[1].SendTime = now.Add(-10 * time.Minute)
|
getPacketElement(1).Value.SendTime = now.Add(-10 * time.Minute)
|
||||||
err := handler.ReceivedAck(&frames.AckFrame{LargestAcked: 1, DelayTime: 5 * time.Minute}, 1)
|
err := handler.ReceivedAck(&frames.AckFrame{LargestAcked: 1, DelayTime: 5 * time.Minute}, 1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second))
|
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second))
|
||||||
|
@ -414,18 +437,20 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
|
|
||||||
It("does not dequeue a packet if no packet has been nacked", func() {
|
It("does not dequeue a packet if no packet has been nacked", func() {
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
_, err := handler.nackPacket(2)
|
_, err := handler.nackPacket(getPacketElement(2))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
Expect(getPacketElement(2)).ToNot(BeNil())
|
||||||
Expect(handler.ProbablyHasPacketForRetransmission()).To(BeFalse())
|
Expect(handler.ProbablyHasPacketForRetransmission()).To(BeFalse())
|
||||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("queues a packet for retransmission", func() {
|
It("queues a packet for retransmission", func() {
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
||||||
_, err := handler.nackPacket(2)
|
_, err := handler.nackPacket(getPacketElement(2))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
Expect(getPacketElement(2)).To(BeNil())
|
||||||
Expect(handler.ProbablyHasPacketForRetransmission()).To(BeTrue())
|
Expect(handler.ProbablyHasPacketForRetransmission()).To(BeTrue())
|
||||||
Expect(handler.retransmissionQueue).To(HaveLen(1))
|
Expect(handler.retransmissionQueue).To(HaveLen(1))
|
||||||
Expect(handler.retransmissionQueue[0].PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
Expect(handler.retransmissionQueue[0].PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||||
|
@ -433,7 +458,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
|
|
||||||
It("dequeues a packet for retransmission", func() {
|
It("dequeues a packet for retransmission", func() {
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
||||||
_, err := handler.nackPacket(3)
|
_, err := handler.nackPacket(getPacketElement(3))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
packet := handler.DequeuePacketForRetransmission()
|
packet := handler.DequeuePacketForRetransmission()
|
||||||
|
@ -442,23 +467,13 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("deletes a packet from the packetHistory map when sending out the 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(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(3)))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("keeps the packets in the right order", func() {
|
It("keeps the packets in the right order", func() {
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
||||||
_, err := handler.nackPacket(4)
|
_, err := handler.nackPacket(getPacketElement(4))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
||||||
_, err := handler.nackPacket(2)
|
_, err := handler.nackPacket(getPacketElement(2))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
packet := handler.DequeuePacketForRetransmission()
|
packet := handler.DequeuePacketForRetransmission()
|
||||||
|
@ -469,26 +484,6 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(packet.PacketNumber).To(Equal(protocol.PacketNumber(4)))
|
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("changes the LargestInOrderAcked after queueing the lowest packet for retransmission", func() {
|
It("changes the LargestInOrderAcked after queueing the lowest packet for retransmission", func() {
|
||||||
ack := frames.AckFrame{
|
ack := frames.AckFrame{
|
||||||
LargestAcked: 7,
|
LargestAcked: 7,
|
||||||
|
@ -504,7 +499,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
||||||
// this will trigger a retransmission of packet 3
|
// this will trigger a retransmission of packet 3
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
handler.nackPacket(3)
|
handler.nackPacket(getPacketElement(3))
|
||||||
}
|
}
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
||||||
})
|
})
|
||||||
|
@ -524,7 +519,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
||||||
// this will trigger a retransmission of packet 6
|
// this will trigger a retransmission of packet 6
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
handler.nackPacket(6)
|
handler.nackPacket(getPacketElement(6))
|
||||||
}
|
}
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(2)))
|
||||||
})
|
})
|
||||||
|
@ -543,44 +538,29 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// this will trigger a retransmission of packet 3
|
// this will trigger a retransmission of packet 3
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
handler.nackPacket(3)
|
handler.nackPacket(getPacketElement(3))
|
||||||
}
|
}
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(1)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(1)))
|
||||||
// now, trigger retransmission of 2 ...
|
// now, trigger retransmission of 2 ...
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
handler.nackPacket(2)
|
handler.nackPacket(getPacketElement(2))
|
||||||
}
|
}
|
||||||
// and check that it increased LargestInOrderAcked past 3
|
// and check that it increased LargestInOrderAcked past 3
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(5)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does not retransmit a packet if a belated ACK was received", func() {
|
Context("StopWaitings", func() {
|
||||||
// lose packet by NACKing it often enough
|
It("gets a StopWaitingFrame", func() {
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
ack := frames.AckFrame{LargestAcked: 5, LowestAcked: 5}
|
||||||
_, err := handler.nackPacket(2)
|
err := handler.ReceivedAck(&ack, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
Expect(handler.GetStopWaitingFrame()).To(Equal(&frames.StopWaitingFrame{LeastUnacked: 6}))
|
||||||
// this is the belated ACK
|
})
|
||||||
handler.ackPacket(2)
|
|
||||||
// this is the edge case where ProbablyHasPacketForRetransmission() get's it wrong: it says there's probably a packet for retransmission, but actually there isn't
|
|
||||||
Expect(handler.ProbablyHasPacketForRetransmission()).To(BeTrue())
|
|
||||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("correctly treats a belated ACK for a packet that has already been RTO retransmitted", func() {
|
It("gets a StopWaitingFrame after queueing a retransmission", func() {
|
||||||
// lose packet by NACKing it often enough
|
handler.queuePacketForRetransmission(getPacketElement(5))
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold+1; i++ {
|
Expect(handler.GetStopWaitingFrame()).To(Equal(&frames.StopWaitingFrame{LeastUnacked: 6}))
|
||||||
_, err := handler.nackPacket(2)
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
}
|
|
||||||
packet := handler.DequeuePacketForRetransmission()
|
|
||||||
Expect(packet).ToNot(BeNil())
|
|
||||||
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2)))
|
|
||||||
// this is the belated ACK
|
|
||||||
err := handler.ReceivedAck(&frames.AckFrame{LowestAcked: 2, LargestAcked: 3}, 1)
|
|
||||||
Expect(handler.LargestInOrderAcked).To(Equal(protocol.PacketNumber(0)))
|
|
||||||
Expect(handler.LargestAcked).To(Equal(protocol.PacketNumber(3)))
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -612,7 +592,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
|
|
||||||
// Simulate protocol.RetransmissionThreshold more NACKs
|
// Simulate protocol.RetransmissionThreshold more NACKs
|
||||||
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
for i := uint8(0); i < protocol.RetransmissionThreshold; i++ {
|
||||||
_, err = handler.nackPacket(2)
|
_, err = handler.nackPacket(getPacketElement(2))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(0)))
|
Expect(handler.BytesInFlight()).To(Equal(protocol.ByteCount(0)))
|
||||||
|
@ -753,12 +733,6 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(handler.TimeOfFirstRTO().Sub(time.Now())).To(BeNumerically("~", protocol.DefaultRetransmissionTime, time.Millisecond))
|
Expect(handler.TimeOfFirstRTO().Sub(time.Now())).To(BeNumerically("~", protocol.DefaultRetransmissionTime, time.Millisecond))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("ignores nil packets", func() {
|
|
||||||
handler.packetHistory[1] = nil
|
|
||||||
handler.maybeQueuePacketsRTO()
|
|
||||||
Expect(handler.TimeOfFirstRTO().IsZero()).To(BeTrue())
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("queuing packets due to RTO", func() {
|
Context("queuing packets due to RTO", func() {
|
||||||
|
@ -776,22 +750,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
handler.lastSentPacketTime = time.Now().Add(-time.Second)
|
handler.lastSentPacketTime = time.Now().Add(-time.Second)
|
||||||
handler.maybeQueuePacketsRTO()
|
handler.maybeQueuePacketsRTO()
|
||||||
Expect(handler.retransmissionQueue).To(HaveLen(1))
|
Expect(handler.retransmissionQueue).To(HaveLen(1))
|
||||||
Expect(handler.retransmissionQueue[0]).To(Equal(p))
|
Expect(handler.retransmissionQueue[0].PacketNumber).To(Equal(p.PacketNumber))
|
||||||
})
|
|
||||||
|
|
||||||
It("does not queue retransmittedpackets", func() {
|
|
||||||
p := &ackhandlerlegacy.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.maybeQueuePacketsRTO()
|
|
||||||
Expect(handler.retransmissionQueue).To(BeEmpty())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("ignores nil packets", func() {
|
|
||||||
handler.packetHistory[1] = nil
|
|
||||||
handler.maybeQueuePacketsRTO()
|
|
||||||
Expect(handler.retransmissionQueue).To(BeEmpty())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -808,7 +767,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||||
err := handler.SentPacket(p)
|
err := handler.SentPacket(p)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
handler.lastSentPacketTime = time.Now().Add(-time.Second)
|
handler.lastSentPacketTime = time.Now().Add(-time.Second)
|
||||||
Expect(handler.DequeuePacketForRetransmission()).To(Equal(p))
|
Expect(handler.DequeuePacketForRetransmission().PacketNumber).To(Equal(p.PacketNumber))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
7
ackhandlerlegacy/_gen.go
Normal file
7
ackhandlerlegacy/_gen.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/clipperhouse/linkedlist"
|
||||||
|
_ "github.com/clipperhouse/slice"
|
||||||
|
_ "github.com/clipperhouse/stringer"
|
||||||
|
)
|
|
@ -10,6 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Packet is a packet
|
// A Packet is a packet
|
||||||
|
// +gen linkedlist
|
||||||
type Packet struct {
|
type Packet struct {
|
||||||
PacketNumber protocol.PacketNumber
|
PacketNumber protocol.PacketNumber
|
||||||
Frames []frames.Frame
|
Frames []frames.Frame
|
||||||
|
@ -18,7 +19,8 @@ type Packet struct {
|
||||||
Length protocol.ByteCount
|
Length protocol.ByteCount
|
||||||
|
|
||||||
MissingReports uint8
|
MissingReports uint8
|
||||||
Retransmitted bool // has this Packet ever been retransmitted
|
// TODO: remove this when dropping support for QUIC 33
|
||||||
|
Retransmitted bool // has this Packet ever been retransmitted
|
||||||
|
|
||||||
SendTime time.Time
|
SendTime time.Time
|
||||||
}
|
}
|
||||||
|
|
214
ackhandlerlegacy/packet_linkedlist.go
Normal file
214
ackhandlerlegacy/packet_linkedlist.go
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ coverage:
|
||||||
ignore:
|
ignore:
|
||||||
- /utils/byteinterval_linkedlist.go
|
- /utils/byteinterval_linkedlist.go
|
||||||
- /utils/packetinterval_linkedlist.go
|
- /utils/packetinterval_linkedlist.go
|
||||||
|
- /ackhandlerlegacy/packet_linkedlist.go
|
||||||
|
|
||||||
notify:
|
notify:
|
||||||
status:
|
status:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue