package  netimport  (	"context" 	"internal/poll" 	"os" 	"syscall" )func  socket ctx  context .Context , net  string , family , sotype , proto  int , ipv6only  bool , laddr , raddr  sockaddr , ctrlCtxFn  func (context .Context , string , string , syscall .RawConn ) error ) (fd  *netFD , err  error ) {	s , err  := sysSocket (family , sotype , proto )	if  err  != nil  {		return  nil , err 	}	if  err  = setDefaultSockopts (s , family , sotype , ipv6only ); err  != nil  {		poll .CloseFunc (s )		return  nil , err 	}	if  fd , err  = newFD (s , family , sotype , net ); err  != nil  {		poll .CloseFunc (s )		return  nil , err 	}		if  laddr  != nil  && raddr  == nil  {		switch  sotype  {		case  syscall .SOCK_STREAM , syscall .SOCK_SEQPACKET :			if  err  := fd .listenStream (ctx , laddr , listenerBacklog (), ctrlCtxFn ); err  != nil  {				fd .Close ()				return  nil , err 			}			return  fd , nil 		case  syscall .SOCK_DGRAM :			if  err  := fd .listenDatagram (ctx , laddr , ctrlCtxFn ); err  != nil  {				fd .Close ()				return  nil , err 			}			return  fd , nil 		}	}	if  err  := fd .dial (ctx , laddr , raddr , ctrlCtxFn ); err  != nil  {		fd .Close ()		return  nil , err 	}	return  fd , nil }func  (fd  *netFD ) ctrlNetwork string  {	switch  fd .net  {	case  "unix" , "unixgram" , "unixpacket" :		return  fd .net 	}	switch  fd .net [len (fd .net )-1 ] {	case  '4' , '6' :		return  fd .net 	}	if  fd .family  == syscall .AF_INET  {		return  fd .net  + "4" 	}	return  fd .net  + "6" }func  (fd  *netFD ) dial ctx  context .Context , laddr , raddr  sockaddr , ctrlCtxFn  func (context .Context , string , string , syscall .RawConn ) error ) error  {	var  c  *rawConn 	if  ctrlCtxFn  != nil  {		c  = newRawConn (fd )		var  ctrlAddr  string 		if  raddr  != nil  {			ctrlAddr  = raddr .String ()		} else  if  laddr  != nil  {			ctrlAddr  = laddr .String ()		}		if  err  := ctrlCtxFn (ctx , fd .ctrlNetwork (), ctrlAddr , c ); err  != nil  {			return  err 		}	}	var  lsa  syscall .Sockaddr 	var  err  error 	if  laddr  != nil  {		if  lsa , err  = laddr .sockaddr (fd .family ); err  != nil  {			return  err 		} else  if  lsa  != nil  {			if  err  = syscall .Bind (fd .pfd .Sysfd , lsa ); err  != nil  {				return  os .NewSyscallError ("bind" , err )			}		}	}	var  rsa  syscall .Sockaddr   	var  crsa  syscall .Sockaddr  	if  raddr  != nil  {		if  rsa , err  = raddr .sockaddr (fd .family ); err  != nil  {			return  err 		}		if  crsa , err  = fd .connect (ctx , lsa , rsa ); err  != nil  {			return  err 		}		fd .isConnected  = true 	} else  {		if  err  := fd .init (); err  != nil  {			return  err 		}	}		lsa , _ = syscall .Getsockname (fd .pfd .Sysfd )	if  crsa  != nil  {		fd .setAddr (fd .addrFunc ()(lsa ), fd .addrFunc ()(crsa ))	} else  if  rsa , _ = syscall .Getpeername (fd .pfd .Sysfd ); rsa  != nil  {		fd .setAddr (fd .addrFunc ()(lsa ), fd .addrFunc ()(rsa ))	} else  {		fd .setAddr (fd .addrFunc ()(lsa ), raddr )	}	return  nil }func  (fd  *netFD ) listenStream ctx  context .Context , laddr  sockaddr , backlog  int , ctrlCtxFn  func (context .Context , string , string , syscall .RawConn ) error ) error  {	var  err  error 	if  err  = setDefaultListenerSockopts (fd .pfd .Sysfd ); err  != nil  {		return  err 	}	var  lsa  syscall .Sockaddr 	if  lsa , err  = laddr .sockaddr (fd .family ); err  != nil  {		return  err 	}	if  ctrlCtxFn  != nil  {		c  := newRawConn (fd )		if  err  := ctrlCtxFn (ctx , fd .ctrlNetwork (), laddr .String (), c ); err  != nil  {			return  err 		}	}	if  err  = syscall .Bind (fd .pfd .Sysfd , lsa ); err  != nil  {		return  os .NewSyscallError ("bind" , err )	}	if  err  = listenFunc (fd .pfd .Sysfd , backlog ); err  != nil  {		return  os .NewSyscallError ("listen" , err )	}	if  err  = fd .init (); err  != nil  {		return  err 	}	lsa , _ = syscall .Getsockname (fd .pfd .Sysfd )	fd .setAddr (fd .addrFunc ()(lsa ), nil )	return  nil }func  (fd  *netFD ) listenDatagram ctx  context .Context , laddr  sockaddr , ctrlCtxFn  func (context .Context , string , string , syscall .RawConn ) error ) error  {	switch  addr := laddr .(type ) {	case  *UDPAddr :				if  addr .IP  != nil  && addr .IP .IsMulticast () {			if  err  := setDefaultMulticastSockopts (fd .pfd .Sysfd ); err  != nil  {				return  err 			}			addr  := *addr 			switch  fd .family  {			case  syscall .AF_INET :				addr .IP  = IPv4zero 			case  syscall .AF_INET6 :				addr .IP  = IPv6unspecified 			}			laddr  = &addr 		}	}	var  err  error 	var  lsa  syscall .Sockaddr 	if  lsa , err  = laddr .sockaddr (fd .family ); err  != nil  {		return  err 	}	if  ctrlCtxFn  != nil  {		c  := newRawConn (fd )		if  err  := ctrlCtxFn (ctx , fd .ctrlNetwork (), laddr .String (), c ); err  != nil  {			return  err 		}	}	if  err  = syscall .Bind (fd .pfd .Sysfd , lsa ); err  != nil  {		return  os .NewSyscallError ("bind" , err )	}	if  err  = fd .init (); err  != nil  {		return  err 	}	lsa , _ = syscall .Getsockname (fd .pfd .Sysfd )	fd .setAddr (fd .addrFunc ()(lsa ), nil )	return  nil } The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .