From 7604f7927d6fb942c28ab69d1b2cfa7054068ee7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 29 Jul 2016 18:00:05 +0700 Subject: [PATCH] send a StopWaiting with every ACK in QUIC 34 fixes #185 --- ackhandler/interfaces.go | 3 +++ ackhandler/sent_packet_handler.go | 10 ++++++++++ ackhandler/sent_packet_handler_test.go | 11 +++++++++++ ackhandlerlegacy/interfaces.go | 2 ++ ackhandlerlegacy/sent_packet_handler.go | 4 ++++ session.go | 4 ++++ session_test.go | 9 ++++++--- 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ackhandler/interfaces.go b/ackhandler/interfaces.go index 1999b4c4..414c4787 100644 --- a/ackhandler/interfaces.go +++ b/ackhandler/interfaces.go @@ -13,6 +13,8 @@ type SentPacketHandler interface { SentPacket(packet *ackhandlerlegacy.Packet) error ReceivedAck(ackFrame *frames.AckFrame, withPacketNumber protocol.PacketNumber) error + GetStopWaitingFrame() *frames.StopWaitingFrame + ProbablyHasPacketForRetransmission() bool DequeuePacketForRetransmission() (packet *ackhandlerlegacy.Packet) @@ -35,6 +37,7 @@ type ReceivedPacketHandler interface { } // StopWaitingManager manages StopWaitings for sent packets +// TODO: remove once we drop support for QUIC 33 type StopWaitingManager interface { RegisterPacketForRetransmission(packet *ackhandlerlegacy.Packet) GetStopWaitingFrame() *frames.StopWaitingFrame diff --git a/ackhandler/sent_packet_handler.go b/ackhandler/sent_packet_handler.go index 0c248a05..935313e6 100644 --- a/ackhandler/sent_packet_handler.go +++ b/ackhandler/sent_packet_handler.go @@ -272,6 +272,16 @@ func (h *sentPacketHandler) GetLargestAcked() protocol.PacketNumber { return h.LargestAcked } +func (h *sentPacketHandler) GetStopWaitingFrame() *frames.StopWaitingFrame { + if h.LargestAcked == 0 { + return nil + } + + return &frames.StopWaitingFrame{ + LeastUnacked: h.LargestAcked + 1, + } +} + func (h *sentPacketHandler) CongestionAllowsSending() bool { return h.BytesInFlight() <= h.congestion.GetCongestionWindow() } diff --git a/ackhandler/sent_packet_handler_test.go b/ackhandler/sent_packet_handler_test.go index ea661516..e9492461 100644 --- a/ackhandler/sent_packet_handler_test.go +++ b/ackhandler/sent_packet_handler_test.go @@ -350,6 +350,17 @@ var _ = Describe("SentPacketHandler", func() { }) }) + Context("StopWaitings", func() { + It("does not get a StopWaiting if no ACKs haven't been received yet", func() { + Expect(handler.GetStopWaitingFrame()).To(BeNil()) + }) + + It("gets a StopWaitingFrame", func() { + handler.LargestAcked = 1336 + Expect(handler.GetStopWaitingFrame()).To(Equal(&frames.StopWaitingFrame{LeastUnacked: 1337})) + }) + }) + Context("calculating RTT", func() { It("calculates the RTT", func() { now := time.Now() diff --git a/ackhandlerlegacy/interfaces.go b/ackhandlerlegacy/interfaces.go index 45d5be5b..0c7253a2 100644 --- a/ackhandlerlegacy/interfaces.go +++ b/ackhandlerlegacy/interfaces.go @@ -12,6 +12,8 @@ type SentPacketHandler interface { SentPacket(packet *Packet) error ReceivedAck(ackFrame *frames.AckFrame, withPacketNumber protocol.PacketNumber) error + GetStopWaitingFrame() *frames.StopWaitingFrame + ProbablyHasPacketForRetransmission() bool DequeuePacketForRetransmission() (packet *Packet) diff --git a/ackhandlerlegacy/sent_packet_handler.go b/ackhandlerlegacy/sent_packet_handler.go index 8cdde14c..d609ec85 100644 --- a/ackhandlerlegacy/sent_packet_handler.go +++ b/ackhandlerlegacy/sent_packet_handler.go @@ -312,6 +312,10 @@ func (h *sentPacketHandler) GetLargestAcked() protocol.PacketNumber { return h.LargestObserved } +func (h *sentPacketHandler) GetStopWaitingFrame() *frames.StopWaitingFrame { + panic("Legacy AckHandler should use StopWaitingManager") +} + func (h *sentPacketHandler) CongestionAllowsSending() bool { return h.BytesInFlight() <= h.congestion.GetCongestionWindow() } diff --git a/session.go b/session.go index 63b42e8f..4c52cce2 100644 --- a/session.go +++ b/session.go @@ -513,6 +513,10 @@ func (s *Session) sendPacket() error { var stopWaitingFrame *frames.StopWaitingFrame if s.version <= protocol.Version33 { stopWaitingFrame = s.stopWaitingManager.GetStopWaitingFrame() + } else { + if ack != nil { + stopWaitingFrame = s.sentPacketHandler.GetStopWaitingFrame() + } } packet, err := s.packer.PackPacket(stopWaitingFrame, controlFrames, s.sentPacketHandler.GetLargestAcked(), maySendOnlyAck) if err != nil { diff --git a/session_test.go b/session_test.go index 42ba531d..c06f99ee 100644 --- a/session_test.go +++ b/session_test.go @@ -56,9 +56,12 @@ func (h *mockSentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame, withPacke } func (h *mockSentPacketHandler) BytesInFlight() protocol.ByteCount { return 0 } func (h *mockSentPacketHandler) GetLargestAcked() 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) GetStopWaitingFrame() *frames.StopWaitingFrame { + panic("not implemented") +} +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