package peer import ( "net/netip" "sort" "sync" "time" ) type pubAddrStore struct { lock sync.Mutex localPub bool localAddr netip.AddrPort lastSeen map[netip.AddrPort]time.Time addrList []netip.AddrPort } func newPubAddrStore(localAddr netip.AddrPort) *pubAddrStore { return &pubAddrStore{ localPub: localAddr.IsValid(), localAddr: localAddr, lastSeen: map[netip.AddrPort]time.Time{}, addrList: make([]netip.AddrPort, 0, 32), } } func (store *pubAddrStore) Store(addr netip.AddrPort) { if store.localPub { return } if !addr.IsValid() { return } if addr.Addr().IsPrivate() { return } store.lock.Lock() defer store.lock.Unlock() if _, exists := store.lastSeen[addr]; !exists { store.addrList = append(store.addrList, addr) } store.lastSeen[addr] = time.Now() store.sort() } func (store *pubAddrStore) Get() (addrs [8]netip.AddrPort) { store.lock.Lock() defer store.lock.Unlock() store.clean() if store.localPub { addrs[0] = store.localAddr return } copy(addrs[:], store.addrList) return } func (store *pubAddrStore) clean() { if store.localPub { return } for ip, lastSeen := range store.lastSeen { if time.Since(lastSeen) > timeoutInterval { delete(store.lastSeen, ip) } } store.addrList = store.addrList[:0] for ip := range store.lastSeen { store.addrList = append(store.addrList, ip) } store.sort() } func (store *pubAddrStore) sort() { sort.Slice(store.addrList, func(i, j int) bool { return store.lastSeen[store.addrList[j]].Before(store.lastSeen[store.addrList[i]]) }) }