diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 000f0d91c..144ccd0b5 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -123,6 +123,7 @@ type LocalBackend struct { varRoot string // or empty if SetVarRoot never called sshAtomicBool syncs.AtomicBool sshServer SSHServer // or nil + shutdownCalled bool // if Shutdown has been called filterAtomic atomic.Value // of *filter.Filter containsViaIPFuncAtomic atomic.Value // of func(netaddr.IP) bool @@ -343,6 +344,7 @@ func (b *LocalBackend) onHealthChange(sys health.Subsystem, err error) { // can no longer be used after Shutdown returns. func (b *LocalBackend) Shutdown() { b.mu.Lock() + b.shutdownCalled = true cc := b.cc b.closePeerAPIListenersLocked() b.mu.Unlock() @@ -2341,6 +2343,9 @@ const peerAPIListenAsync = runtime.GOOS == "windows" || runtime.GOOS == "android func (b *LocalBackend) initPeerAPIListener() { b.mu.Lock() defer b.mu.Unlock() + if b.shutdownCalled { + return + } if b.netMap == nil { // We're called from authReconfig which checks that diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index 73393f2b6..09e953fb7 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -1104,7 +1104,7 @@ func (fl *fakePeerAPIListener) Close() error { func (fl *fakePeerAPIListener) Accept() (net.Conn, error) { <-fl.closed - return nil, io.EOF + return nil, net.ErrClosed } func (fl *fakePeerAPIListener) Addr() net.Addr { return fl.addr }