fix: Only hold `tailnet.*Conn.Close()` for a short duration (#4015)

* fix: Only hold `tailnet.*Conn.Close()` for a short duration

The long duration could be cause to a test deadlock.

* Add closed chan to listener struct
This commit is contained in:
Kyle Carberry 2022-09-12 12:46:45 -05:00 committed by GitHub
parent d4f0a6fecf
commit 5c0d63d31f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 14 deletions

2
go.mod
View File

@ -49,7 +49,7 @@ replace github.com/tcnksm/go-httpstat => github.com/kylecarbs/go-httpstat v0.0.0
// There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here:
// https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20220907193453-fb5ba5ab658d
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20220912172152-aa5fb7fc6cac
// Switch to our fork that imports fixes from http://github.com/tailscale/ssh.
// See: https://github.com/coder/coder/issues/3371

4
go.sum
View File

@ -355,8 +355,8 @@ github.com/coder/retry v1.3.0 h1:5lAAwt/2Cm6lVmnfBY7sOMXcBOwcwJhmV5QGSELIVWY=
github.com/coder/retry v1.3.0/go.mod h1:tXuRgZgWjUnU5LZPT4lJh4ew2elUhexhlnXzrJWdyFY=
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 h1:tN5GKFT68YLVzJoA8AHuiMNJ0qlhoD3pGN3JY9gxSko=
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
github.com/coder/tailscale v1.1.1-0.20220907193453-fb5ba5ab658d h1:IQ8wJn8MfDS+sesYPpn3EDAyvoGMxFvyyE9uWtcfU6w=
github.com/coder/tailscale v1.1.1-0.20220907193453-fb5ba5ab658d/go.mod h1:MO+tWkQp2YIF3KBnnej/mQvgYccRS5Xk/IrEpZ4Z3BU=
github.com/coder/tailscale v1.1.1-0.20220912172152-aa5fb7fc6cac h1:8v0giAuGwJKFXO3J3ZULhjUku7dSLnBSvTQwkBjhSYs=
github.com/coder/tailscale v1.1.1-0.20220912172152-aa5fb7fc6cac/go.mod h1:MO+tWkQp2YIF3KBnnej/mQvgYccRS5Xk/IrEpZ4Z3BU=
github.com/coder/wireguard-go/tun/netstack v0.0.0-20220823170024-a78136eb0cab h1:9yEvRWXXfyKzXu8AqywCi+tFZAoqCy4wVcsXwuvZNMc=
github.com/coder/wireguard-go/tun/netstack v0.0.0-20220823170024-a78136eb0cab/go.mod h1:TCJ66NtXh3urJotTdoYQOHHkyE899vOQl5TuF+WLSes=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=

View File

@ -387,16 +387,17 @@ func (c *Conn) Closed() <-chan struct{} {
// Close shuts down the Wireguard connection.
func (c *Conn) Close() error {
c.mutex.Lock()
defer c.mutex.Unlock()
select {
case <-c.closed:
c.mutex.Unlock()
return nil
default:
}
close(c.closed)
for _, l := range c.listeners {
_ = l.closeNoLock()
}
close(c.closed)
c.mutex.Unlock()
_ = c.dialer.Close()
_ = c.magicConn.Close()
_ = c.netStack.Close()
@ -406,6 +407,15 @@ func (c *Conn) Close() error {
return nil
}
func (c *Conn) isClosed() bool {
select {
case <-c.closed:
return true
default:
return false
}
}
// This and below is taken _mostly_ verbatim from Tailscale:
// https://github.com/tailscale/tailscale/blob/c88bd53b1b7b2fcf7ba302f2e53dd1ce8c32dad4/tsnet/tsnet.go#L459-L494
@ -422,9 +432,14 @@ func (c *Conn) Listen(network, addr string) (net.Listener, error) {
key: lk,
addr: addr,
conn: make(chan net.Conn),
closed: make(chan struct{}),
conn: make(chan net.Conn),
}
c.mutex.Lock()
if c.isClosed() {
c.mutex.Unlock()
return nil, xerrors.New("closed")
}
if c.listeners == nil {
c.listeners = map[listenKey]*listener{}
}
@ -460,9 +475,12 @@ func (c *Conn) forwardTCP(conn net.Conn, port uint16) {
defer t.Stop()
select {
case ln.conn <- conn:
return
case <-ln.closed:
case <-c.closed:
case <-t.C:
_ = conn.Close()
}
_ = conn.Close()
}
func (c *Conn) forwardTCPToLocal(conn net.Conn, port uint16) {
@ -506,15 +524,18 @@ type listenKey struct {
}
type listener struct {
s *Conn
key listenKey
addr string
conn chan net.Conn
s *Conn
key listenKey
addr string
conn chan net.Conn
closed chan struct{}
}
func (ln *listener) Accept() (net.Conn, error) {
c, ok := <-ln.conn
if !ok {
var c net.Conn
select {
case c = <-ln.conn:
case <-ln.closed:
return nil, xerrors.Errorf("wgnet: %w", net.ErrClosed)
}
return c, nil
@ -530,7 +551,7 @@ func (ln *listener) Close() error {
func (ln *listener) closeNoLock() error {
if v, ok := ln.s.listeners[ln.key]; ok && v == ln {
delete(ln.s.listeners, ln.key)
close(ln.conn)
close(ln.closed)
}
return nil
}