1
0
mirror of https://github.com/golang/go synced 2024-11-25 10:07:56 -07:00

net: prefer an IPv4 listen if no address given

This CL avoids net.Listen("tcp", ":80"), http.ListenAdnServe(":80")
prefer an IPv6 listen.

R=rsc
CC=golang-dev
https://golang.org/cl/5669043
This commit is contained in:
Mikio Hara 2012-02-15 01:59:18 +09:00
parent 60e4d5668e
commit 6fbe80572e
3 changed files with 11 additions and 11 deletions

View File

@ -185,7 +185,7 @@ func Listen(net, laddr string) (Listener, error) {
if a != nil { if a != nil {
la = a.(*TCPAddr) la = a.(*TCPAddr)
} }
return ListenTCP(afnet, la) return ListenTCP(net, la)
case "unix", "unixpacket": case "unix", "unixpacket":
var la *UnixAddr var la *UnixAddr
if a != nil { if a != nil {

View File

@ -53,13 +53,13 @@ func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
} }
// favoriteAddrFamily returns the appropriate address family to // favoriteAddrFamily returns the appropriate address family to
// the given net, raddr, laddr and mode. At first it figures // the given net, laddr, raddr and mode. At first it figures
// address family out from the net. If mode indicates "listen" // address family out from the net. If mode indicates "listen"
// and laddr.(type).IP is nil, it assumes that the user wants to // and laddr.(type).IP is nil, it assumes that the user wants to
// make a passive connection with wildcard address family, both // make a passive connection with wildcard address family, both
// INET and INET6, and wildcard address. Otherwise guess: if the // INET and INET6, and wildcard address. Otherwise guess: if the
// addresses are IPv4 then returns INET, or else returns INET6. // addresses are IPv4 then returns INET, or else returns INET6.
func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int { func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) int {
switch net[len(net)-1] { switch net[len(net)-1] {
case '4': case '4':
return syscall.AF_INET return syscall.AF_INET
@ -68,17 +68,20 @@ func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int {
} }
if mode == "listen" { if mode == "listen" {
// Note that OpenBSD allows neither "net.inet6.ip6.v6only"
// change nor IPPROTO_IPV6 level IPV6_V6ONLY socket option
// setting.
switch a := laddr.(type) { switch a := laddr.(type) {
case *TCPAddr: case *TCPAddr:
if a.IP == nil && supportsIPv6 { if a.IP == nil && supportsIPv6 && supportsIPv4map {
return syscall.AF_INET6 return syscall.AF_INET6
} }
case *UDPAddr: case *UDPAddr:
if a.IP == nil && supportsIPv6 { if a.IP == nil && supportsIPv6 && supportsIPv4map {
return syscall.AF_INET6 return syscall.AF_INET6
} }
case *IPAddr: case *IPAddr:
if a.IP == nil && supportsIPv6 { if a.IP == nil && supportsIPv6 && supportsIPv4map {
return syscall.AF_INET6 return syscall.AF_INET6
} }
} }
@ -104,7 +107,7 @@ type sockaddr interface {
func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
var oserr error var oserr error
var la, ra syscall.Sockaddr var la, ra syscall.Sockaddr
family := favoriteAddrFamily(net, raddr, laddr, mode) family := favoriteAddrFamily(net, laddr, raddr, mode)
if laddr != nil { if laddr != nil {
if la, oserr = laddr.sockaddr(family); oserr != nil { if la, oserr = laddr.sockaddr(family); oserr != nil {
goto Error goto Error

View File

@ -115,16 +115,13 @@ func doTest(t *testing.T, network, listenaddr, dialaddr string) {
} }
func TestTCPServer(t *testing.T) { func TestTCPServer(t *testing.T) {
if runtime.GOOS != "openbsd" { doTest(t, "tcp", "", "127.0.0.1")
doTest(t, "tcp", "", "127.0.0.1")
}
doTest(t, "tcp", "0.0.0.0", "127.0.0.1") doTest(t, "tcp", "0.0.0.0", "127.0.0.1")
doTest(t, "tcp", "127.0.0.1", "127.0.0.1") doTest(t, "tcp", "127.0.0.1", "127.0.0.1")
doTest(t, "tcp4", "", "127.0.0.1") doTest(t, "tcp4", "", "127.0.0.1")
doTest(t, "tcp4", "0.0.0.0", "127.0.0.1") doTest(t, "tcp4", "0.0.0.0", "127.0.0.1")
doTest(t, "tcp4", "127.0.0.1", "127.0.0.1") doTest(t, "tcp4", "127.0.0.1", "127.0.0.1")
if supportsIPv6 { if supportsIPv6 {
doTest(t, "tcp", "", "[::1]")
doTest(t, "tcp", "[::]", "[::1]") doTest(t, "tcp", "[::]", "[::1]")
doTest(t, "tcp", "[::1]", "[::1]") doTest(t, "tcp", "[::1]", "[::1]")
doTest(t, "tcp6", "", "[::1]") doTest(t, "tcp6", "", "[::1]")