dequeue all retransmission when sending a packet

This commit is contained in:
Marten Seemann
2016-06-06 12:04:02 +07:00
parent 6b6fea94ec
commit 3f86e0f198
3 changed files with 77 additions and 13 deletions

View File

@@ -12,17 +12,30 @@ import (
. "github.com/onsi/gomega"
)
type mockSentPacketHandler struct{}
type mockSentPacketHandler struct {
retransmissionQueue []*ackhandler.Packet
}
func (h *mockSentPacketHandler) SentPacket(packet *ackhandler.Packet) error { return nil }
func (h *mockSentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame) error { return nil }
func (h *mockSentPacketHandler) DequeuePacketForRetransmission() *ackhandler.Packet { return nil }
func (h *mockSentPacketHandler) ProbablyHasPacketForRetransmission() bool { return false }
func (h *mockSentPacketHandler) BytesInFlight() protocol.ByteCount { return 0 }
func (h *mockSentPacketHandler) GetLargestObserved() protocol.PacketNumber { return 1 }
func (h *mockSentPacketHandler) CongestionAllowsSending() bool { panic("not implemented") }
func (h *mockSentPacketHandler) CheckForError() error { panic("not implemented") }
func (h *mockSentPacketHandler) TimeOfFirstRTO() time.Time { panic("not implemented") }
func (h *mockSentPacketHandler) SentPacket(packet *ackhandler.Packet) error { return nil }
func (h *mockSentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame) error { return nil }
func (h *mockSentPacketHandler) BytesInFlight() protocol.ByteCount { return 0 }
func (h *mockSentPacketHandler) GetLargestObserved() protocol.PacketNumber { return 1 }
func (h *mockSentPacketHandler) CongestionAllowsSending() bool { return true }
func (h *mockSentPacketHandler) CheckForError() error { return nil }
func (h *mockSentPacketHandler) TimeOfFirstRTO() time.Time { panic("not implemented") }
func (h *mockSentPacketHandler) ProbablyHasPacketForRetransmission() bool {
return len(h.retransmissionQueue) > 0
}
func (h *mockSentPacketHandler) DequeuePacketForRetransmission() *ackhandler.Packet {
if len(h.retransmissionQueue) > 0 {
packet := h.retransmissionQueue[0]
h.retransmissionQueue = h.retransmissionQueue[1:]
return packet
}
return nil
}
func newMockSentPacketHandler() ackhandler.SentPacketHandler {
return &mockSentPacketHandler{}

View File

@@ -478,9 +478,11 @@ func (s *Session) sendPacket() error {
var controlFrames []frames.Frame
// check for retransmissions first
// TODO: handle multiple packets retransmissions
retransmitPacket := s.sentPacketHandler.DequeuePacketForRetransmission()
if retransmitPacket != nil {
for {
retransmitPacket := s.sentPacketHandler.DequeuePacketForRetransmission()
if retransmitPacket == nil {
break
}
utils.Debugf("\tDequeueing retransmission for packet 0x%x", retransmitPacket.PacketNumber)
s.stopWaitingManager.RegisterPacketForRetransmission(retransmitPacket)
// resend the frames that were in the packet

View File

@@ -455,6 +455,55 @@ var _ = Describe("Session", func() {
})
})
Context("retransmissions", func() {
It("sends a StreamFrame from a packet queued for retransmission", func() {
f := frames.StreamFrame{
StreamID: 0x5,
Data: []byte("foobar1234567"),
}
p := ackhandler.Packet{
PacketNumber: 0x1337,
Frames: []frames.Frame{&f},
}
sph := newMockSentPacketHandler()
sph.(*mockSentPacketHandler).retransmissionQueue = []*ackhandler.Packet{&p}
session.sentPacketHandler = sph
err := session.sendPacket()
Expect(err).NotTo(HaveOccurred())
Expect(conn.written).To(HaveLen(1))
Expect(conn.written[0]).To(ContainSubstring("foobar1234567"))
})
It("sends a StreamFrame from a packet queued for retransmission", func() {
f1 := frames.StreamFrame{
StreamID: 0x5,
Data: []byte("foobar"),
}
f2 := frames.StreamFrame{
StreamID: 0x7,
Data: []byte("loremipsum"),
}
p1 := ackhandler.Packet{
PacketNumber: 0x1337,
Frames: []frames.Frame{&f1},
}
p2 := ackhandler.Packet{
PacketNumber: 0x1338,
Frames: []frames.Frame{&f2},
}
sph := newMockSentPacketHandler()
sph.(*mockSentPacketHandler).retransmissionQueue = []*ackhandler.Packet{&p1, &p2}
session.sentPacketHandler = sph
err := session.sendPacket()
Expect(err).NotTo(HaveOccurred())
Expect(conn.written).To(HaveLen(1))
Expect(conn.written[0]).To(ContainSubstring("foobar"))
Expect(conn.written[0]).To(ContainSubstring("loremipsum"))
})
})
Context("scheduling sending", func() {
It("sends after queuing a stream frame", func() {
Expect(session.sendingScheduled).NotTo(Receive())