forked from quic-go/quic-go
Merge pull request #2569 from lucas-clemente/drop-duplicate-packets
drop duplicate packets
This commit is contained in:
@@ -63,6 +63,7 @@ type sentPacketTracker interface {
|
||||
|
||||
// ReceivedPacketHandler handles ACKs needed to send for incoming packets
|
||||
type ReceivedPacketHandler interface {
|
||||
IsPotentiallyDuplicate(protocol.PacketNumber, protocol.EncryptionLevel) bool
|
||||
ReceivedPacket(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time, shouldInstigateAck bool) error
|
||||
DropPackets(protocol.EncryptionLevel)
|
||||
|
||||
|
||||
@@ -137,3 +137,21 @@ func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel) *
|
||||
}
|
||||
return ack
|
||||
}
|
||||
|
||||
func (h *receivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool {
|
||||
switch encLevel {
|
||||
case protocol.EncryptionInitial:
|
||||
if h.initialPackets != nil {
|
||||
return h.initialPackets.IsPotentiallyDuplicate(pn)
|
||||
}
|
||||
case protocol.EncryptionHandshake:
|
||||
if h.handshakePackets != nil {
|
||||
return h.handshakePackets.IsPotentiallyDuplicate(pn)
|
||||
}
|
||||
case protocol.Encryption0RTT, protocol.Encryption1RTT:
|
||||
if h.appDataPackets != nil {
|
||||
return h.appDataPackets.IsPotentiallyDuplicate(pn)
|
||||
}
|
||||
}
|
||||
panic("unexpected encryption level")
|
||||
}
|
||||
|
||||
@@ -134,4 +134,26 @@ var _ = Describe("Received Packet Handler", func() {
|
||||
Expect(ack.LowestAcked()).To(Equal(protocol.PacketNumber(2)))
|
||||
Expect(ack.LargestAcked()).To(Equal(protocol.PacketNumber(4)))
|
||||
})
|
||||
|
||||
It("says if packets are duplicates", func() {
|
||||
sendTime := time.Now()
|
||||
sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().AnyTimes()
|
||||
// Initial
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.EncryptionInitial)).To(BeFalse())
|
||||
Expect(handler.ReceivedPacket(3, protocol.EncryptionInitial, sendTime, true)).To(Succeed())
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.EncryptionInitial)).To(BeTrue())
|
||||
// Handshake
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.EncryptionHandshake)).To(BeFalse())
|
||||
Expect(handler.ReceivedPacket(3, protocol.EncryptionHandshake, sendTime, true)).To(Succeed())
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.EncryptionHandshake)).To(BeTrue())
|
||||
// 0-RTT
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.Encryption0RTT)).To(BeFalse())
|
||||
Expect(handler.ReceivedPacket(3, protocol.Encryption0RTT, sendTime, true)).To(Succeed())
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.Encryption0RTT)).To(BeTrue())
|
||||
// 1-RTT
|
||||
Expect(handler.IsPotentiallyDuplicate(3, protocol.Encryption1RTT)).To(BeTrue())
|
||||
Expect(handler.IsPotentiallyDuplicate(4, protocol.Encryption1RTT)).To(BeFalse())
|
||||
Expect(handler.ReceivedPacket(4, protocol.Encryption1RTT, sendTime, true)).To(Succeed())
|
||||
Expect(handler.IsPotentiallyDuplicate(4, protocol.Encryption1RTT)).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -128,3 +128,18 @@ func (h *receivedPacketHistory) GetHighestAckRange() wire.AckRange {
|
||||
}
|
||||
return ackRange
|
||||
}
|
||||
|
||||
func (h *receivedPacketHistory) IsPotentiallyDuplicate(p protocol.PacketNumber) bool {
|
||||
if p < h.deletedBelow {
|
||||
return true
|
||||
}
|
||||
for el := h.ranges.Back(); el != nil; el = el.Prev() {
|
||||
if p > el.Value.End {
|
||||
return false
|
||||
}
|
||||
if p <= el.Value.End && p >= el.Value.Start {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -246,4 +246,55 @@ var _ = Describe("receivedPacketHistory", func() {
|
||||
Expect(hist.GetHighestAckRange()).To(Equal(wire.AckRange{Smallest: 6, Largest: 7}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("duplicate detection", func() {
|
||||
It("doesn't declare the first packet a duplicate", func() {
|
||||
Expect(hist.IsPotentiallyDuplicate(5)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("detects a duplicate in a range", func() {
|
||||
hist.ReceivedPacket(4)
|
||||
hist.ReceivedPacket(5)
|
||||
hist.ReceivedPacket(6)
|
||||
Expect(hist.IsPotentiallyDuplicate(3)).To(BeFalse())
|
||||
Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(6)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(7)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("detects a duplicate in multiple ranges", func() {
|
||||
hist.ReceivedPacket(4)
|
||||
hist.ReceivedPacket(5)
|
||||
hist.ReceivedPacket(8)
|
||||
hist.ReceivedPacket(9)
|
||||
Expect(hist.IsPotentiallyDuplicate(3)).To(BeFalse())
|
||||
Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(6)).To(BeFalse())
|
||||
Expect(hist.IsPotentiallyDuplicate(7)).To(BeFalse())
|
||||
Expect(hist.IsPotentiallyDuplicate(8)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(9)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(10)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("says a packet is a potentially duplicate if the ranges were already deleted", func() {
|
||||
hist.ReceivedPacket(4)
|
||||
hist.ReceivedPacket(5)
|
||||
hist.ReceivedPacket(8)
|
||||
hist.ReceivedPacket(9)
|
||||
hist.ReceivedPacket(11)
|
||||
hist.DeleteBelow(8)
|
||||
Expect(hist.IsPotentiallyDuplicate(3)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(6)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(7)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(8)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(9)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(10)).To(BeFalse())
|
||||
Expect(hist.IsPotentiallyDuplicate(11)).To(BeTrue())
|
||||
Expect(hist.IsPotentiallyDuplicate(12)).To(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -188,3 +188,7 @@ func (h *receivedPacketTracker) GetAckFrame() *wire.AckFrame {
|
||||
}
|
||||
|
||||
func (h *receivedPacketTracker) GetAlarmTimeout() time.Time { return h.ackAlarm }
|
||||
|
||||
func (h *receivedPacketTracker) IsPotentiallyDuplicate(pn protocol.PacketNumber) bool {
|
||||
return h.packetHistory.IsPotentiallyDuplicate(pn)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,20 @@ func (mr *MockReceivedPacketHandlerMockRecorder) GetAlarmTimeout() *gomock.Call
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmTimeout", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAlarmTimeout))
|
||||
}
|
||||
|
||||
// IsPotentiallyDuplicate mocks base method
|
||||
func (m *MockReceivedPacketHandler) IsPotentiallyDuplicate(arg0 protocol.PacketNumber, arg1 protocol.EncryptionLevel) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsPotentiallyDuplicate", arg0, arg1)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsPotentiallyDuplicate indicates an expected call of IsPotentiallyDuplicate
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) IsPotentiallyDuplicate(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPotentiallyDuplicate", reflect.TypeOf((*MockReceivedPacketHandler)(nil).IsPotentiallyDuplicate), arg0, arg1)
|
||||
}
|
||||
|
||||
// ReceivedPacket mocks base method
|
||||
func (m *MockReceivedPacketHandler) ReceivedPacket(arg0 protocol.PacketNumber, arg1 protocol.EncryptionLevel, arg2 time.Time, arg3 bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Reference in New Issue
Block a user