summaryrefslogtreecommitdiff
path: root/libgo/go/net/ipsock.go
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-31 00:59:47 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-31 00:59:47 +0000
commit4a3da3a8a45d5496118798146de1fa4e5798ed5a (patch)
tree13beeaed3698c61903fe93fb1ce70bd9b18d4e7f /libgo/go/net/ipsock.go
parentcd529f4d86a17a3e8959f2cb5ac7132a841ab6f1 (diff)
downloadgcc-4a3da3a8a45d5496118798146de1fa4e5798ed5a.tar.gz
runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field. Reviewed-on: https://go-review.googlesource.com/16525 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229616 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/net/ipsock.go')
-rw-r--r--libgo/go/net/ipsock.go201
1 files changed, 84 insertions, 117 deletions
diff --git a/libgo/go/net/ipsock.go b/libgo/go/net/ipsock.go
index dda85780308..6e75c33d534 100644
--- a/libgo/go/net/ipsock.go
+++ b/libgo/go/net/ipsock.go
@@ -26,113 +26,82 @@ var (
supportsIPv4map bool
)
-func init() {
- sysInit()
- supportsIPv4 = probeIPv4Stack()
- supportsIPv6, supportsIPv4map = probeIPv6Stack()
-}
+// An addrList represents a list of network endpoint addresses.
+type addrList []Addr
-// 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
+// isIPv4 returns true if the Addr contains an IPv4 address.
+func isIPv4(addr Addr) bool {
+ switch addr := addr.(type) {
+ case *TCPAddr:
+ return addr.IP.To4() != nil
+ case *UDPAddr:
+ return addr.IP.To4() != nil
+ case *IPAddr:
+ return addr.IP.To4() != nil
+ }
+ return false
}
-// An addrList represents a list of network endpoint addresses.
-type addrList []netaddr
+// first returns the first address which satisfies strategy, or if
+// none do, then the first address of any kind.
+func (addrs addrList) first(strategy func(Addr) bool) Addr {
+ for _, addr := range addrs {
+ if strategy(addr) {
+ return addr
+ }
+ }
+ return addrs[0]
+}
-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()
+// partition divides an address list into two categories, using a
+// strategy function to assign a boolean label to each address.
+// The first address, and any with a matching label, are returned as
+// primaries, while addresses with the opposite label are returned
+// as fallbacks. For non-empty inputs, primaries is guaranteed to be
+// non-empty.
+func (addrs addrList) partition(strategy func(Addr) bool) (primaries, fallbacks addrList) {
+ var primaryLabel bool
+ for i, addr := range addrs {
+ label := strategy(addr)
+ if i == 0 || label == primaryLabel {
+ primaryLabel = label
+ primaries = append(primaries, addr)
+ } else {
+ fallbacks = append(fallbacks, addr)
+ }
}
+ return
}
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
- )
+// filterAddrList applies a filter to a list of IP addresses,
+// yielding a list of Addr objects. Known filters are nil, ipv4only,
+// and ipv6only. It returns every address when the filter is nil.
+// The result contains at least one address when error is nil.
+func filterAddrList(filter func(IPAddr) bool, ips []IPAddr, inetaddr func(IPAddr) Addr) (addrList, error) {
+ var addrs 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
+ if filter == nil || filter(ip) {
+ addrs = append(addrs, inetaddr(ip))
}
}
- switch len(list) {
- case 0:
+ if len(addrs) == 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
+ return addrs, nil
}
-// 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
+// ipv4only reports whether the kernel supports IPv4 addressing mode
+// and addr is an IPv4 address.
+func ipv4only(addr IPAddr) bool {
+ return supportsIPv4 && addr.IP.To4() != 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
+// ipv6only reports whether the kernel supports IPv6 addressing mode
+// and addr is an IPv6 address except IPv4-mapped IPv6 address.
+func ipv6only(addr IPAddr) bool {
+ return supportsIPv6 && len(addr.IP) == IPv6len && addr.IP.To4() == nil
}
// SplitHostPort splits a network address of the form "host:port",
@@ -153,7 +122,7 @@ func SplitHostPort(hostport string) (host, port string, err error) {
// Expect the first ']' just before the last ':'.
end := byteIndex(hostport, ']')
if end < 0 {
- err = &AddrError{"missing ']' in address", hostport}
+ err = &AddrError{Err: "missing ']' in address", Addr: hostport}
return
}
switch end + 1 {
@@ -182,11 +151,11 @@ func SplitHostPort(hostport string) (host, port string, err error) {
}
}
if byteIndex(hostport[j:], '[') >= 0 {
- err = &AddrError{"unexpected '[' in address", hostport}
+ err = &AddrError{Err: "unexpected '[' in address", Addr: hostport}
return
}
if byteIndex(hostport[k:], ']') >= 0 {
- err = &AddrError{"unexpected ']' in address", hostport}
+ err = &AddrError{Err: "unexpected ']' in address", Addr: hostport}
return
}
@@ -194,15 +163,15 @@ func SplitHostPort(hostport string) (host, port string, err error) {
return
missingPort:
- err = &AddrError{"missing port in address", hostport}
+ err = &AddrError{Err: "missing port in address", Addr: hostport}
return
tooManyColons:
- err = &AddrError{"too many colons in address", hostport}
+ err = &AddrError{Err: "too many colons in address", Addr: hostport}
return
missingBrackets:
- err = &AddrError{"missing brackets in address", hostport}
+ err = &AddrError{Err: "missing brackets in address", Addr: hostport}
return
}
@@ -228,17 +197,15 @@ func JoinHostPort(host, port string) string {
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) {
+// internetAddrList resolves addr, which may be a literal IP
+// address or a DNS name, and returns a list of internet protocol
+// family addresses. The result contains at least one address when
+// error is nil.
+func internetAddrList(net, addr string, deadline time.Time) (addrList, error) {
var (
- err error
- host, port, zone string
- portnum int
+ err error
+ host, port string
+ portnum int
)
switch net {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
@@ -257,43 +224,43 @@ func resolveInternetAddr(net, addr string, deadline time.Time) (netaddr, error)
default:
return nil, UnknownNetworkError(net)
}
- inetaddr := func(ip IP) netaddr {
+ inetaddr := func(ip IPAddr) Addr {
switch net {
case "tcp", "tcp4", "tcp6":
- return &TCPAddr{IP: ip, Port: portnum, Zone: zone}
+ return &TCPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}
case "udp", "udp4", "udp6":
- return &UDPAddr{IP: ip, Port: portnum, Zone: zone}
+ return &UDPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}
case "ip", "ip4", "ip6":
- return &IPAddr{IP: ip, Zone: zone}
+ return &IPAddr{IP: ip.IP, Zone: ip.Zone}
default:
panic("unexpected network: " + net)
}
}
if host == "" {
- return inetaddr(nil), nil
+ return addrList{inetaddr(IPAddr{})}, nil
}
// Try as a literal IP address.
var ip IP
if ip = parseIPv4(host); ip != nil {
- return inetaddr(ip), nil
+ return addrList{inetaddr(IPAddr{IP: ip})}, nil
}
+ var zone string
if ip, zone = parseIPv6(host, true); ip != nil {
- return inetaddr(ip), nil
+ return addrList{inetaddr(IPAddr{IP: ip, Zone: zone})}, 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
+ var filter func(IPAddr) bool
if net != "" && net[len(net)-1] == '4' {
filter = ipv4only
}
- if net != "" && net[len(net)-1] == '6' || zone != "" {
+ if net != "" && net[len(net)-1] == '6' {
filter = ipv6only
}
- return firstFavoriteAddr(filter, ips, inetaddr)
+ return filterAddrList(filter, ips, inetaddr)
}
func zoneToString(zone int) string {
@@ -303,7 +270,7 @@ func zoneToString(zone int) string {
if ifi, err := InterfaceByIndex(zone); err == nil {
return ifi.Name
}
- return itod(uint(zone))
+ return uitoa(uint(zone))
}
func zoneToInt(zone string) int {