aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFazlul Shahriar <fshahriar@gmail.com>2020-07-08 16:57:10 -0400
committerDavid du Colombier <0intro@gmail.com>2020-07-10 11:32:36 +0000
commit3a4322627e781c05418a8cc40ebb9f547a6c4ac8 (patch)
treef14fb62596f4f2264026bab10ed5fe9e61a349ea
parent574dac9d9707ddd35d57aaea646710dfae67bd89 (diff)
downloadgo-3a4322627e781c05418a8cc40ebb9f547a6c4ac8.tar.gz
go-3a4322627e781c05418a8cc40ebb9f547a6c4ac8.zip
net: hangup TCP connection after Dial timeout in Plan 9
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>
-rw-r--r--src/net/ipsock_plan9.go28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/net/ipsock_plan9.go b/src/net/ipsock_plan9.go
index 99d3e3971a..23082366aa 100644
--- a/src/net/ipsock_plan9.go
+++ b/src/net/ipsock_plan9.go
@@ -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
+}