Checksum the header and refuse sequence numbers the sender never sent
This commit is contained in:
@@ -18,19 +18,39 @@ type lossWindow struct {
|
||||
bits []uint64
|
||||
lost atomic.Uint64
|
||||
late atomic.Uint64
|
||||
|
||||
// The sending half of this stream. Both halves are in this process and the
|
||||
// receiving socket ignores its own outgoing frames, so this window is fed by
|
||||
// that sender alone and by nothing else on the wire.
|
||||
sent *atomic.Uint64
|
||||
}
|
||||
|
||||
func newLossWindows(n int) []lossWindow {
|
||||
w := make([]lossWindow, n)
|
||||
// Takes the sending halves rather than a count, so a window cannot be built
|
||||
// without the bound it judges sequence numbers against.
|
||||
func newLossWindows(tx []*txStats) []lossWindow {
|
||||
w := make([]lossWindow, len(tx))
|
||||
for i := range w {
|
||||
w[i].bits = make([]uint64, lossWords)
|
||||
w[i].sent = &tx[i].sent
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
// A sequence number is only judged once it falls out of the window, so frames
|
||||
// still queued in another rx worker are never miscounted as lost.
|
||||
func (w *lossWindow) observe(seq uint64) {
|
||||
//
|
||||
// Reports whether the sequence number could have come off the wire at all. One
|
||||
// above what the sender has reached is a damaged header rather than a gap, and
|
||||
// is refused before it can touch the base. Believing one would drag the window
|
||||
// up past every real sequence, write off the span in between as lost, and leave
|
||||
// every frame after it arriving below the base and counted late for the rest of
|
||||
// the run. Nothing that arrives later is evidence enough to undo that, which is
|
||||
// why the sender's own frontier is the guard rather than a limit on how far a
|
||||
// single step may move.
|
||||
func (w *lossWindow) observe(seq uint64) bool {
|
||||
if seq >= w.sent.Load() {
|
||||
return false
|
||||
}
|
||||
w.mu.Lock()
|
||||
if !w.inited {
|
||||
// Start half a window below the first sequence seen, so frames another
|
||||
@@ -43,7 +63,7 @@ func (w *lossWindow) observe(seq uint64) {
|
||||
if seq < w.base {
|
||||
w.mu.Unlock()
|
||||
w.late.Add(1)
|
||||
return
|
||||
return true
|
||||
}
|
||||
if seq >= w.base+lossSlots {
|
||||
w.evict(seq - lossSlots + 1)
|
||||
@@ -51,6 +71,7 @@ func (w *lossWindow) observe(seq uint64) {
|
||||
idx := seq & (lossSlots - 1)
|
||||
w.bits[idx>>6] |= 1 << (idx & 63)
|
||||
w.mu.Unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *lossWindow) evict(newBase uint64) {
|
||||
|
||||
Reference in New Issue
Block a user