From 6881c0f985b4f2f0d0168fb3a91dbcefe2055959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Wed, 17 Jun 2026 16:51:01 +0200 Subject: [PATCH] [client] Apply lazy connection toggle to running engine The daemon SetConfig only persisted the lazy connection flag to the profile config; the running engine was untouched, so a UI/CLI change took effect only after a down/up or daemon restart. Wire SetConfig to push the change into the running engine via a new ConnMgr.SetLocalLazyConn, which sets enabledLocally like an env/CLI flag so a later management sync cannot override it, and starts or stops the lazy manager in place. --- client/internal/conn_mgr.go | 31 ++++++++++++++++++++++++++++++ client/internal/engine_lazyconn.go | 19 ++++++++++++++++++ client/server/server.go | 10 ++++++++++ 3 files changed, 60 insertions(+) create mode 100644 client/internal/engine_lazyconn.go diff --git a/client/internal/conn_mgr.go b/client/internal/conn_mgr.go index 112559132..5d7308706 100644 --- a/client/internal/conn_mgr.go +++ b/client/internal/conn_mgr.go @@ -107,6 +107,37 @@ func (e *ConnMgr) UpdatedRemoteFeatureFlag(ctx context.Context, enabled bool) er } } +// SetLocalLazyConn applies a local lazy connection override (UI / CLI / env). +// While enabledLocally is true, UpdatedRemoteFeatureFlag (management sync) is a +// no-op, so the local setting wins until it is turned off again. +func (e *ConnMgr) SetLocalLazyConn(ctx context.Context, enabled bool) error { + e.enabledLocally = enabled + + if enabled { + if e.lazyConnMgr != nil { + return nil + } + + if e.rosenpassEnabled { + log.Warnf("rosenpass connection manager is enabled, lazy connection manager will not be started") + return nil + } + + log.Infof("lazy connection manager is enabled locally") + e.initLazyManager(ctx) + e.statusRecorder.UpdateLazyConnection(true) + return e.addPeersToLazyConnManager() + } + + if e.lazyConnMgr == nil { + return nil + } + log.Infof("lazy connection manager is disabled locally") + e.closeManager(ctx) + e.statusRecorder.UpdateLazyConnection(false) + return nil +} + // UpdateRouteHAMap updates the route HA mappings in the lazy connection manager func (e *ConnMgr) UpdateRouteHAMap(haMap route.HAMap) { if !e.isStartedWithLazyMgr() { diff --git a/client/internal/engine_lazyconn.go b/client/internal/engine_lazyconn.go new file mode 100644 index 000000000..4910ccf72 --- /dev/null +++ b/client/internal/engine_lazyconn.go @@ -0,0 +1,19 @@ +package internal + +import ( + "errors" +) + +// SetLazyConnEnabled applies a local lazy connection override to the running +// engine. It pins the setting like an env/CLI flag, so a later management sync +// cannot override it. syncMsgMux guards ConnMgr, which is not thread-safe. +func (e *Engine) SetLazyConnEnabled(enabled bool) error { + e.syncMsgMux.Lock() + defer e.syncMsgMux.Unlock() + + if e.connMgr == nil { + return errors.New("connection manager is not initialised") + } + + return e.connMgr.SetLocalLazyConn(e.ctx, enabled) +} diff --git a/client/server/server.go b/client/server/server.go index 09530a00f..efb0db49d 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -422,6 +422,16 @@ func (s *Server) SetConfig(callerCtx context.Context, msg *proto.SetConfigReques return nil, fmt.Errorf("failed to update profile config: %w", err) } + // Apply the lazy connection toggle to the running engine so it takes + // effect without a down/up. s.mutex is already held. + if msg.LazyConnectionEnabled != nil && s.connectClient != nil { + if engine := s.connectClient.Engine(); engine != nil { + if err := engine.SetLazyConnEnabled(msg.GetLazyConnectionEnabled()); err != nil { + log.Errorf("failed to apply lazy connection change at runtime: %v", err) + } + } + } + return &proto.SetConfigResponse{}, nil }