From 152ffca82fa53008bd2872f7163c7a1885da880e Mon Sep 17 00:00:00 2001 From: Fazlul Shahriar Date: Thu, 25 Jun 2020 19:41:13 -0400 Subject: [PATCH] net: add support for dialing from a custom local address on Plan 9 Make use of the extra parameter on "connect" control message to set the local IP address and port. The ip(3) man page doesn't document that the local IP address is settable, but upon inspection of the source code, it's clearly settable. Fixes #39747 Change-Id: Ied3d60452f20d6e5af23d1c1dcb34774af0dbd5b Reviewed-on: https://go-review.googlesource.com/c/go/+/240064 Run-TryBot: David du Colombier <0intro@gmail.com> TryBot-Result: Gobot Gobot Reviewed-by: David du Colombier <0intro@gmail.com> --- src/net/ipsock_plan9.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/net/ipsock_plan9.go b/src/net/ipsock_plan9.go index eaf3064955..a5d722d3a1 100644 --- a/src/net/ipsock_plan9.go +++ b/src/net/ipsock_plan9.go @@ -199,7 +199,11 @@ func dialPlan9Blocking(ctx context.Context, net string, laddr, raddr Addr) (fd * if err != nil { return nil, err } - _, err = f.WriteString("connect " + dest) + if la := plan9LocalAddr(laddr); la == "" { + _, err = f.WriteString("connect " + dest) + } else { + _, err = f.WriteString("connect " + dest + " " + la) + } if err != nil { f.Close() return nil, err @@ -303,3 +307,29 @@ func toLocal(a Addr, net string) Addr { } return a } + +// plan9LocalAddr returns a Plan 9 local address string. +// See setladdrport at https://9p.io/sources/plan9/sys/src/9/ip/devip.c. +func plan9LocalAddr(addr Addr) string { + ip := "" + port := 0 + switch a := addr.(type) { + case *TCPAddr: + if a != nil { + ip = ipEmptyString(a.IP) + port = a.Port + } + case *UDPAddr: + if a != nil { + ip = ipEmptyString(a.IP) + port = a.Port + } + } + if ip == "" { + if port == 0 { + return "" + } + return itoa(port) + } + return ip + "!" + itoa(port) +} -- 2.48.1