[management] use peer.Status.LastSeen field to detect stale peer.Status.Connected values (#7268)

This commit is contained in:
dmitri-netbird
2026-10-28 18:39:51 +01:00
committed by GitHub
parent 4ff3267542
commit dea73ff13f
20 changed files with 348 additions and 30 deletions
@@ -2,17 +2,20 @@ package grpc
import (
"context"
"sync/atomic"
"time"
"github.com/netbirdio/netbird/encryption"
"github.com/netbirdio/netbird/management/internals/controllers/network_map"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/shared/management/certposture"
"github.com/netbirdio/netbird/shared/management/proto"
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/encryption"
"github.com/netbirdio/netbird/management/internals/controllers/network_map"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/shared/management/certposture"
"github.com/netbirdio/netbird/shared/management/proto"
)
func PeerUpdateHandlerFactory(
@@ -21,6 +24,7 @@ func PeerUpdateHandlerFactory(
secretsManager SecretsManager,
challenger *certposture.Challenger,
onChallengeStamped func(),
heartbeat func(),
srv proto.ManagementService_SyncServer,
cleanupfunc func()) *PeerUpdateHandler {
return &PeerUpdateHandler{
@@ -29,6 +33,7 @@ func PeerUpdateHandlerFactory(
secretsManager: secretsManager,
challenger: challenger,
onChallengeStamped: onChallengeStamped,
heartbeat: heartbeat,
srv: srv,
encrypter: encryption.DefaultEncrypter{},
debouncer: NewUpdateDebouncer(1000 * time.Millisecond),
@@ -54,6 +59,7 @@ type PeerUpdateHandler struct {
encrypter encryption.Encrypter
debouncer Debouncer
cleanupFunc func()
heartbeat func()
}
func (pu *PeerUpdateHandler) WithMetrics(appMetrics telemetry.AppMetrics) *PeerUpdateHandler {
@@ -72,6 +78,14 @@ func (pu *PeerUpdateHandler) HandleUpdates(ctx context.Context) error {
defer pu.debouncer.Stop()
var heartbeat <-chan time.Time
var heartbeatRunning atomic.Bool
if pu.heartbeat != nil {
ticker := time.NewTicker(nbpeer.HeartbeatInterval)
defer ticker.Stop()
heartbeat = ticker.C
}
for {
select {
// condition when there are some updates
@@ -110,6 +124,15 @@ func (pu *PeerUpdateHandler) HandleUpdates(ctx context.Context) error {
}
}
case <-heartbeat:
// A heartbeat that finishes after cleanup writes nothing: it is fenced on this stream's session.
if heartbeatRunning.CompareAndSwap(false, true) {
go func() {
defer heartbeatRunning.Store(false)
pu.heartbeat()
}()
}
// condition when client <-> server connection has been terminated
case <-pu.srv.Context().Done():
// happens when connection drops, e.g. client disconnects