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 linux netbsd openbsd solaris windows

package net

import (
	
	
	
	
)
socket returns a network file descriptor that is ready for asynchronous I/O using the network poller.
func ( context.Context,  string, , ,  int,  bool, ,  sockaddr,  func(string, string, syscall.RawConn) error) ( *netFD,  error) {
	,  := sysSocket(, , )
	if  != nil {
		return nil, 
	}
	if  = setDefaultSockopts(, , , );  != nil {
		poll.CloseFunc()
		return nil, 
	}
	if ,  = newFD(, , , );  != nil {
		poll.CloseFunc()
		return nil, 
	}
This function makes a network file descriptor for the following applications: - An endpoint holder that opens a passive stream connection, known as a stream listener - An endpoint holder that opens a destination-unspecific datagram connection, known as a datagram listener - An endpoint holder that opens an active stream or a destination-specific datagram connection, known as a dialer - An endpoint holder that opens the other connection, such as talking to the protocol stack inside the kernel For stream and datagram listeners, they will only require named sockets, so we can assume that it's just a request from stream or datagram listeners when laddr is not nil but raddr is nil. Otherwise we assume it's just for dialers or the other connection holders.

	if  != nil &&  == nil {
		switch  {
		case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
			if  := .listenStream(, listenerBacklog(), );  != nil {
				.Close()
				return nil, 
			}
			return , nil
		case syscall.SOCK_DGRAM:
			if  := .listenDatagram(, );  != nil {
				.Close()
				return nil, 
			}
			return , nil
		}
	}
	if  := .dial(, , , );  != nil {
		.Close()
		return nil, 
	}
	return , nil
}

func ( *netFD) () string {
	switch .net {
	case "unix", "unixgram", "unixpacket":
		return .net
	}
	switch .net[len(.net)-1] {
	case '4', '6':
		return .net
	}
	if .family == syscall.AF_INET {
		return .net + "4"
	}
	return .net + "6"
}

func ( *netFD) () func(syscall.Sockaddr) Addr {
	switch .family {
	case syscall.AF_INET, syscall.AF_INET6:
		switch .sotype {
		case syscall.SOCK_STREAM:
			return sockaddrToTCP
		case syscall.SOCK_DGRAM:
			return sockaddrToUDP
		case syscall.SOCK_RAW:
			return sockaddrToIP
		}
	case syscall.AF_UNIX:
		switch .sotype {
		case syscall.SOCK_STREAM:
			return sockaddrToUnix
		case syscall.SOCK_DGRAM:
			return sockaddrToUnixgram
		case syscall.SOCK_SEQPACKET:
			return sockaddrToUnixpacket
		}
	}
	return func(syscall.Sockaddr) Addr { return nil }
}

func ( *netFD) ( context.Context, ,  sockaddr,  func(string, string, syscall.RawConn) error) error {
	if  != nil {
		,  := newRawConn()
		if  != nil {
			return 
		}
		var  string
		if  != nil {
			 = .String()
		} else if  != nil {
			 = .String()
		}
		if  := (.ctrlNetwork(), , );  != nil {
			return 
		}
	}
	var  error
	var  syscall.Sockaddr
	if  != nil {
		if ,  = .sockaddr(.family);  != nil {
			return 
		} else if  != nil {
			if  = syscall.Bind(.pfd.Sysfd, );  != nil {
				return os.NewSyscallError("bind", )
			}
		}
	}
	var  syscall.Sockaddr  // remote address from the user
	var  syscall.Sockaddr // remote address we actually connected to
	if  != nil {
		if ,  = .sockaddr(.family);  != nil {
			return 
		}
		if ,  = .connect(, , );  != nil {
			return 
		}
		.isConnected = true
	} else {
		if  := .init();  != nil {
			return 
		}
Record the local and remote addresses from the actual socket. Get the local address by calling Getsockname. For the remote address, use 1) the one returned by the connect method, if any; or 2) the one from Getpeername, if it succeeds; or 3) the one passed to us as the raddr parameter.
	, _ = syscall.Getsockname(.pfd.Sysfd)
	if  != nil {
		.setAddr(.addrFunc()(), .addrFunc()())
	} else if , _ = syscall.Getpeername(.pfd.Sysfd);  != nil {
		.setAddr(.addrFunc()(), .addrFunc()())
	} else {
		.setAddr(.addrFunc()(), )
	}
	return nil
}

func ( *netFD) ( sockaddr,  int,  func(string, string, syscall.RawConn) error) error {
	var  error
	if  = setDefaultListenerSockopts(.pfd.Sysfd);  != nil {
		return 
	}
	var  syscall.Sockaddr
	if ,  = .sockaddr(.family);  != nil {
		return 
	}
	if  != nil {
		,  := newRawConn()
		if  != nil {
			return 
		}
		if  := (.ctrlNetwork(), .String(), );  != nil {
			return 
		}
	}
	if  = syscall.Bind(.pfd.Sysfd, );  != nil {
		return os.NewSyscallError("bind", )
	}
	if  = listenFunc(.pfd.Sysfd, );  != nil {
		return os.NewSyscallError("listen", )
	}
	if  = .init();  != nil {
		return 
	}
	, _ = syscall.Getsockname(.pfd.Sysfd)
	.setAddr(.addrFunc()(), nil)
	return nil
}

func ( *netFD) ( sockaddr,  func(string, string, syscall.RawConn) error) error {
	switch addr := .(type) {
We provide a socket that listens to a wildcard address with reusable UDP port when the given laddr is an appropriate UDP multicast address prefix. This makes it possible for a single UDP listener to join multiple different group addresses, for multiple UDP listeners that listen on the same UDP port to join the same group address.
		if .IP != nil && .IP.IsMulticast() {
			if  := setDefaultMulticastSockopts(.pfd.Sysfd);  != nil {
				return 
			}
			 := *
			switch .family {
			case syscall.AF_INET:
				.IP = IPv4zero
			case syscall.AF_INET6:
				.IP = IPv6unspecified
			}
			 = &
		}
	}
	var  error
	var  syscall.Sockaddr
	if ,  = .sockaddr(.family);  != nil {
		return 
	}
	if  != nil {
		,  := newRawConn()
		if  != nil {
			return 
		}
		if  := (.ctrlNetwork(), .String(), );  != nil {
			return 
		}
	}
	if  = syscall.Bind(.pfd.Sysfd, );  != nil {
		return os.NewSyscallError("bind", )
	}
	if  = .init();  != nil {
		return 
	}
	, _ = syscall.Getsockname(.pfd.Sysfd)
	.setAddr(.addrFunc()(), nil)
	return nil