2010-05-21 18:30:40 -06:00
|
|
|
// Copyright 2010 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.
|
|
|
|
|
|
|
|
// (Raw) IP sockets
|
|
|
|
|
|
|
|
package net
|
|
|
|
|
2012-07-19 17:32:25 -06:00
|
|
|
// IPAddr represents the address of an IP end point.
|
2010-05-21 18:30:40 -06:00
|
|
|
type IPAddr struct {
|
|
|
|
IP IP
|
|
|
|
}
|
|
|
|
|
|
|
|
// Network returns the address's network name, "ip".
|
|
|
|
func (a *IPAddr) Network() string { return "ip" }
|
|
|
|
|
2010-07-27 01:22:22 -06:00
|
|
|
func (a *IPAddr) String() string {
|
|
|
|
if a == nil {
|
|
|
|
return "<nil>"
|
|
|
|
}
|
|
|
|
return a.IP.String()
|
|
|
|
}
|
2010-05-21 18:30:40 -06:00
|
|
|
|
2012-07-19 17:32:25 -06:00
|
|
|
// ResolveIPAddr parses addr as an IP address and resolves domain
|
2011-05-16 15:03:06 -06:00
|
|
|
// names to numeric addresses on the network net, which must be
|
|
|
|
// "ip", "ip4" or "ip6". A literal IPv6 host address must be
|
2010-05-21 18:30:40 -06:00
|
|
|
// enclosed in square brackets, as in "[::]".
|
2011-11-01 20:05:34 -06:00
|
|
|
func ResolveIPAddr(net, addr string) (*IPAddr, error) {
|
2011-05-16 15:03:06 -06:00
|
|
|
ip, err := hostToIP(net, addr)
|
2010-05-21 18:30:40 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &IPAddr{ip}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert "host" into IP address.
|
2011-11-01 20:05:34 -06:00
|
|
|
func hostToIP(net, host string) (ip IP, err error) {
|
2010-05-21 18:30:40 -06:00
|
|
|
var addr IP
|
|
|
|
// Try as an IP address.
|
|
|
|
addr = ParseIP(host)
|
|
|
|
if addr == nil {
|
2011-05-16 15:03:06 -06:00
|
|
|
filter := anyaddr
|
|
|
|
if net != "" && net[len(net)-1] == '4' {
|
|
|
|
filter = ipv4only
|
|
|
|
}
|
|
|
|
if net != "" && net[len(net)-1] == '6' {
|
|
|
|
filter = ipv6only
|
|
|
|
}
|
2010-05-21 18:30:40 -06:00
|
|
|
// Not an IP address. Try as a DNS name.
|
2011-03-28 21:28:42 -06:00
|
|
|
addrs, err1 := LookupHost(host)
|
2010-05-21 18:30:40 -06:00
|
|
|
if err1 != nil {
|
|
|
|
err = err1
|
|
|
|
goto Error
|
|
|
|
}
|
undo CL 4557058 / b4c2ffae7034
Using the getaddrinfo order is only okay if we
are smart enough to try multiple addresses in Dial.
Since the code does not do that, we must make
the right first choice, regardless of what getaddrinfo
does, and more often that not that means using the
IPv4 address, even on IPv6 systems. With the CL
applied, gotest fails in package net on OS X.
helix.cam=; gotest
...
--- FAIL: net.TestDialGoogleIPv4 (1.05 seconds)
-- 74.125.226.179:80 --
-- www.google.com:80 --
Dial("tcp", "", "www.google.com:80") = _, dial tcp [2001:4860:800f::69]:80: address family not supported by protocol family
-- 74.125.226.179:http --
-- www.google.com:http --
Dial("tcp", "", "www.google.com:http") = _, dial tcp [2001:4860:800f::69]:80: address family not supported by protocol family
-- 074.125.226.179:0080 --
-- [::ffff:74.125.226.179]:80 --
-- [::ffff:4a7d:e2b3]:80 --
-- [0:0:0:0:0000:ffff:74.125.226.179]:80 --
-- [0:0:0:0:000000:ffff:74.125.226.179]:80 --
-- [0:0:0:0:0:ffff::74.125.226.179]:80 --
FAIL
gotest: "./6.out" failed: exit status 1
««« original CL description
net: name-based destination address selection
getaddrinfo() orders the addresses according to RFC 3484.
This means when IPv6 is working on a host we get results like:
[]string = {"2001:4810::110", "66.117.47.214"}
and when it's not working we get:
[]string = {"66.117.47.214", "2001:4810::110"}
thus can drop firstFavoriteAddr.
This also means /etc/gai.conf works on relevant systems.
R=rsc, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/4557058
»»»
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/4532101
2011-06-01 13:49:57 -06:00
|
|
|
addr = firstFavoriteAddr(filter, addrs)
|
2010-05-21 18:30:40 -06:00
|
|
|
if addr == nil {
|
|
|
|
// should not happen
|
2011-05-16 15:03:06 -06:00
|
|
|
err = &AddrError{"LookupHost returned no suitable address", addrs[0]}
|
2010-05-21 18:30:40 -06:00
|
|
|
goto Error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return addr, nil
|
|
|
|
Error:
|
|
|
|
return nil, err
|
|
|
|
}
|