diff --git a/client/iface/iface_close_test.go b/client/iface/iface_close_test.go index ea3115ec0..ecbbf4866 100644 --- a/client/iface/iface_close_test.go +++ b/client/iface/iface_close_test.go @@ -12,6 +12,7 @@ import ( "golang.zx2c4.com/wireguard/tun/netstack" "github.com/netbirdio/netbird/client/iface/device" + nbnetstack "github.com/netbirdio/netbird/client/iface/netstack" "github.com/netbirdio/netbird/client/iface/udpmux" "github.com/netbirdio/netbird/client/iface/wgaddr" "github.com/netbirdio/netbird/client/iface/wgproxy" @@ -34,14 +35,14 @@ func (f *fakeTunDevice) Create() (device.WGConfigurer, error) { func (f *fakeTunDevice) Up() (*udpmux.UniversalUDPMuxDefault, error) { return nil, errors.New("not implemented") } -func (f *fakeTunDevice) UpdateAddr(wgaddr.Address) error { return nil } -func (f *fakeTunDevice) WgAddress() wgaddr.Address { return wgaddr.Address{} } -func (f *fakeTunDevice) MTU() uint16 { return DefaultMTU } -func (f *fakeTunDevice) DeviceName() string { return "nb-close-test" } +func (f *fakeTunDevice) UpdateAddr(wgaddr.Address) error { return nil } +func (f *fakeTunDevice) WgAddress() wgaddr.Address { return wgaddr.Address{} } +func (f *fakeTunDevice) MTU() uint16 { return DefaultMTU } +func (f *fakeTunDevice) DeviceName() string { return "nb-close-test" } func (f *fakeTunDevice) FilteredDevice() *device.FilteredDevice { return nil } -func (f *fakeTunDevice) Device() *wgdevice.Device { return nil } -func (f *fakeTunDevice) GetNet() *netstack.Net { return nil } -func (f *fakeTunDevice) GetICEBind() device.EndpointManager { return nil } +func (f *fakeTunDevice) Device() *wgdevice.Device { return nil } +func (f *fakeTunDevice) GetNet() *netstack.Net { return nil } +func (f *fakeTunDevice) GetICEBind() device.EndpointManager { return nil } func (f *fakeTunDevice) Close() error { close(f.closeStarted) @@ -62,6 +63,10 @@ func (fakeProxyFactory) Free() error { return nil } // WGIface.GetDevice() which needs the same mutex. The fix is to drop // the lock before tun.Close() returns control. func TestWGIface_CloseReleasesMutexBeforeTunClose(t *testing.T) { + // Netstack mode skips the platform interface cleanup in Close, so only + // the mutex and tun close behavior is exercised. + t.Setenv(nbnetstack.EnvUseNetstackMode, "true") + tun := &fakeTunDevice{ closeStarted: make(chan struct{}), unblockClose: make(chan struct{}), @@ -105,7 +110,10 @@ func TestWGIface_CloseReleasesMutexBeforeTunClose(t *testing.T) { close(tun.unblockClose) select { - case <-closeDone: + case err := <-closeDone: + if err != nil { + t.Errorf("WGIface.Close() returned an error: %v", err) + } case <-time.After(2 * time.Second): t.Fatal("WGIface.Close() never returned after the tun was unblocked") } diff --git a/client/ssh/client/client.go b/client/ssh/client/client.go index 31143a4f4..dc94c33f4 100644 --- a/client/ssh/client/client.go +++ b/client/ssh/client/client.go @@ -166,7 +166,8 @@ func (c *Client) ExecuteCommandWithIO(ctx context.Context, command string) error case <-ctx.Done(): _ = session.Signal(ssh.SIGTERM) select { - case <-done: + case err := <-done: + log.Debugf("session ended after SIGTERM: %v", err) return ctx.Err() case <-time.After(100 * time.Millisecond): return ctx.Err() @@ -205,7 +206,8 @@ func (c *Client) ExecuteCommandWithPTY(ctx context.Context, command string) erro case <-ctx.Done(): _ = session.Signal(ssh.SIGTERM) select { - case <-done: + case err := <-done: + log.Debugf("session ended after SIGTERM: %v", err) return ctx.Err() case <-time.After(100 * time.Millisecond): return ctx.Err() diff --git a/management/internals/server/server.go b/management/internals/server/server.go index bbf0f389d..c95092d70 100644 --- a/management/internals/server/server.go +++ b/management/internals/server/server.go @@ -335,7 +335,11 @@ func (s *BaseServer) Stop() error { } select { - case <-s.Errors(): + case err := <-s.Errors(): + if err != nil { + log.WithContext(ctx).Infof("stopped Management Service: %v", err) + return nil + } log.WithContext(ctx).Infof("stopped Management Service") return nil case <-ctx.Done():