]> Cypherpunks repositories - gostls13.git/commitdiff
net: add support for dialing from a custom local address on Plan 9
authorFazlul Shahriar <fshahriar@gmail.com>
Thu, 25 Jun 2020 23:41:13 +0000 (19:41 -0400)
committerDavid du Colombier <0intro@gmail.com>
Mon, 29 Jun 2020 08:06:32 +0000 (08:06 +0000)
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 <gobot@golang.org>
Reviewed-by: David du Colombier <0intro@gmail.com>
src/net/ipsock_plan9.go

index eaf306495550dbebb77f171ebb1ea63dd5f6ee7e..a5d722d3a1e378c5ee91f947bff3004032a9379d 100644 (file)
@@ -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)
+}