Skip to content

Commit

Permalink
Debounce network changes
Browse files Browse the repository at this point in the history
  • Loading branch information
hurricanehrndz committed Jun 25, 2024
1 parent d2157bd commit 5ea441e
Showing 1 changed file with 47 additions and 21 deletions.
68 changes: 47 additions & 21 deletions client/internal/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ type Engine struct {
relayProbe *Probe
wgProbe *Probe

wgConnWorker sync.WaitGroup
wgConnWorker sync.WaitGroup
lastNetworkChangeTimestamp *NetworkChangeTimestamp

// checks are the client-applied posture checks that need to be evaluated on the client
checks []*mgmProto.Checks
Expand All @@ -172,6 +173,17 @@ type Peer struct {
WgAllowedIps string
}

// NetworkChangeTimestamp is a thread-safe structure that holds the timestamp of the last network change
type NetworkChangeTimestamp struct {
mu sync.Mutex
value int64
}

// NewNetworkChangeTimestamp creates a new NetworkChangeTimestamp instance with the current time as the initial value
func NewNetworkChangeTimestamp() *NetworkChangeTimestamp {
return &NetworkChangeTimestamp{value: time.Now().Unix()}
}

// NewEngine creates a new Connection Engine
func NewEngine(
clientCtx context.Context,
Expand Down Expand Up @@ -216,24 +228,25 @@ func NewEngineWithProbes(
) *Engine {

return &Engine{
clientCtx: clientCtx,
clientCancel: clientCancel,
signal: signalClient,
mgmClient: mgmClient,
peerConns: make(map[string]*peer.Conn),
syncMsgMux: &sync.Mutex{},
config: config,
mobileDep: mobileDep,
STUNs: []*stun.URI{},
TURNs: []*stun.URI{},
networkSerial: 0,
sshServerFunc: nbssh.DefaultSSHServer,
statusRecorder: statusRecorder,
mgmProbe: mgmProbe,
signalProbe: signalProbe,
relayProbe: relayProbe,
wgProbe: wgProbe,
checks: checks,
clientCtx: clientCtx,
clientCancel: clientCancel,
signal: signalClient,
mgmClient: mgmClient,
peerConns: make(map[string]*peer.Conn),
syncMsgMux: &sync.Mutex{},
config: config,
mobileDep: mobileDep,
STUNs: []*stun.URI{},
TURNs: []*stun.URI{},
networkSerial: 0,
sshServerFunc: nbssh.DefaultSSHServer,
statusRecorder: statusRecorder,
mgmProbe: mgmProbe,
signalProbe: signalProbe,
relayProbe: relayProbe,
wgProbe: wgProbe,
lastNetworkChangeTimestamp: &NetworkChangeTimestamp{},
checks: checks,
}
}

Expand All @@ -244,6 +257,7 @@ func (e *Engine) Stop() error {
if e.cancel != nil {
e.cancel()
}
e.cancel = nil

// stopping network monitor first to avoid starting the engine again
if e.networkMonitor != nil {
Expand Down Expand Up @@ -377,7 +391,6 @@ func (e *Engine) Start() error {
// modifyPeers updates peers that have been modified (e.g. IP address has been changed).
// It closes the existing connection, removes it from the peerConns map, and creates a new one.
func (e *Engine) modifyPeers(peersUpdate []*mgmProto.RemotePeerConfig) error {

// first, check if peers have been modified
var modified []*mgmProto.RemotePeerConfig
for _, p := range peersUpdate {
Expand Down Expand Up @@ -1474,7 +1487,20 @@ func (e *Engine) startNetworkMonitor() {
e.networkMonitor = networkmonitor.New()
go func() {
err := e.networkMonitor.Start(e.ctx, func() {
log.Infof("Network monitor detected network change, restarting engine")
log.Infof("Network monitor: detected network change")
e.lastNetworkChangeTimestamp.mu.Lock()
defer e.lastNetworkChangeTimestamp.mu.Unlock()
now := time.Now().Unix()
if e.lastNetworkChangeTimestamp.value+3 > now || e.cancel == nil {
log.Infof("Network monitor: skipping engine restart")
return
}
log.Infof("Network monitor: detected network change, restarting engine")
e.lastNetworkChangeTimestamp.value = now
if e.cancel == nil {
log.Info("Network monitor: restart already in progress, skipping")
return
}
if err := e.Stop(); err != nil {
log.Errorf("Failed to stop engine: %v", err)
}
Expand Down

0 comments on commit 5ea441e

Please sign in to comment.