xtc_net(3)
---xtc_net(3)
networking helpers
| XTC_NET(3) | Library Functions Manual | XTC_NET(3) |
NAME
xtc_net_listen,
xtc_net_dial,
xtc_net_apply_tcp_opts,
xtc_net_setnonblock,
xtc_net_close,
xtc_net_unix_listen,
xtc_net_unix_dial,
xtc_net_unix_send_creds,
xtc_net_unix_recv_creds,
xtc_net_send_frame,
xtc_net_recv_frame,
xtc_net_udp_socket,
xtc_net_udp_sendto,
xtc_net_udp_recvfrom,
xtc_dns_resolve — networking
helpers
SYNOPSIS
#include <xtc.h>
#include <xtc_net.h>
int
xtc_net_listen(xtc_net_family_t
fam, const char
*host, int port,
const xtc_tcp_opts_t
*opts, int
*out_fd);
int
xtc_net_dial(xtc_net_family_t
fam, const char
*host, int port,
const xtc_tcp_opts_t
*opts, int
*out_fd);
int
xtc_net_apply_tcp_opts(int
fd, const xtc_tcp_opts_t
*opts);
int
xtc_net_setnonblock(int
fd);
void
xtc_net_close(int
fd);
int
xtc_net_unix_listen(const
char *path, int
*out_fd);
int
xtc_net_unix_dial(const
char *path, int
*out_fd);
int
xtc_net_unix_send_creds(int
fd, const void
*buf, size_t
buflen);
int
xtc_net_unix_recv_creds(int
fd, void *buf,
size_t buflen,
uint32_t *out_uid,
uint32_t *out_gid,
size_t *out_n);
int
xtc_net_send_frame(int
fd, const void
*buf, size_t
len);
int
xtc_net_recv_frame(int
fd, void **out,
size_t *out_len,
size_t max_len,
int64_t timeout_ns);
int
xtc_net_udp_socket(xtc_net_family_t
fam, const char
*host, int port,
int *out_fd);
int
xtc_net_udp_sendto(int
fd, const void
*buf, size_t len,
const char *host,
int port);
int
xtc_net_udp_recvfrom(int
fd, void *buf,
size_t buflen,
char *out_host,
size_t out_host_size,
int *out_port,
size_t *out_n);
int
xtc_dns_resolve(const
char *hostname, int
port, xtc_net_family_t
fam, char
*out_addr, size_t
out_addr_size);
DESCRIPTION
xtc_net provides convenience wrappers
around the standard networking syscalls. The actual I/O multiplexing happens
through xtc_io(3) and
xtc_proc_wait_fd(3);
xtc_net_send_frame()
and
xtc_net_recv_frame()
exchange a 4-byte big-endian length prefix followed by the payload. On a
non-blocking fd they yield the calling fiber on partial I/O instead of
blocking the loop, so many connections share one loop; off a loop they fall
back to poll(2).
xtc_net_recv_frame() allocates the frame (free it
with
__os_free()),
and rejects a claimed length above max_len (0 = no
cap) with XTC_E_RANGE so a peer cannot force an
unbounded allocation; it returns XTC_E_AGAIN on
timeout and XTC_E_INVAL if the peer closed
mid-frame. A zero-length frame yields XTC_OK with
*out set to NULL. these helpers handle socket
creation, address resolution, knob setting, and credential passing.
xtc_net_udp_socket()
opens a UDP datagram socket bound to
host:port
(host NULL means wildcard,
port 0 means kernel-assigned)
in non-blocking, close-on-exec mode.
xtc_net_udp_sendto()
sends one datagram to host:port,
returning XTC_E_AGAIN if the kernel buffer is full.
xtc_net_udp_recvfrom()
receives one datagram, filling out_host (of
out_host_size bytes),
out_port, and out_n with the
peer address and byte count.
xtc_dns_resolve()
resolves hostname:port for
family fam to a printable address string in
out_addr (of out_addr_size
bytes). It uses getaddrinfo(3) on
a blocking thread, so run it from a proc whose thread is allowed to
block.
TCP knobs controlled by xtc_tcp_opts_t include:
- nodelay
TCP_NODELAY: disable Nagle's algorithm. Default 1.- reuseaddr
SO_REUSEADDR.- reuseport
SO_REUSEPORTon Linux/BSD; no-op elsewhere.- keepalive
SO_KEEPALIVEplus optional keepidle_s, keepintvl_s, keepcnt on Linux.- user_timeout_ms
TCP_USER_TIMEOUTon Linux.
xtc_net_listen()
opens a non-blocking listening socket bound to
host:port.
fam selects address family
(XTC_NET_INET,
XTC_NET_INET6, or
XTC_NET_UNIX). The fd is non-blocking with
FD_CLOEXEC; caller can register it with
xtc_io_reg_fd(3) or pass to
xtc_proc_wait_fd(3).
xtc_net_dial()
opens a non-blocking TCP connection. The connect is in flight when the call
returns; caller polls for XTC_IO_WRITABLE to detect
completion.
xtc_net_apply_tcp_opts()
applies the knobs to an already-open socket. Useful for sockets returned by
accept(2).
xtc_net_setnonblock()
sets O_NONBLOCK + FD_CLOEXEC
on a fd (POSIX path or) FIONBIO (Windows path).
Unix
domain sockets:
xtc_net_unix_listen()
and
xtc_net_unix_dial()
open AF_UNIX SOCK_STREAM
sockets at the given filesystem path. Listeners auto-unlink the path on bind
failure.
Credential
passing on Unix sockets:
xtc_net_unix_send_creds()
sends a buffer; the receiver, via
xtc_net_unix_recv_creds(),
gets the buffer plus the sender's UID and GID using
SO_PEERCRED (Linux) or
LOCAL_PEERCRED (BSD). On platforms where neither is
available, UID/GID return as 0 without error.
PLATFORM-SPECIFIC NOTES
- Linux
SO_PEERCRED, io_uring + epoll backends.- FreeBSD/macOS
LOCAL_PEERCRED, kqueue backend.- illumos
SO_PEERCREDemulated viagetpeerucred 3C; event ports backend.- Windows
- Winsock2; UDS not supported. TCP only.
EXAMPLES
xtc_tcp_opts_t opts = XTC_TCP_OPTS_DEFAULT;
opts.keepalive = 1;
opts.keepidle_s = 60;
int listen_fd;
xtc_net_listen(XTC_NET_INET, "0.0.0.0", 8080, &opts, &listen_fd);
for (;;) {
uint32_t revents;
int conn_fd;
xtc_proc_wait_fd(listen_fd, XTC_IO_READABLE, -1, &revents);
conn_fd = accept(listen_fd, NULL, NULL);
if (conn_fd < 0) continue;
xtc_net_setnonblock(conn_fd);
xtc_net_apply_tcp_opts(conn_fd, &opts);
/* spawn a per-conn xtc_proc... */
}
SEE ALSO
HISTORY
Appeared in xtc 0.1.
| May 28, 2026 | Debian |