github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgNet/kmgUnix/sockaddr_unix.go (about) 1 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 2 3 package kmgUnix 4 5 import ( 6 "net" 7 8 "golang.org/x/sys/unix" 9 ) 10 11 func IPv4TcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) { 12 tcpAddr, err := net.ResolveTCPAddr("tcp", addr) 13 if err != nil { 14 return nil, err 15 } 16 return ipToSocksAddr(unix.AF_INET, tcpAddr.IP, tcpAddr.Port, tcpAddr.Zone) 17 } 18 19 //copy from http://golang.org/src/net/ipsock_posix.go?s=4615:4700#L130 20 func ipToSocksAddr(family int, ip net.IP, port int, zone string) (unix.Sockaddr, error) { 21 switch family { 22 case unix.AF_INET: 23 if len(ip) == 0 { 24 ip = net.IPv4zero 25 } 26 if ip = ip.To4(); ip == nil { 27 return nil, net.InvalidAddrError("non-IPv4 address") 28 } 29 sa := new(unix.SockaddrInet4) 30 for i := 0; i < net.IPv4len; i++ { 31 sa.Addr[i] = ip[i] 32 } 33 sa.Port = port 34 return sa, nil 35 case unix.AF_INET6: 36 if len(ip) == 0 { 37 ip = net.IPv6zero 38 } 39 // IPv4 callers use 0.0.0.0 to mean "announce on any available address". 40 // In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0", 41 // which it refuses to do. Rewrite to the IPv6 unspecified address. 42 if ip.Equal(net.IPv4zero) { 43 ip = net.IPv6zero 44 } 45 if ip = ip.To16(); ip == nil { 46 return nil, net.InvalidAddrError("non-IPv6 address") 47 } 48 sa := new(unix.SockaddrInet6) 49 for i := 0; i < net.IPv6len; i++ { 50 sa.Addr[i] = ip[i] 51 } 52 sa.Port = port 53 sa.ZoneId = uint32(zoneToInt(zone)) 54 return sa, nil 55 } 56 return nil, net.InvalidAddrError("unexpected socket family") 57 } 58 59 func zoneToInt(zone string) int { 60 if zone == "" { 61 return 0 62 } 63 if ifi, err := net.InterfaceByName(zone); err == nil { 64 return ifi.Index 65 } 66 n, _, _ := dtoi(zone, 0) 67 return n 68 } 69 70 const big = 0xFFFFFF 71 72 func dtoi(s string, i0 int) (n int, i int, ok bool) { 73 n = 0 74 for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { 75 n = n*10 + int(s[i]-'0') 76 if n >= big { 77 return 0, i, false 78 } 79 } 80 if i == i0 { 81 return 0, i, false 82 } 83 return n, i, true 84 }