Report offline peers to agents (#728)

The peer login expiration ACL check introduced in #714
filters out peers that are expired and agents receive a network map 
without that expired peers.
However, the agents should see those peers in status "Disconnected".

This PR extends the Agent <-> Management protocol 
by introducing a new field OfflinePeers
that contain expired peers. Agents keep track of those and display 
then just in the Status response.
This commit is contained in:
Misha Bragin
2023-03-07 10:17:25 +01:00
committed by GitHub
parent 0e9610c5b2
commit ed4f90b6aa
10 changed files with 354 additions and 163 deletions

View File

@ -132,7 +132,7 @@ func NewEngine(
cancel: cancel,
signal: signalClient,
mgmClient: mgmClient,
peerConns: map[string]*peer.Conn{},
peerConns: make(map[string]*peer.Conn),
syncMsgMux: &sync.Mutex{},
config: config,
STUNs: []*ice.URL{},
@ -557,6 +557,8 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
log.Debugf("got peers update from Management Service, total peers to connect to = %d", len(networkMap.GetRemotePeers()))
e.updateOfflinePeers(networkMap.GetOfflinePeers())
// cleanup request, most likely our peer has been deleted
if networkMap.GetRemotePeersIsEmpty() {
err := e.removeAllPeers()
@ -673,6 +675,21 @@ func toDNSConfig(protoDNSConfig *mgmProto.DNSConfig) nbdns.Config {
return dnsUpdate
}
func (e *Engine) updateOfflinePeers(offlinePeers []*mgmProto.RemotePeerConfig) {
replacement := make([]peer.State, len(offlinePeers))
for i, offlinePeer := range offlinePeers {
log.Debugf("added offline peer %s", offlinePeer.Fqdn)
replacement[i] = peer.State{
IP: strings.Join(offlinePeer.GetAllowedIps(), ","),
PubKey: offlinePeer.GetWgPubKey(),
FQDN: offlinePeer.GetFqdn(),
ConnStatus: peer.StatusDisconnected,
ConnStatusUpdate: time.Now(),
}
}
e.statusRecorder.ReplaceOfflinePeers(replacement)
}
// addNewPeers adds peers that were not know before but arrived from the Management service with the update
func (e *Engine) addNewPeers(peersUpdate []*mgmProto.RemotePeerConfig) error {
for _, p := range peersUpdate {

View File

@ -55,6 +55,7 @@ type Status struct {
signal SignalState
management ManagementState
localPeer LocalPeerState
offlinePeers []State
}
// NewRecorder returns a new Status instance
@ -62,9 +63,18 @@ func NewRecorder() *Status {
return &Status{
peers: make(map[string]State),
changeNotify: make(map[string]chan struct{}),
offlinePeers: make([]State, 0),
}
}
// ReplaceOfflinePeers replaces
func (d *Status) ReplaceOfflinePeers(replacement []State) {
d.mux.Lock()
defer d.mux.Unlock()
d.offlinePeers = make([]State, len(replacement))
copy(d.offlinePeers, replacement)
}
// AddPeer adds peer to Daemon status map
func (d *Status) AddPeer(peerPubKey string) error {
d.mux.Lock()
@ -74,7 +84,7 @@ func (d *Status) AddPeer(peerPubKey string) error {
if ok {
return errors.New("peer already exist")
}
d.peers[peerPubKey] = State{PubKey: peerPubKey}
d.peers[peerPubKey] = State{PubKey: peerPubKey, ConnStatus: StatusDisconnected}
return nil
}
@ -237,5 +247,7 @@ func (d *Status) GetFullStatus() FullStatus {
fullStatus.Peers = append(fullStatus.Peers, status)
}
fullStatus.Peers = append(fullStatus.Peers, d.offlinePeers...)
return fullStatus
}