Documentation ¶
Index ¶
- Constants
- func AllLocalIps() (rv []net.IP, err error)
- func AllowIp4(ip net.IP) bool
- func AllowIp6(ip net.IP) bool
- func AllowIps(hosts []string) (filter func(net.IP) bool, err error)
- func AllowUnicastIps(ip net.IP) bool
- func AsSockaddr(ip net.IP, port int) (rv syscall.Sockaddr)
- func CmsgSetupMsghdr(msghdr *syscall.Msghdr, cmsgbuff []byte)
- func DenyLoopbackIps(ip net.IP) bool
- func DenyMulticastIps(ip net.IP) bool
- func DenyPrivateIps(ip net.IP) bool
- func FilterIps(filter ...func(net.IP) bool) func(net.IP) bool
- func FindLocalIps(allowIntfc func(net.Interface) bool, allowIp func(net.IP) bool) (rv []net.IP, err error)
- func GetSocketFd(conn *net.TCPConn) (fd int, f *os.File)
- func HelpDscp() string
- func Htonl(v uint32) (rv uint32)
- func Htons(v uint16) (rv uint16)
- func IsSockaddrPortOrIpZero(sa syscall.Sockaddr) bool
- func IsSockaddrValid(sa syscall.Sockaddr) bool
- func IsSockaddrZero(sa syscall.Sockaddr) bool
- func KnownDscpTosCode(code byte) bool
- func LookupDscpTos(value string) (code byte, err error)
- func MMsghdrsAsString(hdrs []MMsghdr) string
- func MeansClosed(err error) bool
- func NameBytesAsIpAndPort(name *byte, namelen uint32, ip *net.IP) (port int)
- func NameBytesAsSockaddr(name *byte, namelen uint32) (rv syscall.Sockaddr, err error)
- func NameBytesAsString(name *byte, namelen uint32) (rv string)
- func RawRecvMMsg(fd, hdrs, hdrslen uintptr) (messages int, err syscall.Errno)
- func RawSendMMsg(fd, hdrs, hdrslen uintptr) (nsent int, err syscall.Errno)
- func RawSockaddrAsNameBytes(sa syscall.Sockaddr, space []byte) (name *byte, namelen uint32, err error)
- func RecvMMsg(fd, hdrs, hdrslen uintptr) (messages int, err syscall.Errno)
- func RecvMsg(fd, msghdr, flags uintptr) (nread int, err syscall.Errno)
- func ResolveIp(hostOrIp string, timeout ...time.Duration) (rv net.IP, err error)
- func ResolveIps(hostOrIp string, timeout ...time.Duration) (rv []net.IP, err error)
- func ResolveNames(ip net.IP, timeout ...time.Duration) (rv []string, err error)
- func ResolveSockaddr(host string, port int, timeout ...time.Duration) (rv syscall.Sockaddr, err error)
- func ResolveTcp(hostOrIp string, port int, timeout ...time.Duration) (rv *net.TCPAddr, err error)
- func SendMMsg(fd, hdrs, hdrslen uintptr) (nsent int, err syscall.Errno)
- func SendMMsgRetry(fd uintptr, hdrs []MMsghdr, avail int) (retries int, err syscall.Errno)
- func SendMsg(fd, hdr, flags uintptr) (nsent int, err syscall.Errno)
- func SockaddrFamily(sa syscall.Sockaddr) (rv int, err error)
- func SockaddrHostPort(sa syscall.Sockaddr) string
- func SockaddrIP(sa syscall.Sockaddr) net.IP
- func SockaddrPort(sa syscall.Sockaddr) int
- func SysctlGet(item string) (rv int64, err error)
- func SysctlGetNetCoreRmemMax() (rv int64, err error)
- func SysctlGetNetCoreWmemMax() (rv int64, err error)
- func TestUnixSocketPair(t *testing.T)
- func ValidDscpTos(value string) (err error)
- func ValidDscpTosCode(code byte) (err error)
- func ValidIp(hostOrIp string) (err error)
- type Address
- func (this *Address) AsIp() (rv net.IP)
- func (this *Address) AsIpv4() (rv net.IP)
- func (this *Address) AsNameBytes(space []byte) (name *byte, namelen uint32)
- func (this *Address) AsSockaddr() (rv syscall.Sockaddr)
- func (this *Address) Clear()
- func (this *Address) ClearIp()
- func (this *Address) ClearPort()
- func (this *Address) FromCmsgHdr(cmsg *CmsgLens) (ok bool, err error)
- func (this *Address) FromHostPort(hostOrIp string, port uint16) (err error)
- func (this *Address) FromIpAndPort(ip net.IP, port uint16)
- func (this *Address) FromNameBytes(name *byte, namelen uint32)
- func (this *Address) FromSockaddr(sa syscall.Sockaddr)
- func (this *Address) Ip() (rv net.IP)
- func (this *Address) IsAny() bool
- func (this Address) IsEitherZero() bool
- func (this *Address) IsGlobalUnicast() bool
- func (this Address) IsIpSet() bool
- func (this Address) IsIpZero() bool
- func (this Address) IsIpv4() bool
- func (this Address) IsIpv4Zero() bool
- func (this Address) IsIpv6() bool
- func (this Address) IsIpv6Zero() bool
- func (this *Address) IsLoopback() bool
- func (this *Address) IsMulticast() bool
- func (this Address) IsPortSet() bool
- func (this *Address) IsPrivate() bool
- func (this Address) IsSet() bool
- func (this *Address) IsUnspecified() bool
- func (this Address) IsZero() bool
- func (this Address) Network() string
- func (this Address) Port() uint16
- func (this *Address) ResolveIp(hostOrIp string) (err error)
- func (this *Address) SetAddrFrom(that Address)
- func (this *Address) SetIp(ip net.IP)
- func (this *Address) SetIpFromNetIp(ip netip.Addr)
- func (this *Address) SetIpFromString(s string) (ok bool)
- func (this *Address) SetIpv4Zero()
- func (this *Address) SetIpv6Zero()
- func (this *Address) SetPort(port uint16)
- func (this Address) String() string
- func (this *Address) ToSockaddr4(sa *syscall.SockaddrInet4)
- func (this *Address) ToSockaddr6(sa *syscall.SockaddrInet6)
- type CmsgLens
- func (this *CmsgLens) First(msghdr *syscall.Msghdr) (ok bool)
- func (this *CmsgLens) IpError() (rv unix.SockExtendedErr, ok bool, err error)
- func (this *CmsgLens) IpErrorOffender(rv *Address) (ok bool)
- func (this *CmsgLens) IsIpError() bool
- func (this *CmsgLens) Level() int32
- func (this *CmsgLens) Msg() []byte
- func (this *CmsgLens) Next() (ok bool)
- func (this *CmsgLens) PktInfo(ipB net.IP) (rv net.IP, ok bool, err error)
- func (this *CmsgLens) Type() int32
- type IcmpHdr
- type IcmpV6Hdr
- type MMsghdr
- type ManagedFd
- func (this *ManagedFd) Acquire() (fd int, valid bool)
- func (this *ManagedFd) Clear()
- func (this *ManagedFd) Close() (closed bool, err error)
- func (this *ManagedFd) Disable() (shutdown bool)
- func (this *ManagedFd) Eject() (fd int, ok bool)
- func (this *ManagedFd) From(from *ManagedFd) (ok bool)
- func (this *ManagedFd) Get() (fd int, valid bool)
- func (this *ManagedFd) GetStatus() (open, disabled bool, count int)
- func (this *ManagedFd) IsClosed() (closed bool)
- func (this *ManagedFd) IsDisabled() (disabled bool)
- func (this *ManagedFd) IsDisabledOrClosed() (disabledOrClosed bool)
- func (this *ManagedFd) IsSet() bool
- func (this *ManagedFd) Release() (open, disabled bool, count int)
- func (this *ManagedFd) ReleaseAndDisableAndMaybeClose() (count int)
- func (this *ManagedFd) Set(fd int) (actuallySet bool)
- func (this *ManagedFd) ShutdownRead() (valid bool)
- type MtuDisco
- type MtuEchoer
- type MtuProber
- func (this *MtuProber) Close()
- func (this *MtuProber) NewCheckSock(src, dst Address) (err error)
- func (this *MtuProber) NewProbeSock(src, dst Address) (err error)
- func (this *MtuProber) Probe() (pmtu uint16, err error)
- func (this *MtuProber) SetCheckSock(sock *Socket)
- func (this *MtuProber) SetProbeSock(sock *Socket)
- type Polled
- type Poller
- func (this *Poller) Add(polled *Polled) (err error)
- func (this *Poller) AddControlPipe(onCntl func() (bool, error)) (err error)
- func (this *Poller) Close()
- func (this *Poller) IsStarted() bool
- func (this *Poller) NudgeControl() (err error)
- func (this *Poller) Open() (err error)
- func (this *Poller) Poll(millis int) (ok bool, err error)
- func (this *Poller) PollFor(timeout time.Duration) (ok bool, err error)
- func (this *Poller) PollForever() (ok bool, err error)
- func (this *Poller) Remove(polled *Polled) (err error)
- type SockOpt
- type Socket
- func (this *Socket) Accept(sock *Socket) (err error)
- func (this *Socket) Bind(unless ...bool) *Socket
- func (this *Socket) BindTo(host string, port int, unless ...bool) *Socket
- func (this *Socket) CancelDeadline()
- func (this *Socket) ClearTimeout() *Socket
- func (this *Socket) Close() error
- func (this *Socket) Connect(unless ...bool) *Socket
- func (this *Socket) Construct(sockType, proto int) *Socket
- func (this *Socket) ConstructFd(mfd *ManagedFd) *Socket
- func (this *Socket) ConstructTcp() *Socket
- func (this *Socket) ConstructUdp() *Socket
- func (this *Socket) ConstructUnix() *Socket
- func (this *Socket) Disable()
- func (this *Socket) Done() (s *Socket, err error)
- func (this *Socket) GetFarAddress(rv *Address) *Socket
- func (this *Socket) GetNearAddress(rv *Address) *Socket
- func (this *Socket) GetOptInt(layer, key int, value *int) *Socket
- func (this *Socket) GetOptMtu(mtu *int, unless ...bool) *Socket
- func (this *Socket) GetOptRcvBuf(size *int) *Socket
- func (this *Socket) GetOptSndBuf(size *int) *Socket
- func (this *Socket) GetPeerName(unless ...bool) *Socket
- func (this *Socket) GetSockName(unless ...bool) *Socket
- func (this *Socket) GiveMeTheFreakingFd(pfd *int) *Socket
- func (this *Socket) IpOverhead() (rv int)
- func (this *Socket) IsDisabled() bool
- func (this *Socket) IsIpv6() bool
- func (this *Socket) Listen(depth int, unless ...bool) *Socket
- func (this *Socket) LocalAddr() net.Addr
- func (this *Socket) Log(msg string, args ...any) *Socket
- func (this *Socket) ManageFd(managed *ManagedFd) *Socket
- func (this *Socket) Read(buff []byte) (nread int, err error)
- func (this *Socket) RecvFrom(buff []byte, flags int) (nread int, from syscall.Sockaddr, err error)
- func (this *Socket) RecvMsg(msghdr *syscall.Msghdr, flags int) (nread int, err error)
- func (this *Socket) RecvMsgCmsgDest(msghdr *syscall.Msghdr, addr *Address, flags int) (nread int, ok bool, err error)
- func (this *Socket) RemoteAddr() net.Addr
- func (this *Socket) Reset() *Socket
- func (this *Socket) ResolveFarAddr(host string, port int, unless ...bool) *Socket
- func (this *Socket) ResolveNearAddr(host string, port int, unless ...bool) *Socket
- func (this *Socket) Send(buff []byte, flags int) (err error)
- func (this *Socket) SendMsg(msghdr *syscall.Msghdr, flags int) (nsent int, err error)
- func (this *Socket) SendTo(buff []byte, flags int, to syscall.Sockaddr) (err error)
- func (this *Socket) SetDeadline(t time.Time) error
- func (this *Socket) SetFarAddr(far syscall.Sockaddr, unless ...bool) *Socket
- func (this *Socket) SetFarAddress(far Address, unless ...bool) *Socket
- func (this *Socket) SetFarIpPort(ip net.IP, port int, unless ...bool) *Socket
- func (this *Socket) SetFarUnix(path string, unless ...bool) *Socket
- func (this *Socket) SetNearAddr(near syscall.Sockaddr, unless ...bool) *Socket
- func (this *Socket) SetNearAddress(near Address, unless ...bool) *Socket
- func (this *Socket) SetNearIpPort(ip net.IP, port int, unless ...bool) *Socket
- func (this *Socket) SetNearUnix(path string, unless ...bool) *Socket
- func (this *Socket) SetOpt(opt SockOpt, unless ...bool) *Socket
- func (this *Socket) SetOptDscpTos(tos byte, unless ...bool) *Socket
- func (this *Socket) SetOptGso(size int, unless ...bool) *Socket
- func (this *Socket) SetOptInt(layer, key, value int, unless ...bool) *Socket
- func (this *Socket) SetOptKeepalive(tristate ...int) *Socket
- func (this *Socket) SetOptMtuDiscover(disco MtuDisco, unless ...bool) *Socket
- func (this *Socket) SetOptNoDelay(tristate ...int) *Socket
- func (this *Socket) SetOptRcvBuf(size int, unless ...bool) *Socket
- func (this *Socket) SetOptRcvTimeout(timeout time.Duration, unless ...bool) *Socket
- func (this *Socket) SetOptRecvPktInfo(tristate ...int) *Socket
- func (this *Socket) SetOptReuseAddr(tristate ...int) *Socket
- func (this *Socket) SetOptReusePort(tristate ...int) *Socket
- func (this *Socket) SetOptSndBuf(size int, unless ...bool) *Socket
- func (this *Socket) SetOptSndTimeout(timeout time.Duration, unless ...bool) *Socket
- func (this *Socket) SetOptTristate(layer, key int, tristate []int) *Socket
- func (this *Socket) SetReadDeadline(t time.Time) error
- func (this *Socket) SetTimeout(timeout time.Duration) *Socket
- func (this *Socket) SetWriteDeadline(t time.Time) error
- func (this *Socket) ShutdownRead() bool
- func (this *Socket) Temp(mfd ManagedFd) *Socket
- func (this *Socket) Then(thenF func(*Socket) error) *Socket
- func (this *Socket) Write(buff []byte) (nwrote int, err error)
- type UdpEndpoint
- func (this *UdpEndpoint) IovFiller(size int) func([]syscall.Iovec)
- func (this *UdpEndpoint) RecvMMsg(fd int) (messages int, err syscall.Errno)
- func (this *UdpEndpoint) RecvNamer() (name *byte, namelen uint32)
- func (this *UdpEndpoint) SendMMsgRetry(fd, n int) (retries int, err syscall.Errno)
- func (this *UdpEndpoint) SendNamer(dst syscall.Sockaddr, space []byte) (rv func() (*byte, uint32))
- func (this *UdpEndpoint) SetupVectors(messages, iovsPer int, iovFill func(iov []syscall.Iovec), ...)
Constants ¶
const ( InvalidIpv4Str = "192.0.2.1" // RFC5737 - for testing, 192.0.2.0/24 InvalidIpv6Str = "0100::1" // RFC6666 - for testing, 0100::/64 )
const ( // ICMP v4 types // // seen, for example, in unix.SockExtendedErr.Type ICMP_ECHOREPLY = 0 // Echo Reply ICMP_DEST_UNREACH = 3 // Destination Unreachable ICMP_SOURCE_QUENCH = 4 // Source Quench ICMP_REDIRECT = 5 // Redirect (change route) ICMP_ECHO = 8 // Echo Request ICMP_TIME_EXCEEDED = 11 // Time Exceeded ICMP_PARAMETERPROB = 12 // Parameter Problem ICMP_TIMESTAMP = 13 // Timestamp Request ICMP_TIMESTAMPREPLY = 14 // Timestamp Reply ICMP_INFO_REQUEST = 15 // Information Request ICMP_INFO_REPLY = 16 // Information Reply ICMP_ADDRESS = 17 // Address Mask Request ICMP_ADDRESSREPLY = 18 // Address Mask Reply NR_ICMP_TYPES = 18 // Codes for ICMP_DEST_UNREACH // seen, for example, in unix.SockExtendedErr.Code ICMP_NET_UNREACH = 0 // Network Unreachable ICMP_HOST_UNREACH = 1 // Host Unreachable ICMP_PROT_UNREACH = 2 // Protocol Unreachable ICMP_PORT_UNREACH = 3 // Port Unreachable ICMP_FRAG_NEEDED = 4 // Fragmentation Needed/DF set ICMP_SR_FAILED = 5 // Source Route failed ICMP_NET_UNKNOWN = 6 ICMP_HOST_UNKNOWN = 7 ICMP_HOST_ISOLATED = 8 ICMP_NET_ANO = 9 ICMP_HOST_ANO = 10 ICMP_NET_UNR_TOS = 11 ICMP_HOST_UNR_TOS = 12 ICMP_PKT_FILTERED = 13 // Packet filtered ICMP_PREC_VIOLATION = 14 // Precedence violation ICMP_PREC_CUTOFF = 15 // Precedence cut off NR_ICMP_UNREACH = 15 // instead of hardcoding immediate value // Codes for ICMP_REDIRECT ICMP_REDIR_NET = 0 // Redirect Net ICMP_REDIR_HOST = 1 // Redirect Host ICMP_REDIR_NETTOS = 2 // Redirect Net for TOS ICMP_REDIR_HOSTTOS = 3 // Redirect Host for TOS // Codes for ICMP_TIME_EXCEEDED ICMP_EXC_TTL = 0 // TTL count exceeded ICMP_EXC_FRAGTIME = 1 // Fragment Reass time exceeded )
see /usr/include/linux/icmp.h
const ( // ICMP v6 Types ICMPV6_DEST_UNREACH = 1 ICMPV6_PKT_TOOBIG = 2 ICMPV6_TIME_EXCEED = 3 ICMPV6_PARAMPROB = 4 ICMPV6_ECHO_REQUEST = 128 ICMPV6_ECHO_REPLY = 129 // codes for ICMPV6_DEST_UNREACH ICMPV6_NOROUTE = 0 ICMPV6_ADM_PROHIBITED = 1 ICMPV6_NOT_NEIGHBOUR = 2 ICMPV6_ADDR_UNREACH = 3 ICMPV6_PORT_UNREACH = 4 ICMPV6_POLICY_FAIL = 5 ICMPV6_REJECT_ROUTE = 6 // codes for ICMPV6_TIME_EXCEED ICMPV6_EXC_HOPLIMIT = 0 ICMPV6_EXC_FRAGTIME = 1 // codes for ICMPV6_PARAMPROB ICMPV6_HDR_FIELD = 0 ICMPV6_UNK_NEXTHDR = 1 ICMPV6_UNK_OPTION = 2 ICMPV6_HDR_INCOMP = 3 )
see /usr/include/linux/icmpv6.h
const ( MtuMinIpv4 = 576 // RFC 791, but RFC 4821 says 1024 is smallest practical MtuMinIpv6 = 1280 // RFC 2460 MtuMaxJumbo = 9216 // supported by most (all?) equipment, but 9000 common // // This one needs explanation. // // IPv4 has a 16 bit length field, but that includes the header and options. // The header is 20 bytes, so the payload is a max of 65515 bytes. // // UDP has a 16 bit length field, so it's max is 65535, but then the IPv4 header // added to that would be 65555! You probably only see something like this // for loopback, where likely there is no 'real' ipv4 header. // // Indeed, loopback often has mtu set at 65536. // // See also RFC 2675 (jumbograms), which talks about mtu of 65575 for // non-jumbograms! We don't support the notion of jumbograms here. // // However, with all that in mind, even with loopback mtu of 65536, the highest // probed value will be 65535! This makes sense since largest UDP datagram is // 65535. // MtuMax = 65535 )
const ( ErrNotInitialized = uerr.Const("Not initialized. Call Construct first.") ErrFdDisabled = uerr.Const("File descriptor disabled") ErrFdTransfer = uerr.Const("Could not transfer file descriptor") ErrAlreadyInitialized = uerr.Const("Already initialized") ErrNil = uerr.Const("sock is nil") )
const ( IP_OVERHEAD = 20 IP6_OVERHEAD = 40 // does not include extension headers UDP_OVERHEAD = 8 IPUDP_OVERHEAD = IP_OVERHEAD + UDP_OVERHEAD IP6UDP_OVERHEAD = IP6_OVERHEAD + UDP_OVERHEAD UDP_MAX = 65535 - IPUDP_OVERHEAD UDP_MAX_128 = 65408 // max mult of 128 JUMBO_MAX_128 = 8960 // max mult of 128 when MTU is 9001 )
some useful values
const ( SYS_RECVMMSG uintptr = 299 SYS_SENDMMSG uintptr = 307 )
from golang.org/x/sys/unix
const (
UDP_SEGMENT int = 103
)
from golang.org/x/sys/unix
Variables ¶
This section is empty.
Functions ¶
func AllLocalIps ¶
get a list of all IP addresses of all network interfaces
func AsSockaddr ¶
set ip/port to a Sockaddr for ipv4 or ipv6
func CmsgSetupMsghdr ¶
helper to setup msghdr for cmsghdrs before calling recvmsg
func FindLocalIps ¶
func FindLocalIps( allowIntfc func(net.Interface) bool, allowIp func(net.IP) bool, ) ( rv []net.IP, err error, )
get a list of the filtered IP addresses of the filtered network interfaces
setting either filter to nil means to accept all
func GetSocketFd ¶
get the underlying file descriptor from the socket. we also have to return the underlying os.File and the caller has to hold onto that or it will be gc'd and the fd will be unusable.
WARNING: after this call, setting deadlines (SetReadDeadline) on conn will no longer work! See: https://github.com/golang/go/issues/7605
NOTE: This call uses dup(), so there will be 2 file descriptors when done
func IsSockaddrPortOrIpZero ¶
func IsSockaddrValid ¶
func IsSockaddrZero ¶
func KnownDscpTosCode ¶
func LookupDscpTos ¶
DSCP / TOS value: can be one of the known DSCP types or just a numeric.
Valid values that all mean the same thing: - AF42 - by name - 144 - decimal - 0x90 - hex - 0o220 - octal - 0b10010000 - binary
func MMsghdrsAsString ¶
func MeansClosed ¶
does the error mean that the socket is closed?
this occurs when another goroutine in the same process has closed it to tell the guy using it to go away, like when the component is being turned off.
in some situations errors.Is(syscall.ECONNRESET) is also useful
func NameBytesAsIpAndPort ¶
Suitable for decoding Name and Namelen of syscall.Msghdr
NOTE: ip is set to the internal bytes of the name buffer
func NameBytesAsSockaddr ¶
Suitable for decoding Name and Namelen of syscall.Msghdr
func NameBytesAsString ¶
Suitable for decoding Name and Namelen of syscall.Msghdr
func RawSockaddrAsNameBytes ¶
func RawSockaddrAsNameBytes( sa syscall.Sockaddr, space []byte, ) ( name *byte, namelen uint32, err error, )
Suitable for creating Name and Namelen of syscall.Msghdr
space is necessary to reserve space for the sockaddr type. you must ensure that space is allocated on the heap and is sized appropriately (syscall.SizeofSockaddrInet6), or, if UNIX domain sockets: (syscall.SizeofSockaddrUnix),
func ResolveIps ¶
func ResolveSockaddr ¶
func ResolveSockaddr( host string, port int, timeout ...time.Duration, ) ( rv syscall.Sockaddr, err error, )
resolve host/port to a Sockaddr for ipv4 or ipv6
func ResolveTcp ¶
func SendMMsgRetry ¶
We are making syscall, so we need to take care that parameters we pass will not be gc'd or moved by gc. Easiest way to do that is to ensure that all values are on the heap.
this code is escape optimized
func SockaddrFamily ¶
get socket family of sockaddr
func SockaddrHostPort ¶
func SockaddrPort ¶
func SysctlGetNetCoreRmemMax ¶
func SysctlGetNetCoreWmemMax ¶
func TestUnixSocketPair ¶
func ValidDscpTosCode ¶
CS7 (0xe0) is the highest known dscp code, but since we operate on some strange networks, we allow values above that
Types ¶
type Address ¶
type Address struct {
// contains filtered or unexported fields
}
a struct that can hold either ipv4 or ipv6 address, plus port
suitable for using as a map key
the net.IP type is a slice, so cannot be used as a key in a map, etc.
When net.IP stores an ipv4 addr, it either does it in a 4 byte slice (uncommon) or as an ip4-in-ip6 address in a 16 bytes slice. That is:
::ffff:a.b.c.d
So, the ipv4 address is in the last 4 bytes of the slice, preceded by ffff.
We use the ip4-in-ip6 method to store all ipv4 as ipv6.
for ipv6, we currently do not support the zone id, as that is primarily for link local addresses, which are not of interest to us.
func ResolveAddrs ¶
func (*Address) AsNameBytes ¶
Pack addr into provided space, returning name and namelen that point into space. space must be on heap.
Use for syscall.Msghdr (sendmsg/recvmsg)
func (*Address) AsSockaddr ¶
allocate and populate a sockaddr based on this
func (*Address) FromCmsgHdr ¶
If current cmsghdr is IP_PKTINFO, then populate ip, otherwise return false
func (*Address) FromHostPort ¶
func (*Address) FromNameBytes ¶
see syscall.Msghdr (Name and Namelen fields)
func (*Address) FromSockaddr ¶
func (Address) IsEitherZero ¶
is either ip or port set as zeros? this is not the same as unset!
func (*Address) IsGlobalUnicast ¶
func (*Address) IsLoopback ¶
func (*Address) IsMulticast ¶
func (*Address) IsUnspecified ¶
func (Address) IsZero ¶
are both ip and port set as zeros? we also accept unset port as part of zero port this is not the same as unset!
func (*Address) ResolveIp ¶
try to parse hostOrIp, and then try to lookup hostOrIp if that fails. so, if hostOrIp is an IP addr, no lookup will occur
func (*Address) SetAddrFrom ¶
func (*Address) SetIpFromNetIp ¶
func (*Address) SetIpFromString ¶
if s represents an IP address, set from that
func (*Address) ToSockaddr4 ¶
func (this *Address) ToSockaddr4(sa *syscall.SockaddrInet4)
populate provided sockaddr based on this
func (*Address) ToSockaddr6 ¶
func (this *Address) ToSockaddr6(sa *syscall.SockaddrInet6)
populate provided sockaddr based on this
type CmsgLens ¶
type CmsgLens struct {
// contains filtered or unexported fields
}
a lens to examine Cmsghdr structs from recvmsg
func (*CmsgLens) IpError ¶
func (this *CmsgLens) IpError() (rv unix.SockExtendedErr, ok bool, err error)
if cmsg is extended error, get it
if rv.Errno == syscall.EMSGSIZE, then rv.Info contains MTU to use
see ip(7) of the linux man pages for more info about IP_RECVERR
see /usr/include/linux/errqueue.h
func (*CmsgLens) IpErrorOffender ¶
use after IpError() is successful to get source of error.
refer to SO_EE_OFFENDER() in ip(7) of linux man pages
type MMsghdr ¶
type MMsghdr struct { syscall.Msghdr // what to send NTransferred uint32 // returns number of bytes actually sent/received Pad_cgo_2 [4]byte // alignment }
must match layout of C struct mmsghdr
type ManagedFd ¶
type ManagedFd uint64
Manages a socket file descriptor (fd)
When a goroutine is using an fd, it may be blocked on it. When it is time for that goroutine to die, another goroutine will need to tell it. The safe way to do that is to shutdown the fd, which will unblock the goroutine, and then that goroutine can close the fd.
This allows that activity to be safely performed.
On Linux, fds are limited to 32 bits (see epoll interfaces). OS limits push that limit down quite a bit more.
NOTES:
When a TCP socket is shutdown, reads will return 0 bytes, so the reader needs to check IsDisabled upon getting 0 bytes.
When a TCP listen socket is shutdown, the goroutine waiting for connections will get an error (in the accept). IsDisabled should be checked.
When a UDP socket is shutdown, recvmmsg will return 1 message, but the first message will be 0 bytes. IsDisabled needs to be checked in this case.
States
Set Disable -----> [empty] -----> [open] --------> [open,shutdown,disabled] | ^ | | | | Close | | Close | +-----------+ | | | | Disable v +---------------------------> [disabled]
func (*ManagedFd) Clear ¶
func (this *ManagedFd) Clear()
dangerously clear all state - only use when you are *sure*
func (*ManagedFd) Close ¶
If the fd is open, close it. Preserve disabled state. If fd is not disabled, Set can be used to set the fd to a new value.
func (*ManagedFd) Disable ¶
disable the fd, returning true if this caused a shutdown
this is commonly used when a goroutine may be blocking on an fd, and another goroutine is trying to tell it that it is time to die. this provides that notification to the blocked goroutine, but keeps the fd open. this prevents the race condition where one goroutine closes a fd, and then a new connection is made that gets the same fd, and then the other goroutine that was using the fd now has an fd to the wrong thing
func (*ManagedFd) From ¶
Transfer state from other ManagedFd to this
On success, from will be cleared and this will contain the state.
On failure, both this and from will remain unchanged.
Failure is caused when this already has state.
func (*ManagedFd) GetStatus ¶
Get current status - is fd open? - is fd disabled? - current ref count
func (*ManagedFd) IsDisabled ¶
func (*ManagedFd) IsDisabledOrClosed ¶
func (*ManagedFd) ReleaseAndDisableAndMaybeClose ¶
remove a ref to this, disabling if not disabled, closing if count zero
func (*ManagedFd) Set ¶
set the file descriptor to be managed.
this will return false if the ManagedFd is disabled or already set
func (*ManagedFd) ShutdownRead ¶
shut down the read portion of the socket if it is valid.
this is commonly used when a goroutine may be blocking on an fd, and another goroutine is trying to tell it that it is time to die. this provides that notification to the blocked goroutine, but keeps the fd open. this prevents the race condition where one goroutine closes a fd, and then a new connection is made that gets the same fd, and then the other goroutine that was using the fd now has an fd to the wrong thing
type MtuDisco ¶
type MtuDisco int
MTU Discovery option
https://man7.org/linux/man-pages/man7/ip.7.html
/usr/include/bits/in.h
const ( MtuDiscoNone MtuDisco = 0 // unset (leave as system default) MtuDiscoDo MtuDisco = 1 // always set DF MtuDiscoDont MtuDisco = 2 // do not set DF MtuDiscoProbe MtuDisco = 3 // set DF, ignore path MTU MtuDiscoWant MtuDisco = 4 // fragment according to path MTU, or set DF MtuDiscoIntfc MtuDisco = 5 // always use intfc MTU, do not set DF, ignore icmp MtuDiscoOmit MtuDisco = 6 // Like MtuDiscoIntfc, but all pkts to be fragmented )
type MtuEchoer ¶
type MtuEchoer struct { // // if set, log output // Name string // // if set, called on receipt of each pkt // OnPacket func(pkt []byte, from syscall.Sockaddr) (err error) // contains filtered or unexported fields }
MTU discovery server - echos back pkts sent by MtuProber client
type MtuProber ¶
type MtuProber struct { // // if set, log output // Name string // // if set, interval between sending probes. Default 120ms // ProbeInterval time.Duration // // set this to create initial buffer, or one will be created w/o your help // OnStart func(size uint16) (space []byte) // // if set, is called to create pkt from space prior to each send. // // size is how many bytes pkt should be in length // BeforeSend func(size uint16, space []byte) (pkt []byte, err error) // // if set, is called after receiving each pkt // AfterRecv func(pkt []byte) (err error) // // if set, set smallest probe size. otherwise, smallest compliant will be used // MtuMin uint16 // // if set, set largest probe size. otherwise, reasonable max will be used // MtuMax uint16 // // Result: if non-zero, kernel cached PMTU value // CachedPmtu uint16 // // Result: detected/probed PMTU value // Pmtu uint16 // // Result: overhead of IP and UDP // Overhead uint16 // // Result: if BeforeSend and AfterRecv not set, this is computed // LatencyAvg time.Duration LatencyMin time.Duration LatencyMax time.Duration // contains filtered or unexported fields }
client side of MTU discovery - sends UDP probes and sees what happens
func (*MtuProber) NewCheckSock ¶
Create a new socket to be the check socket, used to query kernel pmtu table. If not set, then the probe socket will be used.
func (*MtuProber) NewProbeSock ¶
create a new socket to be the probe socket, used to send/recv probes.
func (*MtuProber) SetCheckSock ¶
set external socket to be used to query kernel pmtu must be constructed similarly to NewProbeSock sock.FarAddr must be set
func (*MtuProber) SetProbeSock ¶
set external socket to be used to send/recv probes sock should be connected, constructed similarly as per NewSock
type Polled ¶
type Polled struct { NearAddr Address // optional - use as lookup for OnInput Sock *Socket // // if set, call when socket hangup // OnHup func(p *Polled) (ok bool, err error) // // if set, call when input is ready on socket during Poll(). // // stop polling if !ok // OnInput func(p *Polled) (ok bool, err error) // // if set, call when error queue is ready on socket // OnErrorQ func(p *Polled) (ok bool, err error) // contains filtered or unexported fields }
type Poller ¶
type Poller struct {
// contains filtered or unexported fields
}
allows polling a socket for activity
func (*Poller) AddControlPipe ¶
if other threads need to tell this thread (the one running Poller) things, then use this to add a control pipe to activate your supplied callback
func (*Poller) Close ¶
func (this *Poller) Close()
must be called by thread running Poller to cause close from another thread, send a cntl message
func (*Poller) NudgeControl ¶
if other threads need to tell the thread running Poller things send a nudge. the actual message should be in a chan or something.
func (*Poller) Poll ¶
Poll, waiting up to millis (-1 if forever) for input Returning false if a callback returned false
func (*Poller) PollForever ¶
Poll forever (or until stopped) Returning false if callback returned false
type Socket ¶
type Socket struct { Fd ManagedFd FarAddr syscall.Sockaddr NearAddr syscall.Sockaddr Error error // contains filtered or unexported fields }
Enable reasonable access to the Berkeley socket API.
needed when golang does not allow in high level interface, or for things like setting socket options before bind.
implements net.Conn, io.Closer, io.Reader, io.Writer
sock, err := NewSocket(). ResolveFarAddr(host, port). ConstructTcp(). SetTimeout(7*time.Second). Connect(). Done()
func NewSocketPair ¶
create a pair of UNIX domain sockets
func (*Socket) Bind ¶
see https://idea.popcount.org/2014-04-03-bind-before-connect/
func (*Socket) CancelDeadline ¶
func (this *Socket) CancelDeadline()
func (*Socket) ClearTimeout ¶
func (this *Socket) ClearTimeout(timeout time.Duration) *Socket {
func (*Socket) ConstructFd ¶
construct Socket from provided mfd, transferring state from mfd to this.
if transfer of state fails, then fd will be closed
func (*Socket) ConstructTcp ¶
func (*Socket) ConstructUdp ¶
func (*Socket) ConstructUnix ¶
func (*Socket) GetFarAddress ¶
func (*Socket) GetNearAddress ¶
func (*Socket) GetOptMtu ¶
If socket is connected, can get the MTU with this, which will either be the MTU of the interface, or the path MTU (PMTU) discovered from ICMP and cached in the kernel.
Especially handy after EMSGSIZE.
func (*Socket) GetOptRcvBuf ¶
func (*Socket) GetOptSndBuf ¶
func (*Socket) GetPeerName ¶
func (*Socket) GetSockName ¶
func (*Socket) GiveMeTheFreakingFd ¶
really just for test situations
func (*Socket) IpOverhead ¶
func (*Socket) IsDisabled ¶
func (*Socket) ManageFd ¶
safely transfer the internal fd to managed, if managed not nil or already set
func (*Socket) RecvFrom ¶
func (this *Socket) RecvFrom( buff []byte, flags int, ) ( nread int, from syscall.Sockaddr, err error, )
wrapper for go syscall, which require alloc of from on each recv useful for simple, non-performant cases
func (*Socket) RecvMsgCmsgDest ¶
func (this *Socket) RecvMsgCmsgDest( msghdr *syscall.Msghdr, addr *Address, flags int, ) ( nread int, ok bool, err error, )
same as recvmsg, but also gets the address that pkt was received on via cmsg
SetOptRecvPktInfo must be set to on for the cmsg info to be there!
func (*Socket) RemoteAddr ¶
func (*Socket) ResolveFarAddr ¶
func (*Socket) ResolveNearAddr ¶
func (*Socket) SetDeadline ¶
set a zero deadline to cancel deadline
func (*Socket) SetFarAddr ¶
func (*Socket) SetFarAddress ¶
func (*Socket) SetFarIpPort ¶
func (*Socket) SetNearAddr ¶
func (*Socket) SetNearAddress ¶
if near is not set, then will be set to 0.0.0.0:0
func (*Socket) SetNearIpPort ¶
func (*Socket) SetOptDscpTos ¶
set IP DSCP / TOS (priority) bits.
func (*Socket) SetOptGso ¶
About GSO (generic segment offload):
https://blog.cloudflare.com/accelerating-udp-packet-transmission-for-quic/
kernel 4.18+ is required.
We have not tested with kernel 4.x, but have tested with 5.4+.
This feature can be controlled using the UDP_SEGMENT socket option:
setsockopt(fd, SOL_UDP, UDP_SEGMENT, &gso_size, sizeof(gso_size)))
As well as via ancillary data, to control segmentation for each sendmsg() call:
cm = CMSG_FIRSTHDR(&msg); cm->cmsg_level = SOL_UDP; cm->cmsg_type = UDP_SEGMENT; cm->cmsg_len = CMSG_LEN(sizeof(uint15_t)); *((uint15_t *) CMSG_DATA(cm)) = gso_size;
Where gso_size is the size of each segment that form the "super buffer" passed to the kernel from the application. Once configured, the application can provide one contiguous large buffer containing a number of packets of gso_size length (as well as a final smaller packet), that will then be segmented by the kernel (or the NIC if hardware segmentation offloading is supported and enabled).
func (*Socket) SetOptKeepalive ¶
default to 'on'. if specified, values are 0 (off), 1 (on) - any other value is 'no change'
func (*Socket) SetOptMtuDiscover ¶
func (*Socket) SetOptNoDelay ¶
turn off/on Nagle algorithm (OS usually has this on by default) default to 'on'. if specified, values are 0 (off), 1 (on) - any other value is 'no change'
func (*Socket) SetOptRcvTimeout ¶
set SO_RCVTIMEO on socket if timeout is positive
func (*Socket) SetOptRecvPktInfo ¶
for recvmsg/recvmmsg, allow receipt of cmsghdr
default to 'on'. if specified, values are 0 (off), 1 (on) - any other value is 'no change'
func (*Socket) SetOptReuseAddr ¶
must be before bind
default to 'on'. if specified, values are 0 (off), 1 (on) - any other value is 'no change'
see https://idea.popcount.org/2014-04-03-bind-before-connect/
func (*Socket) SetOptReusePort ¶
must be before bind
default to 'on'. if specified, values are 0 (off), 1 (on) - any other value is 'no change'
func (*Socket) SetOptSndTimeout ¶
set SO_SNDTIMEO on socket if timeout is positive
func (*Socket) SetOptTristate ¶
func (*Socket) ShutdownRead ¶
type UdpEndpoint ¶
type UdpEndpoint struct { Iov []syscall.Iovec // must be on heap, so keep here Hdrs []MMsghdr // must be on heap, so keep here }
enables use of recvmmsg and sendmmsg system calls
func (*UdpEndpoint) IovFiller ¶
func (this *UdpEndpoint) IovFiller(size int) func([]syscall.Iovec)
returns a func that is suitable for use with SetupVector
func (*UdpEndpoint) RecvMMsg ¶
func (this *UdpEndpoint) RecvMMsg(fd int) (messages int, err syscall.Errno)
receive messages from fd
after this call, you will need to: - loop thru the messages and process them - for each message, reset NTranferred back to 0 - (optionally) provide new buffers for the iovs used (if not reusing them)
this code is escape optimized
func (*UdpEndpoint) RecvNamer ¶
func (this *UdpEndpoint) RecvNamer() (name *byte, namelen uint32)
suitable as nameFill parameter for receiving endpoints
func (*UdpEndpoint) SendMMsgRetry ¶
func (this *UdpEndpoint) SendMMsgRetry(fd, n int) (retries int, err syscall.Errno)
send n messages (previously set up in Hdrs) on fd
func (*UdpEndpoint) SendNamer ¶
func (this *UdpEndpoint) SendNamer( dst syscall.Sockaddr, space []byte, ) ( rv func() (*byte, uint32), )
suitable to create function for nameFill parameter of sending endpoints where all packets will go to the same place.
The space param needs to point to heap storage and be at least 28 bytes.
func (*UdpEndpoint) SetupVectors ¶
func (this *UdpEndpoint) SetupVectors( messages, iovsPer int, iovFill func(iov []syscall.Iovec), nameFill func() (name *byte, namelen uint32), )
setup the initial vectors.
for sending, name should be set. for receiving, name should be nil.
if iovFill is nil, then it is up to you to later do that.
if nameFill is nil, then name and namelen will be left empty. This is a good option for connected datagram sockets.