mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-24 03:06:38 +00:00
112 lines
2.2 KiB
Go
112 lines
2.2 KiB
Go
package activity
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
|
"github.com/netbirdio/netbird/client/internal/peer"
|
|
)
|
|
|
|
type OnAcitvityEvent struct {
|
|
PeerID string
|
|
PeerConnId peer.ConnID
|
|
}
|
|
|
|
type Manager struct {
|
|
OnActivityChan chan OnAcitvityEvent
|
|
|
|
wgIface lazyconn.WGIface
|
|
|
|
portGenerator *portAllocator
|
|
peers map[string]*Listener
|
|
done chan struct{}
|
|
|
|
mu sync.Mutex
|
|
}
|
|
|
|
func NewManager(wgIface lazyconn.WGIface) *Manager {
|
|
m := &Manager{
|
|
OnActivityChan: make(chan OnAcitvityEvent, 1),
|
|
wgIface: wgIface,
|
|
portGenerator: newPortAllocator(),
|
|
peers: make(map[string]*Listener),
|
|
done: make(chan struct{}),
|
|
}
|
|
return m
|
|
}
|
|
|
|
func (m *Manager) MonitorPeerActivity(peerCfg lazyconn.PeerConfig) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
if _, ok := m.peers[peerCfg.PublicKey]; ok {
|
|
log.Warnf("activity listener already exists for: %s", peerCfg.PublicKey)
|
|
return nil
|
|
}
|
|
|
|
conn, addr, err := m.portGenerator.newConn()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to bind activity listener: %v", err)
|
|
}
|
|
|
|
listener, err := NewListener(m.wgIface, peerCfg, conn, addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
m.peers[peerCfg.PublicKey] = listener
|
|
|
|
go m.waitForTraffic(listener, peerCfg.PublicKey, peerCfg.PeerConnID)
|
|
|
|
peerCfg.Log.Infof("created activity listener: %s", addr.String())
|
|
return nil
|
|
}
|
|
|
|
func (m *Manager) RemovePeer(peerID string) bool {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
listener, ok := m.peers[peerID]
|
|
if !ok {
|
|
return false
|
|
}
|
|
delete(m.peers, peerID)
|
|
listener.Close()
|
|
return true
|
|
}
|
|
|
|
func (m *Manager) Close() {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
close(m.done)
|
|
for peerID, listener := range m.peers {
|
|
listener.Close()
|
|
delete(m.peers, peerID)
|
|
}
|
|
}
|
|
|
|
func (m *Manager) waitForTraffic(listener *Listener, peerID string, peerConnID peer.ConnID) {
|
|
listener.ReadPackets()
|
|
|
|
m.mu.Lock()
|
|
if _, ok := m.peers[peerID]; !ok {
|
|
m.mu.Unlock()
|
|
return
|
|
}
|
|
delete(m.peers, peerID)
|
|
m.mu.Unlock()
|
|
|
|
m.notify(OnAcitvityEvent{PeerID: peerID, PeerConnId: peerConnID})
|
|
}
|
|
|
|
func (m *Manager) notify(event OnAcitvityEvent) {
|
|
log.Debugf("peer activity detected: %s", event.PeerID)
|
|
select {
|
|
case <-m.done:
|
|
case m.OnActivityChan <- event:
|
|
}
|
|
}
|