]> Cypherpunks repositories - gostls13.git/commitdiff
net: hangup TCP connection after Dial timeout in Plan 9
authorFazlul Shahriar <fshahriar@gmail.com>
Wed, 8 Jul 2020 20:57:10 +0000 (16:57 -0400)
committerDavid du Colombier <0intro@gmail.com>
Fri, 10 Jul 2020 11:32:36 +0000 (11:32 +0000)
After Dial timeout, force close the TCP connection by writing "hangup"
to the control file. This unblocks the "connect" command if the
connection is taking too long to establish, and frees up the control
file FD.

Fixes #40118

Change-Id: I1cef8539cd9fe0793e32b49c9d0ef636b4b26e1d
Reviewed-on: https://go-review.googlesource.com/c/go/+/241638
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David du Colombier <0intro@gmail.com>
src/net/ipsock_plan9.go

index 99d3e3971af9b9d5592d0b31365e4b9a2f7a65ce..23082366aac14de2a070a1bcc2559facdd3189f6 100644 (file)
@@ -206,9 +206,9 @@ func dialPlan9Blocking(ctx context.Context, net string, laddr, raddr Addr) (fd *
                return nil, err
        }
        if la := plan9LocalAddr(laddr); la == "" {
-               _, err = f.WriteString("connect " + dest)
+               err = hangupCtlWrite(ctx, proto, f, "connect "+dest)
        } else {
-               _, err = f.WriteString("connect " + dest + " " + la)
+               err = hangupCtlWrite(ctx, proto, f, "connect "+dest+" "+la)
        }
        if err != nil {
                f.Close()
@@ -339,3 +339,27 @@ func plan9LocalAddr(addr Addr) string {
        }
        return ip.String() + "!" + itoa(port)
 }
+
+func hangupCtlWrite(ctx context.Context, proto string, ctl *os.File, msg string) error {
+       if proto != "tcp" {
+               _, err := ctl.WriteString(msg)
+               return err
+       }
+       written := make(chan struct{})
+       errc := make(chan error)
+       go func() {
+               select {
+               case <-ctx.Done():
+                       ctl.WriteString("hangup")
+                       errc <- mapErr(ctx.Err())
+               case <-written:
+                       errc <- nil
+               }
+       }()
+       _, err := ctl.WriteString(msg)
+       close(written)
+       if e := <-errc; err == nil && e != nil { // we hung up
+               return e
+       }
+       return err
+}