diff options
Diffstat (limited to 'src/pkg/net/ipsock.go')
-rw-r--r-- | src/pkg/net/ipsock.go | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/src/pkg/net/ipsock.go b/src/pkg/net/ipsock.go deleted file mode 100644 index dda857803..000000000 --- a/src/pkg/net/ipsock.go +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Internet protocol family sockets - -package net - -import ( - "errors" - "time" -) - -var ( - // supportsIPv4 reports whether the platform supports IPv4 - // networking functionality. - supportsIPv4 bool - - // supportsIPv6 reports whether the platform supports IPv6 - // networking functionality. - supportsIPv6 bool - - // supportsIPv4map reports whether the platform supports - // mapping an IPv4 address inside an IPv6 address at transport - // layer protocols. See RFC 4291, RFC 4038 and RFC 3493. - supportsIPv4map bool -) - -func init() { - sysInit() - supportsIPv4 = probeIPv4Stack() - supportsIPv6, supportsIPv4map = probeIPv6Stack() -} - -// A netaddr represents a network endpoint address or a list of -// network endpoint addresses. -type netaddr interface { - // toAddr returns the address represented in Addr interface. - // It returns a nil interface when the address is nil. - toAddr() Addr -} - -// An addrList represents a list of network endpoint addresses. -type addrList []netaddr - -func (al addrList) toAddr() Addr { - switch len(al) { - case 0: - return nil - case 1: - return al[0].toAddr() - default: - // For now, we'll roughly pick first one without - // considering dealing with any preferences such as - // DNS TTL, transport path quality, network routing - // information. - return al[0].toAddr() - } -} - -var errNoSuitableAddress = errors.New("no suitable address found") - -// firstFavoriteAddr returns an address or a list of addresses that -// implement the netaddr interface. Known filters are nil, ipv4only -// and ipv6only. It returns any address when filter is nil. The result -// contains at least one address when error is nil. -func firstFavoriteAddr(filter func(IP) IP, ips []IP, inetaddr func(IP) netaddr) (netaddr, error) { - if filter != nil { - return firstSupportedAddr(filter, ips, inetaddr) - } - var ( - ipv4, ipv6, swap bool - list addrList - ) - for _, ip := range ips { - // We'll take any IP address, but since the dialing - // code does not yet try multiple addresses - // effectively, prefer to use an IPv4 address if - // possible. This is especially relevant if localhost - // resolves to [ipv6-localhost, ipv4-localhost]. Too - // much code assumes localhost == ipv4-localhost. - if ip4 := ipv4only(ip); ip4 != nil && !ipv4 { - list = append(list, inetaddr(ip4)) - ipv4 = true - if ipv6 { - swap = true - } - } else if ip6 := ipv6only(ip); ip6 != nil && !ipv6 { - list = append(list, inetaddr(ip6)) - ipv6 = true - } - if ipv4 && ipv6 { - if swap { - list[0], list[1] = list[1], list[0] - } - break - } - } - switch len(list) { - case 0: - return nil, errNoSuitableAddress - case 1: - return list[0], nil - default: - return list, nil - } -} - -func firstSupportedAddr(filter func(IP) IP, ips []IP, inetaddr func(IP) netaddr) (netaddr, error) { - for _, ip := range ips { - if ip := filter(ip); ip != nil { - return inetaddr(ip), nil - } - } - return nil, errNoSuitableAddress -} - -// ipv4only returns IPv4 addresses that we can use with the kernel's -// IPv4 addressing modes. If ip is an IPv4 address, ipv4only returns ip. -// Otherwise it returns nil. -func ipv4only(ip IP) IP { - if supportsIPv4 && ip.To4() != nil { - return ip - } - return nil -} - -// ipv6only returns IPv6 addresses that we can use with the kernel's -// IPv6 addressing modes. It returns IPv4-mapped IPv6 addresses as -// nils and returns other IPv6 address types as IPv6 addresses. -func ipv6only(ip IP) IP { - if supportsIPv6 && len(ip) == IPv6len && ip.To4() == nil { - return ip - } - return nil -} - -// SplitHostPort splits a network address of the form "host:port", -// "[host]:port" or "[ipv6-host%zone]:port" into host or -// ipv6-host%zone and port. A literal address or host name for IPv6 -// must be enclosed in square brackets, as in "[::1]:80", -// "[ipv6-host]:http" or "[ipv6-host%zone]:80". -func SplitHostPort(hostport string) (host, port string, err error) { - j, k := 0, 0 - - // The port starts after the last colon. - i := last(hostport, ':') - if i < 0 { - goto missingPort - } - - if hostport[0] == '[' { - // Expect the first ']' just before the last ':'. - end := byteIndex(hostport, ']') - if end < 0 { - err = &AddrError{"missing ']' in address", hostport} - return - } - switch end + 1 { - case len(hostport): - // There can't be a ':' behind the ']' now. - goto missingPort - case i: - // The expected result. - default: - // Either ']' isn't followed by a colon, or it is - // followed by a colon that is not the last one. - if hostport[end+1] == ':' { - goto tooManyColons - } - goto missingPort - } - host = hostport[1:end] - j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions - } else { - host = hostport[:i] - if byteIndex(host, ':') >= 0 { - goto tooManyColons - } - if byteIndex(host, '%') >= 0 { - goto missingBrackets - } - } - if byteIndex(hostport[j:], '[') >= 0 { - err = &AddrError{"unexpected '[' in address", hostport} - return - } - if byteIndex(hostport[k:], ']') >= 0 { - err = &AddrError{"unexpected ']' in address", hostport} - return - } - - port = hostport[i+1:] - return - -missingPort: - err = &AddrError{"missing port in address", hostport} - return - -tooManyColons: - err = &AddrError{"too many colons in address", hostport} - return - -missingBrackets: - err = &AddrError{"missing brackets in address", hostport} - return -} - -func splitHostZone(s string) (host, zone string) { - // The IPv6 scoped addressing zone identifier starts after the - // last percent sign. - if i := last(s, '%'); i > 0 { - host, zone = s[:i], s[i+1:] - } else { - host = s - } - return -} - -// JoinHostPort combines host and port into a network address of the -// form "host:port" or, if host contains a colon or a percent sign, -// "[host]:port". -func JoinHostPort(host, port string) string { - // If host has colons or a percent sign, have to bracket it. - if byteIndex(host, ':') >= 0 || byteIndex(host, '%') >= 0 { - return "[" + host + "]:" + port - } - return host + ":" + port -} - -// resolveInternetAddr resolves addr that is either a literal IP -// address or a DNS name and returns an internet protocol family -// address. It returns a list that contains a pair of different -// address family addresses when addr is a DNS name and the name has -// multiple address family records. The result contains at least one -// address when error is nil. -func resolveInternetAddr(net, addr string, deadline time.Time) (netaddr, error) { - var ( - err error - host, port, zone string - portnum int - ) - switch net { - case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6": - if addr != "" { - if host, port, err = SplitHostPort(addr); err != nil { - return nil, err - } - if portnum, err = parsePort(net, port); err != nil { - return nil, err - } - } - case "ip", "ip4", "ip6": - if addr != "" { - host = addr - } - default: - return nil, UnknownNetworkError(net) - } - inetaddr := func(ip IP) netaddr { - switch net { - case "tcp", "tcp4", "tcp6": - return &TCPAddr{IP: ip, Port: portnum, Zone: zone} - case "udp", "udp4", "udp6": - return &UDPAddr{IP: ip, Port: portnum, Zone: zone} - case "ip", "ip4", "ip6": - return &IPAddr{IP: ip, Zone: zone} - default: - panic("unexpected network: " + net) - } - } - if host == "" { - return inetaddr(nil), nil - } - // Try as a literal IP address. - var ip IP - if ip = parseIPv4(host); ip != nil { - return inetaddr(ip), nil - } - if ip, zone = parseIPv6(host, true); ip != nil { - return inetaddr(ip), nil - } - // Try as a DNS name. - host, zone = splitHostZone(host) - ips, err := lookupIPDeadline(host, deadline) - if err != nil { - return nil, err - } - var filter func(IP) IP - if net != "" && net[len(net)-1] == '4' { - filter = ipv4only - } - if net != "" && net[len(net)-1] == '6' || zone != "" { - filter = ipv6only - } - return firstFavoriteAddr(filter, ips, inetaddr) -} - -func zoneToString(zone int) string { - if zone == 0 { - return "" - } - if ifi, err := InterfaceByIndex(zone); err == nil { - return ifi.Name - } - return itod(uint(zone)) -} - -func zoneToInt(zone string) int { - if zone == "" { - return 0 - } - if ifi, err := InterfaceByName(zone); err == nil { - return ifi.Index - } - n, _, _ := dtoi(zone, 0) - return n -} |