@@ -148,6 +148,8 @@ type Engine struct {
148148
149149 // syncMsgMux is used to guarantee sequential Management Service message processing
150150 syncMsgMux * sync.Mutex
151+ // sshMux protects sshServer field access
152+ sshMux sync.Mutex
151153
152154 config * EngineConfig
153155 mobileDep MobileDependency
@@ -710,9 +712,11 @@ func (e *Engine) removeAllPeers() error {
710712func (e * Engine ) removePeer (peerKey string ) error {
711713 log .Debugf ("removing peer from engine %s" , peerKey )
712714
715+ e .sshMux .Lock ()
713716 if ! isNil (e .sshServer ) {
714717 e .sshServer .RemoveAuthorizedKey (peerKey )
715718 }
719+ e .sshMux .Unlock ()
716720
717721 e .connMgr .RemovePeerConn (peerKey )
718722
@@ -914,6 +918,7 @@ func (e *Engine) updateSSH(sshConf *mgmProto.SSHConfig) error {
914918 log .Warnf ("running SSH server on %s is not supported" , runtime .GOOS )
915919 return nil
916920 }
921+ e .sshMux .Lock ()
917922 // start SSH server if it wasn't running
918923 if isNil (e .sshServer ) {
919924 listenAddr := fmt .Sprintf ("%s:%d" , e .wgInterface .Address ().IP .String (), nbssh .DefaultSSHPort )
@@ -925,32 +930,37 @@ func (e *Engine) updateSSH(sshConf *mgmProto.SSHConfig) error {
925930 e .sshServer , err = e .sshServerFunc (e .config .SSHKey , listenAddr )
926931
927932 if err != nil {
933+ e .sshMux .Unlock ()
928934 return fmt .Errorf ("create ssh server: %w" , err )
929935 }
930- e .shutdownWg . Add ( 1 )
936+ e .sshMux . Unlock ( )
931937 go func () {
932- defer e .shutdownWg .Done ()
933938 // blocking
934939 err = e .sshServer .Start ()
935940 if err != nil {
936941 // will throw error when we stop it even if it is a graceful stop
937942 log .Debugf ("stopped SSH server with error %v" , err )
938943 }
939- e .syncMsgMux .Lock ()
940- defer e .syncMsgMux .Unlock ()
944+ e .sshMux .Lock ()
941945 e .sshServer = nil
946+ e .sshMux .Unlock ()
942947 log .Infof ("stopped SSH server" )
943948 }()
944949 } else {
950+ e .sshMux .Unlock ()
945951 log .Debugf ("SSH server is already running" )
946952 }
947- } else if ! isNil (e .sshServer ) {
948- // Disable SSH server request, so stop it if it was running
949- err := e .sshServer .Stop ()
950- if err != nil {
951- log .Warnf ("failed to stop SSH server %v" , err )
953+ } else {
954+ e .sshMux .Lock ()
955+ if ! isNil (e .sshServer ) {
956+ // Disable SSH server request, so stop it if it was running
957+ err := e .sshServer .Stop ()
958+ if err != nil {
959+ log .Warnf ("failed to stop SSH server %v" , err )
960+ }
961+ e .sshServer = nil
952962 }
953- e .sshServer = nil
963+ e .sshMux . Unlock ()
954964 }
955965 return nil
956966}
@@ -1165,6 +1175,7 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
11651175 e .statusRecorder .FinishPeerListModifications ()
11661176
11671177 // update SSHServer by adding remote peer SSH keys
1178+ e .sshMux .Lock ()
11681179 if ! isNil (e .sshServer ) {
11691180 for _ , config := range networkMap .GetRemotePeers () {
11701181 if config .GetSshConfig () != nil && config .GetSshConfig ().GetSshPubKey () != nil {
@@ -1175,6 +1186,7 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
11751186 }
11761187 }
11771188 }
1189+ e .sshMux .Unlock ()
11781190 }
11791191
11801192 // must set the exclude list after the peers are added. Without it the manager can not figure out the peers parameters from the store
@@ -1536,12 +1548,14 @@ func (e *Engine) close() {
15361548 e .statusRecorder .SetWgIface (nil )
15371549 }
15381550
1551+ e .sshMux .Lock ()
15391552 if ! isNil (e .sshServer ) {
15401553 err := e .sshServer .Stop ()
15411554 if err != nil {
15421555 log .Warnf ("failed stopping the SSH server: %v" , err )
15431556 }
15441557 }
1558+ e .sshMux .Unlock ()
15451559
15461560 if e .firewall != nil {
15471561 err := e .firewall .Close (e .stateManager )
0 commit comments