package net
import (
)
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,
}
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
var syscall.Sockaddr
if != nil {
if , = .sockaddr(.family); != nil {
return
}
if , = .connect(, , ); != nil {
return
}
.isConnected = true
} else {
if := .init(); != nil {
return
}
}
, _ = 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) {
case *UDPAddr:
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
}