status-go/vendor/github.com/anacrolix/dht/v2/tokens.go

58 lines
1.3 KiB
Go

package dht
import (
"crypto/sha1"
"encoding/binary"
"time"
"github.com/bradfitz/iter"
)
// Manages creation and validation of tokens issued to querying nodes.
type tokenServer struct {
// Something only we know that peers can't guess, so they can't deduce valid tokens.
secret []byte
// How long between token changes.
interval time.Duration
// How many intervals may pass between the current interval, and one used to generate a token before it is invalid.
maxIntervalDelta int
timeNow func() time.Time
}
func (me tokenServer) CreateToken(addr Addr) string {
return me.createToken(addr, me.getTimeNow())
}
func (me tokenServer) createToken(addr Addr, t time.Time) string {
h := sha1.New()
ip := addr.IP().To16()
if len(ip) != 16 {
panic(ip)
}
h.Write(ip)
ti := t.UnixNano() / int64(me.interval)
var b [8]byte
binary.BigEndian.PutUint64(b[:], uint64(ti))
h.Write(b[:])
h.Write(me.secret)
return string(h.Sum(nil))
}
func (me *tokenServer) ValidToken(token string, addr Addr) bool {
t := me.getTimeNow()
for range iter.N(me.maxIntervalDelta + 1) {
if me.createToken(addr, t) == token {
return true
}
t = t.Add(-me.interval)
}
return false
}
func (me *tokenServer) getTimeNow() time.Time {
if me.timeNow == nil {
return time.Now()
}
return me.timeNow()
}