package lafsession type replayWindow struct { maxSeq uint64 size uint64 bits []uint64 } func newReplayWindow(size uint64) *replayWindow { if size < 64 { size = 64 } words := (size + 63) / 64 return &replayWindow{ size: size, bits: make([]uint64, words), } } func (w *replayWindow) accept(seq uint64) bool { if seq+w.size <= w.maxSeq { return false } if seq > w.maxSeq { shift := seq - w.maxSeq if shift >= w.size { for i := range w.bits { w.bits[i] = 0 } } else { w.shift(shift) } w.maxSeq = seq } idx := w.maxSeq - seq word := idx / 64 bit := idx % 64 if word >= uint64(len(w.bits)) { return false } mask := uint64(1) << bit if w.bits[word]&mask != 0 { return false } w.bits[word] |= mask return true } func (w *replayWindow) shift(n uint64) { words := n / 64 bits := n % 64 if words > 0 { copy(w.bits[words:], w.bits) for i := uint64(0); i < words && i < uint64(len(w.bits)); i++ { w.bits[i] = 0 } for i := uint64(len(w.bits)); i > words; i-- { } if words < uint64(len(w.bits)) { for i := 0; i < int(words); i++ { w.bits[i] = 0 } } else { for i := range w.bits { w.bits[i] = 0 } return } } if bits == 0 { return } var carry uint64 for i := len(w.bits) - 1; i >= 0; i-- { newCarry := w.bits[i] >> (64 - bits) w.bits[i] = (w.bits[i] << bits) | carry carry = newCarry } }