Files
netbird/management/server/loginfilter.go
T

114 lines
2.8 KiB
Go

package server
import (
"strings"
"sync"
"time"
log "github.com/sirupsen/logrus"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
)
const (
loginFilterSize = 100_000 // Size of the login filter map, making it large enough for a future
filterTimeout = 5 * time.Minute // Duration to secure the previous login information in the filter
loggingLimit = 100
loggingLimitOnePeer = 30
loggingTresholdOnePeer = 5 * time.Minute
)
type loginFilter struct {
mu sync.RWMutex
logged map[string]metahash
}
type metahash struct {
hashes map[string]struct{}
counter int
start time.Time
}
func newLoginFilter() *loginFilter {
return &loginFilter{
logged: make(map[string]metahash, loginFilterSize),
}
}
func (l *loginFilter) addLogin(wgPubKey, metaHash string) {
l.mu.Lock()
defer l.mu.Unlock()
mh, ok := l.logged[wgPubKey]
if !ok {
mh = metahash{
hashes: make(map[string]struct{}, loggingLimit),
start: time.Now(),
}
}
mh.hashes[metaHash] = struct{}{}
mh.counter++
if mh.counter >= loggingLimit && mh.counter%loggingLimit == 0 && len(mh.hashes) > 1 {
log.WithFields(log.Fields{
"wgPubKey": wgPubKey,
"number of different hashes": len(mh.hashes),
"elapsed time for number of attempts": time.Since(mh.start),
"number of syncs": mh.counter,
}).Info(mh.prepareHashes())
} else if mh.counter%loggingLimitOnePeer == 0 && time.Since(mh.start) > loggingTresholdOnePeer && len(mh.hashes) == 1 {
log.WithFields(log.Fields{
"wgPubKey": wgPubKey,
"elapsed time for number of attempts": time.Since(mh.start),
"number of syncs": mh.counter,
}).Info(mh.prepareHashes())
mh.start = time.Now()
}
l.logged[wgPubKey] = mh
}
func (m *metahash) prepareHashes() string {
var sb strings.Builder
for hash := range m.hashes {
sb.WriteString(hash)
sb.WriteString(", ")
}
return sb.String()
}
func metaHash(meta nbpeer.PeerSystemMeta, pubip string) string {
mac := getMacAddress(meta.NetworkAddresses)
estimatedSize := len(meta.WtVersion) + len(meta.OSVersion) + len(meta.KernelVersion) + len(meta.Hostname) + len(meta.SystemSerialNumber) +
len(pubip) + len(mac) + 6
var b strings.Builder
b.Grow(estimatedSize)
b.WriteString(meta.WtVersion)
b.WriteByte('|')
b.WriteString(meta.OSVersion)
b.WriteByte('|')
b.WriteString(meta.KernelVersion)
b.WriteByte('|')
b.WriteString(meta.Hostname)
b.WriteByte('|')
b.WriteString(meta.SystemSerialNumber)
b.WriteByte('|')
b.WriteString(pubip)
b.WriteByte('|')
b.WriteString(mac)
return b.String()
}
func getMacAddress(nas []nbpeer.NetworkAddress) string {
if len(nas) == 0 {
return ""
}
macs := make([]string, 0, len(nas))
for _, na := range nas {
macs = append(macs, na.Mac)
}
return strings.Join(macs, "/")
}