[client] Ensure engine is stopped before starting it back (#2565)

Before starting a new instance of the engine, check if it is nil and stop the current instance
This commit is contained in:
Carlos Hernandez 2024-09-13 08:46:59 -06:00 committed by GitHub
parent f6d57e7a96
commit 1ef51a4ffa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 9 deletions

View File

@ -158,6 +158,7 @@ func (c *ConnectClient) run(
} }
defer c.statusRecorder.ClientStop() defer c.statusRecorder.ClientStop()
runningChanOpen := true
operation := func() error { operation := func() error {
// if context cancelled we not start new backoff cycle // if context cancelled we not start new backoff cycle
if c.isContextCancelled() { if c.isContextCancelled() {
@ -267,6 +268,12 @@ func (c *ConnectClient) run(
checks := loginResp.GetChecks() checks := loginResp.GetChecks()
c.engineMutex.Lock() c.engineMutex.Lock()
if c.engine != nil && c.engine.ctx.Err() != nil {
log.Info("Stopping Netbird Engine")
if err := c.engine.Stop(); err != nil {
log.Errorf("Failed to stop engine: %v", err)
}
}
c.engine = NewEngineWithProbes(engineCtx, cancel, signalClient, mgmClient, relayManager, engineConfig, mobileDependency, c.statusRecorder, probes, checks) c.engine = NewEngineWithProbes(engineCtx, cancel, signalClient, mgmClient, relayManager, engineConfig, mobileDependency, c.statusRecorder, probes, checks)
c.engineMutex.Unlock() c.engineMutex.Unlock()
@ -279,9 +286,10 @@ func (c *ConnectClient) run(
log.Infof("Netbird engine started, the IP is: %s", peerConfig.GetAddress()) log.Infof("Netbird engine started, the IP is: %s", peerConfig.GetAddress())
state.Set(StatusConnected) state.Set(StatusConnected)
if runningChan != nil { if runningChan != nil && runningChanOpen {
runningChan <- nil runningChan <- nil
close(runningChan) close(runningChan)
runningChanOpen = false
} }
<-engineCtx.Done() <-engineCtx.Done()

View File

@ -1115,10 +1115,7 @@ func (e *Engine) close() {
} }
// stop/restore DNS first so dbus and friends don't complain because of a missing interface // stop/restore DNS first so dbus and friends don't complain because of a missing interface
if e.dnsServer != nil { e.stopDNSServer()
e.dnsServer.Stop()
e.dnsServer = nil
}
if e.routeManager != nil { if e.routeManager != nil {
e.routeManager.Stop() e.routeManager.Stop()
@ -1360,12 +1357,16 @@ func (e *Engine) probeTURNs() []relay.ProbeResult {
} }
func (e *Engine) restartEngine() { func (e *Engine) restartEngine() {
log.Info("restarting engine")
CtxGetState(e.ctx).Set(StatusConnecting)
if err := e.Stop(); err != nil { if err := e.Stop(); err != nil {
log.Errorf("Failed to stop engine: %v", err) log.Errorf("Failed to stop engine: %v", err)
} }
if err := e.Start(); err != nil {
log.Errorf("Failed to start engine: %v", err) _ = CtxGetState(e.ctx).Wrap(ErrResetConnection)
} log.Infof("cancelling client, engine will be recreated")
e.clientCancel()
} }
func (e *Engine) startNetworkMonitor() { func (e *Engine) startNetworkMonitor() {
@ -1387,6 +1388,7 @@ func (e *Engine) startNetworkMonitor() {
defer mu.Unlock() defer mu.Unlock()
if debounceTimer != nil { if debounceTimer != nil {
log.Infof("Network monitor: detected network change, reset debounceTimer")
debounceTimer.Stop() debounceTimer.Stop()
} }
@ -1396,7 +1398,7 @@ func (e *Engine) startNetworkMonitor() {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
log.Infof("Network monitor detected network change, restarting engine") log.Infof("Network monitor: detected network change, restarting engine")
e.restartEngine() e.restartEngine()
}) })
}) })
@ -1421,6 +1423,20 @@ func (e *Engine) addrViaRoutes(addr netip.Addr) (bool, netip.Prefix, error) {
return false, netip.Prefix{}, nil return false, netip.Prefix{}, nil
} }
func (e *Engine) stopDNSServer() {
err := fmt.Errorf("DNS server stopped")
nsGroupStates := e.statusRecorder.GetDNSStates()
for i := range nsGroupStates {
nsGroupStates[i].Enabled = false
nsGroupStates[i].Error = err
}
e.statusRecorder.UpdateDNSStates(nsGroupStates)
if e.dnsServer != nil {
e.dnsServer.Stop()
e.dnsServer = nil
}
}
// isChecksEqual checks if two slices of checks are equal. // isChecksEqual checks if two slices of checks are equal.
func isChecksEqual(checks []*mgmProto.Checks, oChecks []*mgmProto.Checks) bool { func isChecksEqual(checks []*mgmProto.Checks, oChecks []*mgmProto.Checks) bool {
return slices.EqualFunc(checks, oChecks, func(checks, oChecks *mgmProto.Checks) bool { return slices.EqualFunc(checks, oChecks, func(checks, oChecks *mgmProto.Checks) bool {