limit number of gaps in received StreamFrame data

fixes #159
This commit is contained in:
Marten Seemann
2016-06-01 15:41:29 +07:00
parent dbaae7fc2b
commit d10766906c
3 changed files with 32 additions and 3 deletions

View File

@@ -59,6 +59,10 @@ const STKExpiryTimeSec = 24 * 60 * 60
// TODO: decrease this value after dropping support for QUIC 33 and earlier
const MaxTrackedSentPackets uint32 = 2000
// MaxStreamFrameSorterGaps is the maximum number of gaps between received StreamFrames
// prevents DOS attacks against the streamFrameSorter
const MaxStreamFrameSorterGaps = 50
// CryptoMaxParams is the upper limit for the number of parameters in a crypto message.
// Value taken from Chrome.
const CryptoMaxParams = 128

View File

@@ -17,6 +17,7 @@ type streamFrameSorter struct {
var (
errOverlappingStreamData = qerr.Error(qerr.OverlappingStreamData, "")
errTooManyGapsInReceivedStreamData = errors.New("Too many gaps in received StreamFrame data")
errDuplicateStreamData = errors.New("Overlapping Stream Data")
errEmptyStreamData = errors.New("Stream Data empty")
)
@@ -93,6 +94,10 @@ func (s *streamFrameSorter) Push(frame *frames.StreamFrame) error {
return errDuplicateStreamData
}
if s.gaps.Len() > protocol.MaxStreamFrameSorterGaps {
return errTooManyGapsInReceivedStreamData
}
s.queuedFrames[frame.Offset] = frame
return nil
}

View File

@@ -395,6 +395,26 @@ var _ = Describe("StreamFrame sorter", func() {
compareGapValues(s.gaps, expectedGaps)
})
})
Context("DOS protection", func() {
It("errors when too many gaps are created", func() {
for i := 0; i < protocol.MaxStreamFrameSorterGaps; i++ {
f := &frames.StreamFrame{
Data: []byte("foobar"),
Offset: protocol.ByteCount(i * 7),
}
err := s.Push(f)
Expect(err).ToNot(HaveOccurred())
}
Expect(s.gaps.Len()).To(Equal(protocol.MaxStreamFrameSorterGaps))
f := &frames.StreamFrame{
Data: []byte("foobar"),
Offset: protocol.ByteCount(protocol.MaxStreamFrameSorterGaps*7) + 100,
}
err := s.Push(f)
Expect(err).To(MatchError(errTooManyGapsInReceivedStreamData))
})
})
})
})
})