forked from quic-go/quic-go
allow an amplification factor of 3.x
This commit is contained in:
@@ -34,7 +34,6 @@ type SentPacketHandler interface {
|
||||
|
||||
// The SendMode determines if and what kind of packets can be sent.
|
||||
SendMode() SendMode
|
||||
AmplificationWindow() protocol.ByteCount
|
||||
// TimeUntilSend is the time when the next packet should be sent.
|
||||
// It is used for pacing packets.
|
||||
TimeUntilSend() time.Time
|
||||
|
||||
@@ -692,7 +692,7 @@ func (h *sentPacketHandler) SendMode() SendMode {
|
||||
numTrackedPackets += h.handshakePackets.history.Len()
|
||||
}
|
||||
|
||||
if h.AmplificationWindow() == 0 {
|
||||
if h.isAmplificationLimited() {
|
||||
h.logger.Debugf("Amplification window limited. Received %d bytes, already sent out %d bytes", h.bytesReceived, h.bytesSent)
|
||||
return SendNone
|
||||
}
|
||||
@@ -733,14 +733,11 @@ func (h *sentPacketHandler) HasPacingBudget() bool {
|
||||
return h.congestion.HasPacingBudget()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) AmplificationWindow() protocol.ByteCount {
|
||||
func (h *sentPacketHandler) isAmplificationLimited() bool {
|
||||
if h.peerAddressValidated {
|
||||
return protocol.MaxByteCount
|
||||
return false
|
||||
}
|
||||
if h.bytesSent >= amplificationFactor*h.bytesReceived {
|
||||
return 0
|
||||
}
|
||||
return amplificationFactor*h.bytesReceived - h.bytesSent
|
||||
return h.bytesSent >= amplificationFactor*h.bytesReceived
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) bool {
|
||||
|
||||
@@ -512,31 +512,27 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
handler.SendMode()
|
||||
})
|
||||
|
||||
It("returns SendNone if limited by the 3x limit", func() {
|
||||
handler.ReceivedBytes(100)
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), protocol.ByteCount(300), gomock.Any(), protocol.ByteCount(300), true)
|
||||
handler.SentPacket(&Packet{
|
||||
Length: 300,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
Frames: []Frame{{Frame: &wire.PingFrame{}}},
|
||||
SendTime: time.Now(),
|
||||
})
|
||||
cong.EXPECT().CanSend(protocol.ByteCount(300)).Return(true).AnyTimes()
|
||||
Expect(handler.AmplificationWindow()).To(BeZero())
|
||||
Expect(handler.SendMode()).To(Equal(SendNone))
|
||||
})
|
||||
|
||||
It("limits the window to 3x the bytes received, to avoid amplification attacks", func() {
|
||||
handler.ReceivedPacket(protocol.EncryptionInitial) // receiving an Initial packet doesn't validate the client's address
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), protocol.ByteCount(50), gomock.Any(), protocol.ByteCount(50), true)
|
||||
handler.ReceivedBytes(200)
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), true).Times(2)
|
||||
handler.SentPacket(&Packet{
|
||||
Length: 50,
|
||||
PacketNumber: 1,
|
||||
Length: 599,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
Frames: []Frame{{Frame: &wire.PingFrame{}}},
|
||||
SendTime: time.Now(),
|
||||
})
|
||||
handler.ReceivedBytes(100)
|
||||
Expect(handler.AmplificationWindow()).To(Equal(protocol.ByteCount(3*100 - 50)))
|
||||
cong.EXPECT().CanSend(protocol.ByteCount(599)).Return(true)
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
handler.SentPacket(&Packet{
|
||||
PacketNumber: 2,
|
||||
Length: 1,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
Frames: []Frame{{Frame: &wire.PingFrame{}}},
|
||||
SendTime: time.Now(),
|
||||
})
|
||||
Expect(handler.SendMode()).To(Equal(SendNone))
|
||||
})
|
||||
|
||||
It("allows sending of ACKs when congestion limited", func() {
|
||||
|
||||
@@ -38,20 +38,6 @@ func (m *MockSentPacketHandler) EXPECT() *MockSentPacketHandlerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AmplificationWindow mocks base method
|
||||
func (m *MockSentPacketHandler) AmplificationWindow() protocol.ByteCount {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AmplificationWindow")
|
||||
ret0, _ := ret[0].(protocol.ByteCount)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AmplificationWindow indicates an expected call of AmplificationWindow
|
||||
func (mr *MockSentPacketHandlerMockRecorder) AmplificationWindow() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AmplificationWindow", reflect.TypeOf((*MockSentPacketHandler)(nil).AmplificationWindow))
|
||||
}
|
||||
|
||||
// DropPackets mocks base method
|
||||
func (m *MockSentPacketHandler) DropPackets(arg0 protocol.EncryptionLevel) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Reference in New Issue
Block a user