1
0
mirror of https://github.com/golang/go synced 2024-11-20 11:24:47 -07:00

net: more accurate IPv4-in-IPv6 API test

R=rsc
CC=golang-dev
https://golang.org/cl/4172045
This commit is contained in:
Mikio Hara 2011-02-16 15:05:48 -05:00 committed by Russ Cox
parent df4b22fcff
commit 9b66129fe3
2 changed files with 23 additions and 8 deletions

View File

@ -245,7 +245,7 @@ func hostToIP(host string) (ip IP, err os.Error) {
err = err1
goto Error
}
addr = ParseIP(addrs[0])
addr = firstSupportedAddr(addrs)
if addr == nil {
// should not happen
err = &AddrError{"LookupHost returned invalid address", addrs[0]}

View File

@ -18,19 +18,34 @@ import (
// Unfortunately, we need to run on kernels built without IPv6 support too.
// So probe the kernel to figure it out.
func kernelSupportsIPv6() bool {
// FreeBSD does not support this sort of interface.
if syscall.OS == "freebsd" {
s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
if err != 0 {
return false
}
fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
if fd >= 0 {
closesocket(fd)
defer closesocket(s)
la := &TCPAddr{IP: IPv4(127, 0, 0, 1)}
sa, oserr := la.toAddr().sockaddr(syscall.AF_INET6)
if oserr != nil {
return false
}
return e == 0
return syscall.Bind(s, sa) == 0
}
var preferIPv4 = !kernelSupportsIPv6()
func firstSupportedAddr(addrs []string) (addr IP) {
for _, s := range addrs {
addr = ParseIP(s)
if !preferIPv4 || addr.To4() != nil {
break
}
addr = nil
}
return addr
}
// TODO(rsc): if syscall.OS == "linux", we're supposd to read
// /proc/sys/net/core/somaxconn,
// to take advantage of kernels that have raised the limit.
@ -208,7 +223,7 @@ func hostPortToIP(net, hostport string) (ip IP, iport int, err os.Error) {
err = err1
goto Error
}
addr = ParseIP(addrs[0])
addr = firstSupportedAddr(addrs)
if addr == nil {
// should not happen
err = &AddrError{"LookupHost returned invalid address", addrs[0]}