diff options
Diffstat (limited to 'src/net/ipsock_posix.go')
-rw-r--r-- | src/net/ipsock_posix.go | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go index c51c227401..50003ac446 100644 --- a/src/net/ipsock_posix.go +++ b/src/net/ipsock_posix.go @@ -142,42 +142,58 @@ func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, soty return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlFn) } +func ipToSockaddrInet4(ip IP, port int) (syscall.SockaddrInet4, error) { + if len(ip) == 0 { + ip = IPv4zero + } + ip4 := ip.To4() + if ip4 == nil { + return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: ip.String()} + } + sa := syscall.SockaddrInet4{Port: port} + copy(sa.Addr[:], ip4) + return sa, nil +} + +func ipToSockaddrInet6(ip IP, port int, zone string) (syscall.SockaddrInet6, error) { + // In general, an IP wildcard address, which is either + // "0.0.0.0" or "::", means the entire IP addressing + // space. For some historical reason, it is used to + // specify "any available address" on some operations + // of IP node. + // + // When the IP node supports IPv4-mapped IPv6 address, + // we allow a listener to listen to the wildcard + // address of both IP addressing spaces by specifying + // IPv6 wildcard address. + if len(ip) == 0 || ip.Equal(IPv4zero) { + ip = IPv6zero + } + // We accept any IPv6 address including IPv4-mapped + // IPv6 address. + ip6 := ip.To16() + if ip6 == nil { + return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: ip.String()} + } + sa := syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))} + copy(sa.Addr[:], ip6) + return sa, nil +} + func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) { switch family { case syscall.AF_INET: - if len(ip) == 0 { - ip = IPv4zero - } - ip4 := ip.To4() - if ip4 == nil { - return nil, &AddrError{Err: "non-IPv4 address", Addr: ip.String()} + sa, err := ipToSockaddrInet4(ip, port) + if err != nil { + return nil, err } - sa := &syscall.SockaddrInet4{Port: port} - copy(sa.Addr[:], ip4) - return sa, nil + return &sa, nil case syscall.AF_INET6: - // In general, an IP wildcard address, which is either - // "0.0.0.0" or "::", means the entire IP addressing - // space. For some historical reason, it is used to - // specify "any available address" on some operations - // of IP node. - // - // When the IP node supports IPv4-mapped IPv6 address, - // we allow a listener to listen to the wildcard - // address of both IP addressing spaces by specifying - // IPv6 wildcard address. - if len(ip) == 0 || ip.Equal(IPv4zero) { - ip = IPv6zero - } - // We accept any IPv6 address including IPv4-mapped - // IPv6 address. - ip6 := ip.To16() - if ip6 == nil { - return nil, &AddrError{Err: "non-IPv6 address", Addr: ip.String()} + sa, err := ipToSockaddrInet6(ip, port, zone) + if err != nil { + return nil, err } - sa := &syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))} - copy(sa.Addr[:], ip6) - return sa, nil + return &sa, nil } return nil, &AddrError{Err: "invalid address family", Addr: ip.String()} } |