| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 | package nebulaimport (	"github.com/rcrowley/go-metrics"	"github.com/sirupsen/logrus")type Bits struct {	length             uint64	current            uint64	bits               []bool	firstSeen          bool	lostCounter        metrics.Counter	dupeCounter        metrics.Counter	outOfWindowCounter metrics.Counter}func NewBits(bits uint64) *Bits {	return &Bits{		length:             bits,		bits:               make([]bool, bits, bits),		current:            0,		lostCounter:        metrics.GetOrRegisterCounter("network.packets.lost", nil),		dupeCounter:        metrics.GetOrRegisterCounter("network.packets.duplicate", nil),		outOfWindowCounter: metrics.GetOrRegisterCounter("network.packets.out_of_window", nil),	}}func (b *Bits) Check(l logrus.FieldLogger, i uint64) bool {	// If i is the next number, return true.	if i > b.current || (i == 0 && b.firstSeen == false && b.current < b.length) {		return true	}	// If i is within the window, check if it's been set already. The first window will fail this check	if i > b.current-b.length {		return !b.bits[i%b.length]	}	// If i is within the first window	if i < b.length {		return !b.bits[i%b.length]	}	// Not within the window	l.Debugf("rejected a packet (top) %d %d\n", b.current, i)	return false}func (b *Bits) Update(l *logrus.Logger, i uint64) bool {	// If i is the next number, return true and update current.	if i == b.current+1 {		// Report missed packets, we can only understand what was missed after the first window has been gone through		if i > b.length && b.bits[i%b.length] == false {			b.lostCounter.Inc(1)		}		b.bits[i%b.length] = true		b.current = i		return true	}	// If i packet is greater than current but less than the maximum length of our bitmap,	// flip everything in between to false and move ahead.	if i > b.current && i < b.current+b.length {		// In between current and i need to be zero'd to allow those packets to come in later		for n := b.current + 1; n < i; n++ {			b.bits[n%b.length] = false		}		b.bits[i%b.length] = true		b.current = i		//l.Debugf("missed %d packets between %d and %d\n", i-b.current, i, b.current)		return true	}	// If i is greater than the delta between current and the total length of our bitmap,	// just flip everything in the map and move ahead.	if i >= b.current+b.length {		// The current window loss will be accounted for later, only record the jump as loss up until then		lost := maxInt64(0, int64(i-b.current-b.length))		//TODO: explain this		if b.current == 0 {			lost++		}		for n := range b.bits {			// Don't want to count the first window as a loss			//TODO: this is likely wrong, we are wanting to track only the bit slots that we aren't going to track anymore and this is marking everything as missed			//if b.bits[n] == false {			//	lost++			//}			b.bits[n] = false		}		b.lostCounter.Inc(lost)		if l.Level >= logrus.DebugLevel {			l.WithField("receiveWindow", m{"accepted": true, "currentCounter": b.current, "incomingCounter": i, "reason": "window shifting"}).				Debug("Receive window")		}		b.bits[i%b.length] = true		b.current = i		return true	}	// Allow for the 0 packet to come in within the first window	if i == 0 && b.firstSeen == false && b.current < b.length {		b.firstSeen = true		b.bits[i%b.length] = true		return true	}	// If i is within the window of current minus length (the total pat window size),	// allow it and flip to true but to NOT change current. We also have to account for the first window	if ((b.current >= b.length && i > b.current-b.length) || (b.current < b.length && i < b.length)) && i <= b.current {		if b.current == i {			if l.Level >= logrus.DebugLevel {				l.WithField("receiveWindow", m{"accepted": false, "currentCounter": b.current, "incomingCounter": i, "reason": "duplicate"}).					Debug("Receive window")			}			b.dupeCounter.Inc(1)			return false		}		if b.bits[i%b.length] == true {			if l.Level >= logrus.DebugLevel {				l.WithField("receiveWindow", m{"accepted": false, "currentCounter": b.current, "incomingCounter": i, "reason": "old duplicate"}).					Debug("Receive window")			}			b.dupeCounter.Inc(1)			return false		}		b.bits[i%b.length] = true		return true	}	// In all other cases, fail and don't change current.	b.outOfWindowCounter.Inc(1)	if l.Level >= logrus.DebugLevel {		l.WithField("accepted", false).			WithField("currentCounter", b.current).			WithField("incomingCounter", i).			WithField("reason", "nonsense").			Debug("Receive window")	}	return false}func maxInt64(a, b int64) int64 {	if a > b {		return a	}	return b}
 |