core/net
net
Types
62Accept_Error
Accept_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket, or options.
Invalid_Argument = 3,
// The given socket does not support accepting connections.
Unsupported_Socket = 4,
// accept called on a socket which is not listening.
Not_Listening = 5,
// A connection arrived but was closed while in the listen queue.
Aborted = 6,
// Timed out before being able to accept a connection.
Timeout = 7,
// Non-blocking socket that would need to block waiting for a connection.
Would_Block = 8,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 9,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 10,
}SourceAddress
Address :: union {
IP4_Address,
IP6_Address,
}SourceAddress_Duplication
Address_Duplication :: enum i32 {
Invalid = 0,
Tentative = 1,
Duplicate = 2,
Deprecated = 3,
Preferred = 4,
}SourceAddress_Family
Address_Family :: enum int {
IP4 = 0,
IP6 = 1,
}SourceAny_Socket
Any_Socket :: union {
TCP_Socket,
UDP_Socket,
}SourceBind_Error
Bind_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket or endpoint, or invalid combination of the two.
Invalid_Argument = 3,
// The socket is already bound to an address.
Already_Bound = 4,
// The address is protected and the current user has insufficient permissions to access it.
Insufficient_Permissions_For_Address = 5,
// The address is already in use.
Address_In_Use = 6,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 7,
}SourceCreate_Socket_Error
Create_Socket_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid/unsupported family or protocol.
Invalid_Argument = 3,
// The user has no permission to create a socket of this type and/or protocol.
Insufficient_Permissions = 4,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 5,
}SourceDNS_Configuration
DNS_Configuration :: struct {
// Configuration files.
resolv_conf: string,
hosts_file: string,
resolv_conf_buf: [128]u8,
hosts_file_buf: [128]u8,
// TODO: Allow loading these up with `reload_configuration()` call or the like,
// so we don't have to do it each call.
name_servers: []Endpoint,
hosts_file_entries: []DNS_Record,
}SourceDNS DEFINITIONS
DNS_Error
DNS_Error :: enum u32 {
None = 0,
Invalid_Hostname_Error = 1,
Invalid_Hosts_Config_Error = 2,
Invalid_Resolv_Config_Error = 3,
Connection_Error = 4,
Server_Error = 5,
System_Error = 6,
}SourceDNS_Header
DNS_Header :: struct {
id: u16be,
is_response: bool,
opcode: u16be,
is_authoritative: bool,
is_truncated: bool,
is_recursion_desired: bool,
is_recursion_available: bool,
response_code: DNS_Response_Code,
}SourceDNS_Host_Entry
DNS_Host_Entry :: struct {
name: string,
addr: Address,
}SourceDNS_Query
DNS_Query :: enum u16be {
Host_Address = 1,
Authoritative_Name_Server = 2,
Mail_Destination = 3,
Mail_Forwarder = 4,
CNAME = 5,
All = 255,
}SourceDNS_Record
DNS_Record :: union {
DNS_Record_IP4,
DNS_Record_IP6,
DNS_Record_CNAME,
DNS_Record_TXT,
DNS_Record_NS,
DNS_Record_MX,
DNS_Record_SRV,
}SourceDNS_Record_Base
DNS_Record_Base :: struct {
record_name: string,
ttl_seconds: u32,
}SourceBase DNS Record. All DNS responses will carry a hostname and TTL (time to live) field.
DNS_Record_CNAME
DNS_Record_CNAME :: struct {
base: DNS_Record_Base,
host_name: string,
}SourceAnother domain name that the domain name maps to.
Domains can be pointed to another domain instead of directly to an IP address.
`get_dns_records` will recursively follow these if you request this type of record.DNS_Record_Header
DNS_Record_Header :: struct #packed {
type: u16be,
class: u16be,
ttl: u32be,
length: u16be,
}SourceDNS_Record_IP4
DNS_Record_IP4 :: struct {
base: DNS_Record_Base,
address: IP4_Address,
}SourceAn IP4 address that the domain name maps to. There can be any number of these.
DNS_Record_IP6
DNS_Record_IP6 :: struct {
base: DNS_Record_Base,
address: IP6_Address,
}SourceAn IPv6 address that the domain name maps to. There can be any number of these.
DNS_Record_MX
DNS_Record_MX :: struct {
base: DNS_Record_Base,
host_name: string,
preference: int,
}SourceDomain names for email servers that are associated with the domain name. These records also have values which ranks them in the order they should be preferred. Lower is more-preferred.
DNS_Record_NS
DNS_Record_NS :: struct {
base: DNS_Record_Base,
host_name: string,
}SourceDomain names of other DNS servers that are associated with the domain name.
TODO(tetra): Expand on what these records are used for, and when you should use pay attention to these.DNS_Record_SRV
DNS_Record_SRV :: struct {
// base contains the full name of this record.
// e.g: _sip._tls.example.com
base: DNS_Record_Base,
// The hostname or address where this service can be found.
target: string,
// The port on which this service can be found.
port: int,
service_name: string,
protocol_name: string,
// Lower is higher priority
priority: int,
// Relative weight of this host compared to other of same priority; the chance of using this host should be proporitional to this weight.
// The number of seconds that it will take to update the record.
weight: int,
}SourceAn endpoint for a service that is available through the domain name.
This is the way to discover the services that a domain name provides.
Clients MUST attempt to contact the host with the lowest priority that they can reach.
If two hosts have the same priority, they should be contacted in the order according to their weight.
Hosts with larger weights should have a proportionally higher chance of being contacted by clients.
A weight of zero indicates a very low weight, or, when there is no choice (to reduce visual noise).
The host may be "." to indicate that it is "decidedly not available" on this domain.DNS_Record_TXT
DNS_Record_TXT :: struct {
base: DNS_Record_Base,
value: string,
}SourceArbitrary string data that is associated with the domain name.
Commonly of the form `key=value` to be parsed, though there is no specific format for them.
These can be used for any purpose.DNS_Record_Type
DNS_Record_Type :: enum u16 {
DNS_TYPE_A = 1, // IP4 address.
DNS_TYPE_NS = 2, // IP6 address.
DNS_TYPE_CNAME = 5, // Another host name.
DNS_TYPE_MX = 15, // Arbitrary binary data or text.
DNS_TYPE_AAAA = 28, // Address of a name (DNS) server.
DNS_TYPE_TEXT = 16, // Address and preference priority of a mail exchange server.
DNS_TYPE_SRV = 33, // Address, port, priority, and weight of a host that provides a particular service.
IP4 = DNS_TYPE_A,
IP6 = DNS_TYPE_AAAA,
CNAME = DNS_TYPE_CNAME,
TXT = DNS_TYPE_TEXT,
NS = DNS_TYPE_NS,
MX = DNS_TYPE_MX,
SRV = DNS_TYPE_SRV,
}SourceDNS_Response_Code
DNS_Response_Code :: enum u16be {
No_Error = 0,
Format_Error = 1,
Server_Failure = 2,
Name_Error = 3,
Not_Implemented = 4,
Refused = 5,
}SourceDial_Error
Dial_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid endpoint and/or options.
Invalid_Argument = 3,
// An attempt was made to connect to a broadcast socket on a socket that doesn't support it.
Broadcast_Not_Supported = 4,
// The socket is already connected.
Already_Connected = 5,
// The socket is already in the progress of making a connection.
Already_Connecting = 6,
// The address is already in use.
Address_In_Use = 7,
// Could not reach the remote host.
Host_Unreachable = 8,
// The remote host refused the connection or isn't listening.
Refused = 9,
// The connection was reset by the remote host.
Reset = 10,
// Timed out before making a connection.
Timeout = 11,
// Non-blocking socket that would need to block waiting to connect.
Would_Block = 12,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 13,
// Endpoint given without a port, which is required.
Port_Required = 14,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 15,
}SourceDigit_Parse_Base
Digit_Parse_Base :: enum u8 {
Dec = 0, // No prefix
Oct = 1, // Leading zero
Hex = 2, // 0x prefix
IPv6 = 3, // Unprefixed IPv6 piece hex. Can't be used with other bases.
}SourceDigit_Parse_Bases
Digit_Parse_Bases :: bit_set[Digit_Parse_Base; u8]SourceEndpoint
Endpoint :: struct {
address: Address,
port: int,
}SourceHost
Host :: struct {
hostname: string,
port: int,
}SourceHost_Or_Endpoint
Host_Or_Endpoint :: union {
Host,
Endpoint,
}SourceIP4_Address
IP4_Address :: [4]u8SourceADDRESS DEFINITIONS
IP6_Address
IP6_Address :: [8]u16beSourceInterfaces_Error
Interfaces_Error :: enum u32 {
None = 0,
Unable_To_Enumerate_Network_Interfaces = 1,
Allocation_Failure = 2,
Unknown = 3,
}SourceLease
Lease :: struct {
address: Address,
netmask: Netmask,
lifetime: struct {
valid: u32,
preferred: u32,
lease: u32,
},
origin: struct {
prefix: Prefix_Origin,
suffix: Suffix_Origin,
},
address_duplication: Address_Duplication,
}SourceLink_State
Link_State :: bit_set[Link_States; u32]SourceLink_States
Link_States :: enum u32 {
Up = 1,
Down = 2,
Testing = 3,
Dormant = 4,
Not_Present = 5,
Lower_Layer_Down = 6,
Loopback = 7,
}SourceEmpty bit set is unknown state.
Listen_Error
Listen_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// The socket or backlog is invalid.
Invalid_Argument = 3,
// The socket is valid, but does not support listening.
Unsupported_Socket = 4,
// The socket is already connected.
Already_Connected = 5,
// The address is already in use.
Address_In_Use = 6,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 7,
}SourceNetmask
Netmask :: AddressSourceNetwork_Error
Network_Error :: union {
Create_Socket_Error,
Dial_Error,
Listen_Error,
Accept_Error,
Bind_Error,
TCP_Send_Error,
UDP_Send_Error,
TCP_Recv_Error,
UDP_Recv_Error,
Shutdown_Error,
Interfaces_Error,
Socket_Info_Error,
Socket_Option_Error,
Set_Blocking_Error,
Parse_Endpoint_Error,
Resolve_Error,
DNS_Error,
}SourceNetwork_Interface
Network_Interface :: struct {
adapter_name: string,
friendly_name: string,
description: string,
dns_suffix: string,
physical_address: string,
mtu: u32,
unicast: [dynamic]Lease,
multicast: [dynamic]Address,
anycast: [dynamic]Address,
gateways: [dynamic]Address,
dhcp_v4: Address,
dhcp_v6: Address,
tunnel_type: Tunnel_Type,
link: struct {
state: Link_State,
transmit_speed: u64,
receive_speed: u64,
},
}SourceINTERFACE / LINK STATE
Parse_Endpoint_Error
Parse_Endpoint_Error :: enum u32 {
None = 0,
Bad_Port = 1,
Bad_Address = 2,
Bad_Hostname = 3,
}SourcePrefix_Origin
Prefix_Origin :: enum i32 {
Other = 0,
Manual = 1,
Well_Known = 2,
DHCP = 3,
Router_Advertisement = 4,
Unchanged = 16,
}SourceRecv_Error
Recv_Error :: union {
TCP_Recv_Error,
UDP_Recv_Error,
}SourceResolve_Error
Resolve_Error :: enum u32 {
None = 0,
Unable_To_Resolve = 1,
Allocation_Failure = 2,
}SourceSend_Error
Send_Error :: union {
TCP_Send_Error,
UDP_Send_Error,
}SourceSet_Blocking_Error
Set_Blocking_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Socket is invalid.
Invalid_Argument = 2,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 3,
}SourceShutdown_Error
Shutdown_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Socket is invalid or not connected, or the manner given is invalid.
Invalid_Argument = 2,
// Connection was closed/aborted/shutdown.
Connection_Closed = 3,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 4,
}SourceShutdown_Manner
Shutdown_Manner :: enum i32 {
Receive = i32(_SHUTDOWN_MANNER_RECEIVE),
Send = i32(_SHUTDOWN_MANNER_SEND),
Both = i32(_SHUTDOWN_MANNER_BOTH),
}SourceSocket
Socket :: i64SourceTo allow freely using Socket in your own data structures in a cross-platform manner,
we treat it as a handle large enough to accomodate OS-specific notions of socket handles.
The platform code will perform the cast so you don't have to.Socket_Info_Error
Socket_Info_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Socket is invalid or not connected, or the manner given is invalid.
Invalid_Argument = 3,
// The socket is valid, but unsupported by this opperation.
Unsupported_Socket = 4,
// Connection was closed/aborted/shutdown.
Connection_Closed = 5,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 6,
}SourceSocket_Option
Socket_Option :: enum i32 {
Broadcast = i32(_SOCKET_OPTION_BROADCAST),
Reuse_Address = i32(_SOCKET_OPTION_REUSE_ADDRESS),
Keep_Alive = i32(_SOCKET_OPTION_KEEP_ALIVE),
Out_Of_Bounds_Data_Inline = i32(_SOCKET_OPTION_OUT_OF_BOUNDS_DATA_INLINE),
Linger = i32(_SOCKET_OPTION_LINGER),
Receive_Buffer_Size = i32(_SOCKET_OPTION_RECEIVE_BUFFER_SIZE),
Send_Buffer_Size = i32(_SOCKET_OPTION_SEND_BUFFER_SIZE),
Receive_Timeout = i32(_SOCKET_OPTION_RECEIVE_TIMEOUT),
Send_Timeout = i32(_SOCKET_OPTION_SEND_TIMEOUT),
TCP_Nodelay = i32(_SOCKET_OPTION_TCP_NODELAY),
Use_Loopback = i32(_SOCKET_OPTION_USE_LOOPBACK),
Reuse_Port = i32(_SOCKET_OPTION_REUSE_PORT),
No_SIGPIPE_From_EPIPE = i32(_SOCKET_OPTION_NO_SIGPIPE_FROM_EPIPE),
Reuse_Port_Load_Balancing = i32(_SOCKET_OPTION_REUSE_PORT_LOAD_BALANCING),
Exclusive_Addr_Use = i32(_SOCKET_OPTION_EXCLUSIVE_ADDR_USE),
Conditional_Accept = i32(_SOCKET_OPTION_CONDITIONAL_ACCEPT),
Dont_Linger = i32(_SOCKET_OPTION_DONT_LINGER),
}SourcePackage net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
For other protocols and their features, see subdirectories of this package.
Copyright 2022-2023 Tetralux <tetraluxonpc@gmail.com>
Copyright 2022-2023 Colin Davidson <colrdavidson@gmail.com>
Copyright 2022-2023 Jeroen van Rijn <nom@duclavier.com>.
Copyright 2024 Feoramund <rune@swevencraft.org>.
Made available under Odin's license.
List of contributors:
Tetralux: Initial implementation
Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
Jeroen van Rijn: Cross platform unification, code style, documentation
Feoramund: FreeBSD platform codeSocket_Option_Error
Socket_Option_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Socket is invalid, not connected, or the connection has been closed/reset/shutdown.
Invalid_Socket = 3,
// Unknown or unsupported option for the socket.
Invalid_Option = 4,
// Invalid level or value.
Invalid_Value = 5,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 6,
}SourceSocket_Protocol
Socket_Protocol :: enum int {
TCP = 0,
UDP = 1,
}SourceSuffix_Origin
Suffix_Origin :: enum i32 {
Other = 0,
Manual = 1,
Well_Known = 2,
DHCP = 3,
Link_Layer_Address = 4,
Random = 5,
Unchanged = 16,
}SourceTCP_Options
TCP_Options :: struct {
no_delay: bool,
}SourceSOCKET OPTIONS & DEFINITIONS
TCP_Recv_Error
TCP_Recv_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket or buffer given.
Invalid_Argument = 3,
// The socket is not connected.
Not_Connected = 4,
// Connection was closed due to an error or shutdown.
// NOTE: a graceful close is indicated by a `0, nil` (0 bytes received and no error) return.
Connection_Closed = 5,
// Timed out before being able to receive any data.
Timeout = 6,
// Non-blocking socket that would need to block waiting on data.
Would_Block = 7,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 8,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 9,
}SourceTCP_Send_Error
TCP_Send_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket or buffer given.
Invalid_Argument = 3,
// Connection was closed/broken/shutdown while sending data.
Connection_Closed = 4,
// The socket is not connected.
Not_Connected = 5,
// Could not reach the remote host.
Host_Unreachable = 6,
// Timed out before being able to send any data.
Timeout = 7,
// Non-blocking socket that would need to block waiting on the remote to be able to receive the data.
Would_Block = 8,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 9,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 10,
}SourceTCP_Socket
TCP_Socket :: SocketSourceTunnel_Type
Tunnel_Type :: enum i32 {
None = 0,
Other = 1,
Direct = 2,
IPv4_To_IPv6 = 11,
ISA_TAP = 13,
Teredo = 14,
IP_HTTPS = 15,
}SourceUDP_Recv_Error
UDP_Recv_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket or buffer given.
Invalid_Argument = 3,
// "Connection" was refused, or closed due to an error.
// NOTE: a graceful close is indicated by a `0, nil` (0 bytes received and no error) return.
Connection_Refused = 4,
// Timed out before being able to receive any data.
Timeout = 5,
// Non-blocking socket that would need to block waiting on data.
Would_Block = 6,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 7,
// Linux and UDP only: indicates the buffer was too small to receive all data, and the excess is truncated and discarded.
Excess_Truncated = 8,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 9,
}SourceUDP_Send_Error
UDP_Send_Error :: enum i32 {
None = 0,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 1,
// Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given.
Insufficient_Resources = 2,
// Invalid socket or buffer given.
Invalid_Argument = 3,
// Could not reach the remote host.
Host_Unreachable = 4,
// "Connection" was refused by remote, or closed/broken/shutdown while sending data.
Connection_Refused = 5,
// Timed out before being able to send any data.
Timeout = 6,
// Non-blocking socket that would need to block waiting on the remote to be able to receive the data.
Would_Block = 7,
// Interrupted by a signal or other method of cancellation like WSACancelBlockingCall on Windows.
Interrupted = 8,
// An error unable to be categorized in above categories, `last_platform_error` may have more info.
Unknown = 9,
}SourceUDP_Socket
UDP_Socket :: SocketSourceConstants
39DEFAULT_DIGIT_BASES
DEFAULT_DIGIT_BASES :: Digit_Parse_Bases = Digit_Parse_Bases{.Dec, .Oct, .Hex}SourceDEFAULT_DNS_CONFIGURATION
DEFAULT_DNS_CONFIGURATION :: DNS_Configuration = DNS_Configuration{}SourceDEFAULT_TCP_OPTIONS
DEFAULT_TCP_OPTIONS :: TCP_Options = TCP_Options {
no_delay = ODIN_NET_TCP_NODELAY_DEFAULT,
}SourceDNS_PACKET_MIN_LEN
DNS_PACKET_MIN_LEN :: (size_of(u16be) * 6) + NAME_MAX + (size_of(u16be) * 2)SourceIP4_Any
IP4_Any :: IP4_Address = IP4_Address{}SourceIP4_Loopback
IP4_Loopback :: IP4_Address = IP4_Address{127, 0, 0, 1}SourceIP4_mDNS_Broadcast
IP4_mDNS_Broadcast :: Endpoint = Endpoint{address=IP4_Address{224, 0, 0, 251}, port=5353}SourceIP6_Any
IP6_Any :: IP6_Address = IP6_Address{}SourceIP6_Loopback
IP6_Loopback :: IP6_Address = IP6_Address{0, 0, 0, 0, 0, 0, 0, 1}SourceIP6_mDNS_Broadcast
IP6_mDNS_Broadcast :: Endpoint = Endpoint{address=IP6_Address{65282, 0, 0, 0, 0, 0, 0, 251}, port = 5353}SourceIPv6_MAX_STRING_LENGTH
IPv6_MAX_STRING_LENGTH :: 45SourceIPv6_MIN_COLONS
IPv6_MIN_COLONS :: 2SourceIPv6_MIN_STRING_LENGTH
IPv6_MIN_STRING_LENGTH :: 2SourceThe minimum length of a valid IPv6 address string is 2, e.g. ::
The maximum length of a valid IPv6 address string is 45, when it embeds an IPv4,
e.g. `0000:0000:0000:0000:0000:ffff:255.255.255.255`
An IPv6 address must contain at least 3 pieces, e.g. `::`,
and at most 9 (using `::` for a trailing or leading 0)IPv6_PIECE_COUNT
IPv6_PIECE_COUNT :: 8SourceLABEL_MAX
LABEL_MAX :: 63SourceMAX_INTERFACE_ENUMERATION_TRIES
MAX_INTERFACE_ENUMERATION_TRIES :: 3SourceMaybe
Maybe :: runtime.MaybeSourceCOMMON DEFINITIONS
NAME_MAX
NAME_MAX :: 255SourceTODO(cloin): Does the DNS Resolver need to recursively hop through CNAMEs to get the IP
or is that what recursion desired does? Do we need to handle recursion unavailable?
How do we deal with is_authoritative / is_truncated?ODIN_NET_TCP_NODELAY_DEFAULT
ODIN_NET_TCP_NODELAY_DEFAULT :: _ = #config(ODIN_NET_TCP_NODELAY_DEFAULT, true)SourceTUNEABLES - See also top of dns.odin for DNS configuration.
Determines the default value for whether dial_tcp() and accept_tcp() will set TCP_NODELAY on the new
socket, and the client socket, respectively.
This can also be set on a per-socket basis using the 'options' optional parameter to those procedures.
When TCP_NODELAY is set, data will be sent out to the peer as quickly as possible, rather than being
coalesced into fewer network packets.
This makes the networking layer more eagerly send data when you ask it to,
which can reduce latency by up to 200ms.
This does mean that a lot of small writes will negatively effect throughput however,
since the Nagle algorithm will be disabled, and each write becomes one
IP packet. This will increase traffic by a factor of 40, with IP and TCP
headers for each payload.
However, you can avoid this by buffering things up yourself if you wish to send a lot of
short data chunks, when TCP_NODELAY is enabled on that socket._SHUTDOWN_MANNER_BOTH
_SHUTDOWN_MANNER_BOTH :: linux.Shutdown_How.RDWRSource_SHUTDOWN_MANNER_RECEIVE
_SHUTDOWN_MANNER_RECEIVE :: linux.Shutdown_How.RDSource_SHUTDOWN_MANNER_SEND
_SHUTDOWN_MANNER_SEND :: linux.Shutdown_How.WRSource_SOCKET_OPTION_BROADCAST
_SOCKET_OPTION_BROADCAST :: linux.Socket_Option.BROADCASTSource_SOCKET_OPTION_CONDITIONAL_ACCEPT
_SOCKET_OPTION_CONDITIONAL_ACCEPT :: -1Source_SOCKET_OPTION_DONT_LINGER
_SOCKET_OPTION_DONT_LINGER :: -1Source_SOCKET_OPTION_EXCLUSIVE_ADDR_USE
_SOCKET_OPTION_EXCLUSIVE_ADDR_USE :: -1Source_SOCKET_OPTION_KEEP_ALIVE
_SOCKET_OPTION_KEEP_ALIVE :: linux.Socket_Option.KEEPALIVESource_SOCKET_OPTION_LINGER
_SOCKET_OPTION_LINGER :: linux.Socket_Option.LINGERSource_SOCKET_OPTION_NO_SIGPIPE_FROM_EPIPE
_SOCKET_OPTION_NO_SIGPIPE_FROM_EPIPE :: -1Source_SOCKET_OPTION_OUT_OF_BOUNDS_DATA_INLINE
_SOCKET_OPTION_OUT_OF_BOUNDS_DATA_INLINE :: linux.Socket_Option.OOBINLINESource_SOCKET_OPTION_RECEIVE_BUFFER_SIZE
_SOCKET_OPTION_RECEIVE_BUFFER_SIZE :: linux.Socket_Option.RCVBUFSource_SOCKET_OPTION_RECEIVE_TIMEOUT
_SOCKET_OPTION_RECEIVE_TIMEOUT :: linux.Socket_Option.RCVTIMEOSource_SOCKET_OPTION_REUSE_ADDRESS
_SOCKET_OPTION_REUSE_ADDRESS :: linux.Socket_Option.REUSEADDRSource_SOCKET_OPTION_REUSE_PORT
_SOCKET_OPTION_REUSE_PORT :: -1Source_SOCKET_OPTION_REUSE_PORT_LOAD_BALANCING
_SOCKET_OPTION_REUSE_PORT_LOAD_BALANCING :: -1Source_SOCKET_OPTION_SEND_BUFFER_SIZE
_SOCKET_OPTION_SEND_BUFFER_SIZE :: linux.Socket_Option.SNDBUFSource_SOCKET_OPTION_SEND_TIMEOUT
_SOCKET_OPTION_SEND_TIMEOUT :: linux.Socket_Option.SNDTIMEOSource_SOCKET_OPTION_TCP_NODELAY
_SOCKET_OPTION_TCP_NODELAY :: linux.Socket_TCP_Option.NODELAYSource_SOCKET_OPTION_USE_LOOPBACK
_SOCKET_OPTION_USE_LOOPBACK :: -1SourceVariables
1Procedures
90_accept_error
_accept_error :: proc(errno: linux.Errno) -> (Accept_Error)Source_bind_error
_bind_error :: proc(errno: linux.Errno) -> (Bind_Error)Source_create_socket
_create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (Create_Socket_Error, Any_Socket)Source_create_socket_error
_create_socket_error :: proc(errno: linux.Errno) -> (Create_Socket_Error)Source_dial_error
_dial_error :: proc(errno: linux.Errno) -> (Dial_Error)Source_last_platform_error
_last_platform_error :: proc() -> (i32)Source_last_platform_error_string
_last_platform_error_string :: proc() -> (string)Source_listen_error
_listen_error :: proc(errno: linux.Errno) -> (Listen_Error)Source_set_blocking_error
_set_blocking_error :: proc(errno: linux.Errno) -> (Set_Blocking_Error)Source_set_last_platform_error
_set_last_platform_error :: proc(err: i32)Source_shutdown_error
_shutdown_error :: proc(errno: linux.Errno) -> (Shutdown_Error)Source_socket_info_error
_socket_info_error :: proc(errno: linux.Errno) -> (Socket_Info_Error)Source_socket_option_error
_socket_option_error :: proc(errno: linux.Errno) -> (Socket_Option_Error)Source_tcp_recv_error
_tcp_recv_error :: proc(errno: linux.Errno) -> (TCP_Recv_Error)Source_tcp_send_error
_tcp_send_error :: proc(errno: linux.Errno) -> (TCP_Send_Error)Source_udp_recv_error
_udp_recv_error :: proc(errno: linux.Errno) -> (UDP_Recv_Error)Source_udp_send_error
_udp_send_error :: proc(errno: linux.Errno) -> (UDP_Send_Error)Sourceaccept_tcp
accept_tcp :: proc(socket: TCP_Socket, options = DEFAULT_TCP_OPTIONS) -> (client: TCP_Socket, source: Endpoint, err: Accept_Error)Sourceaddress_to_string_allocator
address_to_string_allocator :: proc(addr: Address, allocator = context.temp_allocator) -> (string)SourceReturns a temporarily-allocated string representation of the address.
See RFC 5952 section 4 for IPv6 representation recommendations.address_to_string_builder
address_to_string_builder :: proc(addr: Address, b: ^strings.Builder) -> (string)SourceReturns a string representation of the address using a strings.Builder.
See RFC 5952 section 4 for IPv6 representation recommendations.any_socket_to_socket
any_socket_to_socket :: proc(socket: Any_Socket) -> (Socket)Sourceaton
aton :: proc(address_and_maybe_port: string, family: Address_Family, allow_decimal_only: untyped boolean = false) -> (addr: Address, ok: bool)SourceParses an IP address in "non-decimal" inet_aton form.
e.g."00377.0x0ff.65534" = 255.255.255.254
00377 = 255 in octal
0x0ff = 255 in hexadecimal
This leaves 16 bits worth of address
.65534 then accounts for the last two digits
For the address part the allowed forms are:
a.b.c.d - where each part represents a byte
a.b.c - where `a` & `b` represent a byte and `c` a u16
a.b - where `a` represents a byte and `b` supplies the trailing 24 bits
a - where `a` gives the entire 32-bit value
The port, if present, is required to be a base 10 number in the range 0-65535, inclusive.bind
bind :: proc(socket: Any_Socket, ep: Endpoint) -> (err: Bind_Error)Sourcebound_endpoint
bound_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Socket_Info_Error)SourceReturns the endpoint that the given socket is listening / bound on.
close
close :: proc(socket: Any_Socket)Sourcecreate_socket
create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (socket: Any_Socket, err: Create_Socket_Error)Sourcedecode_hostname
decode_hostname :: proc(packet: []u8, start_idx: int, allocator: mem.Allocator = context.allocator) -> (hostname: string, encode_size: int, ok: bool)Sourcedestroy_dns_records
destroy_dns_records :: proc(records: []DNS_Record, allocator: mem.Allocator = context.allocator)Sourcerecords slice is also destroyed.
destroy_interfaces
destroy_interfaces :: proc(interfaces: []Network_Interface, allocator: mem.Allocator = context.allocator)Sourcedestroy_interfaces cleans up a list of network interfaces retrieved by e.g. enumerate_interfaces.
dial_tcp_from_address_and_port
dial_tcp_from_address_and_port :: proc(address: Address, port: int, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceDial from an Address.
Errors that can be returned: `Create_Socket_Error`, or `Dial_Error`dial_tcp_from_endpoint
dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceDial from an Endpoint.
Errors that can be returned: `Create_Socket_Error`, or `Dial_Error`dial_tcp_from_host
dial_tcp_from_host :: proc(host: Host, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceExpects the host as Host.
Errors that can be returned: `Resolve_Error`, `DNS_Error`, `Create_Socket_Error`, or `Dial_Error`dial_tcp_from_host_or_endpoint
dial_tcp_from_host_or_endpoint :: proc(target: Host_Or_Endpoint, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceExpects the target as a Host_OrEndpoint. Unwraps the underlying type and calls dial_tcp_from_host or dial_tcp_from_endpoint.
Errors that can be returned: `Parse_Endpoint_Error`, `Resolve_Error`, `DNS_Error`, `Create_Socket_Error`, or `Dial_Error`dial_tcp_from_hostname_and_port_string
dial_tcp_from_hostname_and_port_string :: proc(hostname_and_port: string, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceExpects both hostname and port to be present in the hostname_and_port parameter, either as: a.host.name:9999, or as 1.2.3.4:9999, or IP6 equivalent.
Calls parse_hostname_or_endpoint and dial_tcp_from_host_or_endpoint.
Errors that can be returned: `Parse_Endpoint_Error`, `Resolve_Error`, `DNS_Error`, `Create_Socket_Error`, or `Dial_Error`dial_tcp_from_hostname_with_port_override
dial_tcp_from_hostname_with_port_override :: proc(hostname: string, port: int, options = DEFAULT_TCP_OPTIONS) -> (socket: TCP_Socket, err: Network_Error)SourceExpects the hostname as a string and port as a int. parse_hostname_or_endpoint is called and the hostname will be resolved into an IP.
If a hostname of form a.host.name:9999 is given, the port will be ignored in favor of the explicit port param.
Errors that can be returned: `Parse_Endpoint_Error`, `Resolve_Error`, `DNS_Error`, `Create_Socket_Error`, or `Dial_Error`encode_hostname
encode_hostname :: proc(b: ^strings.Builder, hostname: string) -> (ok: bool)Sourcewww.google.com -> 3www6google3com0
endpoint_to_string_allocator
endpoint_to_string_allocator :: proc(ep: Endpoint, allocator = context.temp_allocator) -> (string)SourceReturns a temporarily-allocated string representation of the endpoint. If there's a port, uses the ip4address:port or [ip6address]:port format, respectively.
endpoint_to_string_builder
endpoint_to_string_builder :: proc(ep: Endpoint, b: ^strings.Builder) -> (string)SourceReturns a string representation of the endpoint using a strings.Builder. If there's a port, uses the ip4address:port or [ip6address]:port format, respectively.
enumerate_interfaces
enumerate_interfaces :: proc(allocator: mem.Allocator = context.allocator) -> (interfaces: []Network_Interface, err: Interfaces_Error)Sourceenumerate_interfaces retrieves a list of network interfaces with their associated properties.
family_from_address
family_from_address :: proc(addr: Address) -> (Address_Family)Sourcefamily_from_endpoint
family_from_endpoint :: proc(ep: Endpoint) -> (Address_Family)Sourceget_dns_records_from_nameservers
get_dns_records_from_nameservers :: proc(hostname: string, type: DNS_Record_Type, name_servers: []Endpoint, host_overrides: []DNS_Record, allocator: mem.Allocator = context.allocator) -> (records: []DNS_Record, err: DNS_Error)SourceA generic DNS client usable on any platform.
Performs a recursive DNS query for records of a particular type for the hostname.
NOTE: This procedure instructs the DNS resolver to recursively perform CNAME requests on our behalf,
meaning that DNS queries for a hostname will resolve through CNAME records until an
IP address is reached.
IMPORTANT: This procedure allocates memory for each record returned; deleting just the returned slice is not enough!
See `destroy_records`.get_dns_records_from_os
get_dns_records_from_os :: proc(hostname: string, type: DNS_Record_Type, allocator: mem.Allocator = context.allocator) -> (records: []DNS_Record, err: DNS_Error)SourcePerforms a recursive DNS query for records of a particular type for the hostname using the OS.
NOTE: This procedure instructs the DNS resolver to recursively perform CNAME requests on our behalf,
meaning that DNS queries for a hostname will resolve through CNAME records until an
IP address is reached.
IMPORTANT: This procedure allocates memory for each record returned; deleting just the returned slice is not enough!
See `destroy_records`.get_network_interfaces
get_network_interfaces :: proc() -> ([]Address)SourceReturns an address for each interface that can be bound to.
init_dns_configuration
init_dns_configuration :: proc()Sourcejoin_port_allocator
join_port_allocator :: proc(address_or_host: string, port: int, allocator: mem.Allocator = context.allocator) -> (string)SourceJoins an address or hostname with a port, allocated using an Allocator.
join_port_builder
join_port_builder :: proc(address_or_host: string, port: int, b: ^strings.Builder) -> (string)SourceJoins an address or hostname with a port, allocated using a strings.Builder.
join_url
join_url :: proc(
scheme: string,
host: string,
path: string,
queries: map[string]string,
fragment: string,
allocator: mem.Allocator = context.allocator,
) -> (string)Sourcelast_platform_error
last_platform_error :: proc() -> (i32)SourceRetrieve a platform specific error code, for when the categorized cross-platform errors are not enough.
Platforms specific returns:
- Darwin:
posix.Errno(core:sys/posix) - Linux:
linux.Errno(core:sys/linux) - FreeBSD:
freebsd.Errno(core:sys/freebsd) - Windows:
windows.System_Error(core:sys/windows)
last_platform_error_string
last_platform_error_string :: proc() -> (string)SourceRetrieve a stringified version of the last platform error.
listen_tcp
listen_tcp :: proc(interface_endpoint: Endpoint, backlog: untyped integer = 1000) -> (socket: TCP_Socket, err: Network_Error)SourceCreates a TCP socket and starts listening on the given endpoint.
Errors that can be returned: `Create_Socket_Error`, `Bind_Error`, or `Listen_Error`load_hosts
load_hosts :: proc(hosts_file_path: string, allocator: mem.Allocator = context.allocator) -> (hosts: []DNS_Host_Entry, ok: bool)Sourceload_resolv_conf
load_resolv_conf :: proc(resolv_conf_path: string, allocator: mem.Allocator = context.allocator) -> (name_servers: []Endpoint, ok: bool)Sourcemake_bound_udp_socket
make_bound_udp_socket :: proc(bound_address: Address, port: int) -> (socket: UDP_Socket, err: Network_Error)SourceThis type of socket is bound immediately, which enables it to receive data on the port.
Since it's UDP, it's also able to send data without receiving any first.
This is like a listening TCP socket, except that data packets can be sent and received without needing to establish a connection first.
The `bound_address` is the address of the network interface that you want to use, or a loopback address if you don't care which to use.
Errors that can be returned: `Parse_Endpoint_Error`, `Create_Socket_Error`, or `Bind_Error`make_dns_packet
make_dns_packet :: proc(buf: []u8, id: u16be, hostname: string, type: DNS_Record_Type) -> (packet: []u8, err: DNS_Error)Sourcemake_unbound_udp_socket
make_unbound_udp_socket :: proc(family: Address_Family) -> (socket: UDP_Socket, err: Create_Socket_Error)SourceThis type of socket becomes bound when you try to send data.
It is likely what you want if you want to send data unsolicited.
This is like a client TCP socket, except that it can send data to any remote endpoint without needing to establish a connection first.map_to_ip6
map_to_ip6 :: proc(addr: Address) -> (Address)SourceTODO(tetra): Do we need this?
pack_dns_header
pack_dns_header :: proc(hdr: DNS_Header) -> (id: u16be, bits: u16be)Sourceparse_address
parse_address :: proc(address_and_maybe_port: string, non_decimal_address: untyped boolean = false) -> (Address)SourceTry parsing as an IPv6 address.
If it's determined not to be, try as an IPv4 address, optionally in non-decimal format.parse_endpoint
parse_endpoint :: proc(endpoint_str: string) -> (ep: Endpoint, ok: bool)Sourceparse_hostname_or_endpoint
parse_hostname_or_endpoint :: proc(endpoint_str: string) -> (target: Host_Or_Endpoint, err: Parse_Endpoint_Error)SourceTakes a string consisting of a hostname or IP address, and an optional port, and return the component parts in a useful form.
parse_hosts
parse_hosts :: proc(stream: io.Stream, allocator: mem.Allocator = context.allocator) -> (hosts: []DNS_Host_Entry, ok: bool)Sourceparse_ip4_address
parse_ip4_address :: proc(address_and_maybe_port: string, allow_non_decimal: untyped boolean = false) -> (addr: IP4_Address, ok: bool)SourceExpects an IPv4 address with no leading or trailing whitespace:
- a.b.c.d
- a.b.c.d:port
- [a.b.c.d]:port
If the IP address is bracketed, the port must be present and valid (though it will be ignored):
- [a.b.c.d] will be treated as a parsing failure.
The port, if present, is required to be a base 10 number in the range 0-65535, inclusive.
If `allow_non_decimal` is false, `aton` is told each component must be decimal and max 255.parse_ip6_address
parse_ip6_address :: proc(address_and_maybe_port: string) -> (addr: IP6_Address, ok: bool)Sourceparse_ip_component
parse_ip_component :: proc(input: string, max_value: u64 = u64(max(u32)), bases = DEFAULT_DIGIT_BASES) -> (value: u64, bytes_consumed: int, ok: bool)SourceParses a single unsigned number in requested bases from input.
`max_value` represents the maximum allowed value for this number.
Returns the `value`, the `bytes_consumed` so far, and `ok` to signal success or failure.
An out-of-range or invalid number will return the accumulated value so far (which can be out of range),
the number of bytes consumed leading up the error, and `ok = false`.
When `.` or `:` are encountered, they'll be considered valid separators and will stop parsing,
returning the valid number leading up to it.
Other non-digit characters are treated as an error.
Octal numbers are expected to have a leading zero, with no 'o' format specifier.
Hexadecimal numbers are expected to be preceded by '0x' or '0X'.
Numbers will otherwise be considered to be in base 10.parse_record
parse_record :: proc(packet: []u8, cur_off: ^int, filter: DNS_Record_Type) -> (record: DNS_Record, ok: bool)Sourceparse_resolv_conf
parse_resolv_conf :: proc(resolv_str: string, allocator: mem.Allocator = context.allocator) -> (name_servers: []Endpoint)Sourceparse_response
parse_response :: proc(response: []u8, filter: DNS_Record_Type, allocator: mem.Allocator = context.allocator) -> (records: []DNS_Record, xid: u16be, ok: bool)SourceDNS Query Response Format:
- DNS_Header (packed)
- Query Count
- Answer Count
- Authority Count
- Additional Count
- Query[]
- Hostname -- encoded
- Type
- Class
- Answer[]
- DNS Record Data
- Authority[]
- DNS Record Data
- Additional[]
- DNS Record Data
DNS Record Data:
- DNS_Record_Header
- Data[]peer_endpoint
peer_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Socket_Info_Error)SourceReturns the endpoint that the given socket is connected to. (Peer's endpoint)
percent_decode
percent_decode :: proc(encoded_string: string, allocator: mem.Allocator = context.allocator) -> (decoded_string: string, ok: bool)Sourcepercent_encode
percent_encode :: proc(s: string, allocator: mem.Allocator = context.allocator) -> (string)Sourcephysical_address_to_string
physical_address_to_string :: proc(phy_addr: []u8, allocator: mem.Allocator = context.allocator) -> (phy_string: string)SourceTurns a slice of bytes (from e.g. get_adapters_addresses) into a "XX:XX:XX:..." string.
recv_any
recv_any :: proc(socket: Any_Socket, buf: []u8) -> (bytes_read: int, remote_endpoint: Maybe(Endpoint), err: Network_Error)SourceReceive data into a buffer from any socket.
Note: `remote_endpoint` parameter is non-nil only if the socket type is UDP. On TCP sockets it
will always return `nil`.
Errors that can be returned: `TCP_Recv_Error`, or `UDP_Recv_Error`.
If no error occurs, `recv_any` returns the number of bytes received and `buf` will contain this data received.
If the connection has been gracefully closed, the return value is `0, nil, nil` (0 bytes read and no error).recv_tcp
recv_tcp :: proc(socket: TCP_Socket, buf: []u8) -> (bytes_read: int, err: TCP_Recv_Error)SourceReceive data into a buffer from a TCP socket.
If no error occurs, `recv_tcp` returns the number of bytes received and `buf` will contain this data received.
If the connection has been gracefully closed, the return value is `0, nil` (0 bytes read and no error).recv_udp
recv_udp :: proc(socket: UDP_Socket, buf: []u8) -> (bytes_read: int, remote_endpoint: Endpoint, err: UDP_Recv_Error)SourceReceive data into a buffer from a UDP socket.
If no error occurs, `recv_udp` returns the number of bytes received and `buf` will contain this data received.
If the "connection" has been gracefully closed, the return value is `0, nil` (0 bytes read and no error).resolve
resolve :: proc(hostname_and_maybe_port: string) -> (ep4: Endpoint, ep6: Endpoint, err: Network_Error)SourceResolves a hostname to exactly one IP4 and IP6 endpoint.
It's then up to you which one you use.
Note that which address you use to open a socket, determines the type of the socket you get.
Returns `ok=false` if the host name could not be resolved to any endpoints.
Returned endpoints have the same port as provided in the string, or 0 if absent.
If you want to use a specific port, just modify the field after the call to this procedure.
If the hostname part of the endpoint is actually a string representation of an IP address, DNS resolution will be skipped.
This allows you to pass both strings like "example.com:9000" and "1.2.3.4:9000" to this function end reliably get
back an endpoint in both cases.resolve_ip4
resolve_ip4 :: proc(hostname_and_maybe_port: string) -> (ep4: Endpoint, err: Network_Error)Sourceresolve_ip6
resolve_ip6 :: proc(hostname_and_maybe_port: string) -> (ep6: Endpoint, err: Network_Error)Sourcesend_any
send_any :: proc(socket: Any_Socket, buf: []u8, to: Maybe(Endpoint)) -> (bytes_written: int, err: Network_Error)SourceSends data over the socket.
Errors that can be returned: `TCP_Send_Error`, or `UDP_Send_Error`send_tcp
send_tcp :: proc(socket: TCP_Socket, buf: []u8) -> (bytes_written: int, err: TCP_Send_Error)SourceRepeatedly sends data until the entire buffer is sent.
If a send fails before all data is sent, returns the amount sent up to that point.send_udp
send_udp :: proc(socket: UDP_Socket, buf: []u8, to: Endpoint) -> (bytes_written: int, err: UDP_Send_Error)SourceSends a single UDP datagram packet.
Datagrams are limited in size; attempting to send more than this limit at once will result in a Message_Too_Long error.
UDP packets are not guarenteed to be received in order.set_blocking
set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Set_Blocking_Error)Sourceset_last_platform_error
set_last_platform_error :: proc(err: i32)Sourceset_option
set_option :: proc(socket: Any_Socket, option: Socket_Option, value: any, loc = #caller_location) -> (Socket_Option_Error)Sourceshutdown
shutdown :: proc(socket: Any_Socket, manner: Shutdown_Manner) -> (err: Shutdown_Error)Sourceskip_hostname
skip_hostname :: proc(packet: []u8, start_idx: int) -> (encode_size: int, ok: bool)Sourcesplit_port
split_port :: proc(endpoint_str: string) -> (addr_or_host: string, port: int, ok: bool)SourceTakes an endpoint string and returns its parts. Returns ok=false if port is not a number.
split_url
split_url :: proc(url: string, allocator: mem.Allocator = context.allocator) -> (scheme: string, host: string, path: string, queries: map[string]string, fragment: string)Sourceunpack_dns_header
unpack_dns_header :: proc(id: u16be, bits: u16be) -> (hdr: DNS_Header)Sourcevalidate_hostname
validate_hostname :: proc(hostname: string) -> (ok: bool)SourceUses RFC 952 & RFC 1123
Procedure Groups
7address_to_string
address_to_string :: proc{address_to_string_allocator, address_to_string_builder}Sourcedial_tcp
dial_tcp :: proc{dial_tcp_from_endpoint, dial_tcp_from_address_and_port, dial_tcp_from_hostname_and_port_string, dial_tcp_from_hostname_with_port_override, dial_tcp_from_host, dial_tcp_from_host_or_endpoint}Sourceendpoint_to_string
endpoint_to_string :: proc{endpoint_to_string_allocator, endpoint_to_string_builder}Sourcejoin_port
join_port :: proc{join_port_allocator, join_port_builder}Sourcerecv
recv :: proc{recv_tcp, recv_udp, recv_any}Sourcesend
send :: proc{send_tcp, send_udp, send_any}Sourceto_string
to_string :: proc{address_to_string_allocator, address_to_string_builder, endpoint_to_string_allocator, endpoint_to_string_builder}Source