package store import ( "sync" "github.com/netbirdio/netbird/shared/relay/messages" ) type IPeer interface { Close() ID() messages.PeerID } // Store is a thread-safe store of peers // It is used to store the peers that are connected to the relay server type Store struct { peers map[messages.PeerID]IPeer peersLock sync.RWMutex } // NewStore creates a new Store instance func NewStore() *Store { return &Store{ peers: make(map[messages.PeerID]IPeer), } } // AddPeer adds a peer to the store // If the peer already exists, it will be replaced and the old peer will be closed // Returns true if the peer was replaced, false if it was added for the first time. func (s *Store) AddPeer(peer IPeer) bool { s.peersLock.Lock() defer s.peersLock.Unlock() odlPeer, ok := s.peers[peer.ID()] if ok { odlPeer.Close() } s.peers[peer.ID()] = peer return ok } // DeletePeer deletes a peer from the store func (s *Store) DeletePeer(peer IPeer) bool { s.peersLock.Lock() defer s.peersLock.Unlock() dp, ok := s.peers[peer.ID()] if !ok { return false } if dp != peer { return false } delete(s.peers, peer.ID()) return true } // Peer returns a peer by its ID func (s *Store) Peer(id messages.PeerID) (IPeer, bool) { s.peersLock.RLock() defer s.peersLock.RUnlock() p, ok := s.peers[id] return p, ok } // Peers returns all the peers in the store func (s *Store) Peers() []IPeer { s.peersLock.RLock() defer s.peersLock.RUnlock() peers := make([]IPeer, 0, len(s.peers)) for _, p := range s.peers { peers = append(peers, p) } return peers } func (s *Store) GetOnlinePeersAndRegisterInterest(peerIDs []messages.PeerID, listener *Listener) []messages.PeerID { s.peersLock.RLock() defer s.peersLock.RUnlock() onlinePeers := make([]messages.PeerID, 0, len(peerIDs)) listener.AddInterestedPeers(peerIDs) // Check for currently online peers for _, id := range peerIDs { if _, ok := s.peers[id]; ok { onlinePeers = append(onlinePeers, id) } } return onlinePeers }