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.
+build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows

package net

import (
	
	
	
	
)
Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication capabilities which are controlled by the IPV6_V6ONLY socket option and kernel configuration. Should we try to use the IPv4 socket interface if we're only dealing with IPv4 sockets? As long as the host system understands IPv4-mapped IPv6, it's okay to pass IPv4-mapeed IPv6 addresses to the IPv6 interface. That simplifies our code and is most general. Unfortunately, we need to run on kernels built without IPv6 support too. So probe the kernel to figure it out.
func ( *ipStackCapabilities) () {
	,  := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
	switch  {
	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
	case nil:
		poll.CloseFunc()
		.ipv4Enabled = true
	}
	var  = []struct {
		 TCPAddr
		 int
IPv6 communication capability
IPv4-mapped IPv6 address communication capability
		{: TCPAddr{IP: IPv4(127, 0, 0, 1)}, : 0},
	}
	switch runtime.GOOS {
The latest DragonFly BSD and OpenBSD kernels don't support IPV6_V6ONLY=0. They always return an error and we don't need to probe the capability.
		 = [:1]
	}
	for  := range  {
		,  := sysSocket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
		if  != nil {
			continue
		}
		defer poll.CloseFunc()
		syscall.SetsockoptInt(, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, [].)
		,  := []..sockaddr(syscall.AF_INET6)
		if  != nil {
			continue
		}
		if  := syscall.Bind(, );  != nil {
			continue
		}
		if  == 0 {
			.ipv6Enabled = true
		} else {
			.ipv4MappedIPv6Enabled = true
		}
	}
}
favoriteAddrFamily returns the appropriate address family for the given network, laddr, raddr and mode. If mode indicates "listen" and laddr is a wildcard, we assume that the user wants to make a passive-open connection with a wildcard address family, both AF_INET and AF_INET6, and a wildcard address like the following: - A listen for a wildcard communication domain, "tcp" or "udp", with a wildcard address: If the platform supports both IPv6 and IPv4-mapped IPv6 communication capabilities, or does not support IPv4, we use a dual stack, AF_INET6 and IPV6_V6ONLY=0, wildcard address listen. The dual stack wildcard address listen may fall back to an IPv6-only, AF_INET6 and IPV6_V6ONLY=1, wildcard address listen. Otherwise we prefer an IPv4-only, AF_INET, wildcard address listen. - A listen for a wildcard communication domain, "tcp" or "udp", with an IPv4 wildcard address: same as above. - A listen for a wildcard communication domain, "tcp" or "udp", with an IPv6 wildcard address: same as above. - A listen for an IPv4 communication domain, "tcp4" or "udp4", with an IPv4 wildcard address: We use an IPv4-only, AF_INET, wildcard address listen. - A listen for an IPv6 communication domain, "tcp6" or "udp6", with an IPv6 wildcard address: We use an IPv6-only, AF_INET6 and IPV6_V6ONLY=1, wildcard address listen. Otherwise guess: If the addresses are IPv4 then returns AF_INET, or else returns AF_INET6. It also returns a boolean value what designates IPV6_V6ONLY option. Note that the latest DragonFly BSD and OpenBSD kernels allow neither "net.inet6.ip6.v6only=1" change nor IPPROTO_IPV6 level IPV6_V6ONLY socket option setting.
func ( string, ,  sockaddr,  string) ( int,  bool) {
	switch [len()-1] {
	case '4':
		return syscall.AF_INET, false
	case '6':
		return syscall.AF_INET6, true
	}

	if  == "listen" && ( == nil || .isWildcard()) {
		if supportsIPv4map() || !supportsIPv4() {
			return syscall.AF_INET6, false
		}
		if  == nil {
			return syscall.AF_INET, false
		}
		return .family(), false
	}

	if ( == nil || .family() == syscall.AF_INET) &&
		( == nil || .family() == syscall.AF_INET) {
		return syscall.AF_INET, false
	}
	return syscall.AF_INET6, false
}

func ( context.Context,  string, ,  sockaddr, ,  int,  string,  func(string, string, syscall.RawConn) error) ( *netFD,  error) {
	if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd") &&  == "dial" && .isWildcard() {
		 = .toLocal()
	}
	,  := favoriteAddrFamily(, , , )
	return socket(, , , , , , , , )
}

func ( int,  IP,  int,  string) (syscall.Sockaddr, error) {
	switch  {
	case syscall.AF_INET:
		if len() == 0 {
			 = IPv4zero
		}
		 := .To4()
		if  == nil {
			return nil, &AddrError{Err: "non-IPv4 address", Addr: .String()}
		}
		 := &syscall.SockaddrInet4{Port: }
		copy(.Addr[:], )
		return , nil
In general, an IP wildcard address, which is either "0.0.0.0" or "::", means the entire IP addressing space. For some historical reason, it is used to specify "any available address" on some operations of IP node. When the IP node supports IPv4-mapped IPv6 address, we allow a listener to listen to the wildcard address of both IP addressing spaces by specifying IPv6 wildcard address.
		if len() == 0 || .Equal(IPv4zero) {
			 = IPv6zero
We accept any IPv6 address including IPv4-mapped IPv6 address.
		 := .To16()
		if  == nil {
			return nil, &AddrError{Err: "non-IPv6 address", Addr: .String()}
		}
		 := &syscall.SockaddrInet6{Port: , ZoneId: uint32(zoneCache.index())}
		copy(.Addr[:], )
		return , nil
	}
	return nil, &AddrError{Err: "invalid address family", Addr: .String()}