POSIX rte_netlink OSAdapter: IPv4 UDP sockets. LISTEN binds and learns its one peer from that peer's first HELLO datagram; CONNECT dials and retries HELLO until the peer's HELLO_ACK arrives. Both sides then connect() the datagram socket to its one fixed peer, so ordinary send()/recv() (no *_to/_from) carry every later message - see ADR-027.
More...
|
| static rte_status_t | set_nonblocking (int fd) |
| static void | compute_deadline (rte_duration_ms_t timeout_ms, struct timespec *out_deadline) |
| static bool | same_peer (const struct sockaddr_in *a, const struct sockaddr_in *b) |
| static rte_status_t | open_listen_udp (const rte_netlink_config_t *config, int *out_fd, struct sockaddr_in *out_peer, socklen_t *out_peer_len) |
| static rte_status_t | open_connect_udp (const rte_netlink_config_t *config, int *out_fd) |
| static rte_status_t | osadapter_open (rte_netlink_storage_t *storage, const rte_netlink_config_t *config, rte_netlink_handle_t *out_handle) |
| static rte_status_t | backend_send (rte_netlink_handle_t handle, const void *message, size_t message_size, rte_duration_ms_t timeout_ms) |
| static rte_status_t | backend_receive (rte_netlink_handle_t handle, void *out_message, size_t buffer_size, rte_duration_ms_t timeout_ms) |
| static rte_status_t | osadapter_close (rte_netlink_handle_t handle) |
| const rte_osadapter_netlink_t * | rte_posix_osadapter_netlink (void) |
| | The POSIX rte_netlink OSAdapter (TCP sockets, LISTEN/CONNECT).
|
POSIX rte_netlink OSAdapter: IPv4 UDP sockets. LISTEN binds and learns its one peer from that peer's first HELLO datagram; CONNECT dials and retries HELLO until the peer's HELLO_ACK arrives. Both sides then connect() the datagram socket to its one fixed peer, so ordinary send()/recv() (no *_to/_from) carry every later message - see ADR-027.
Known simplifications, stated plainly (this is a demo-grade first cut, not a hardened network stack):
- IPv4 only (AF_INET). IPv6 would need a second code path or an AF_UNSPEC + address-family-agnostic sockaddr_storage rewrite.
- LISTEN serves exactly one peer at a time - this OSAdapter models a single point-to-point link (matching rte_netlink's own scope), not a server accepting many clients - but it does NOT connect() its socket (a connected UDP socket drops datagrams from any other source, so a restarted peer on a new source port was never heard again). It stores the peer's address, re-learns it on every HELLO (answering with the ACK) and sends with sendto(). A listener that itself restarts takes the first datagram from a still-running peer as that peer's identity, since such a peer sends no new HELLO. The CONNECT role is unchanged (connect()ed socket).
- No transport-level "peer disconnected" signal: UDP has no connection to tear down, so unlike the old TCP OSAdapter this one essentially never returns RTE_STATUS_HARDWARE_FAULT spontaneously. The one exception is ECONNREFUSED, which Linux surfaces on a connected UDP socket's next send()/recv() after an ICMP Port-Unreachable arrives (e.g. the peer process exited and closed its socket) - this is opportunistic and best-effort (silently suppressed by many NATs/firewalls, and never fires for a merely slow or partitioned peer), NOT the primary liveness mechanism. Detecting a truly stuck/gone peer is now the caller's job (e.g. rte_dual_channel's ACK timeout, or an application-level staleness timer) - see ADR-027.
- Each send()/receive() call transfers exactly one datagram, never more or less - there is no byte-accumulation loop like a TCP OSAdapter needs, since UDP already preserves message boundaries. A received datagram whose length doesn't match this link's configured message_size is treated as a wire protocol violation (RTE_STATUS_DATA_CORRUPTION), not silently truncated or padded.
- No TLS/authentication: this is a plaintext link, appropriate for a demo on localhost or a trusted network, not for anything exposed to an untrusted network.
- Every wait is one poll() of at most min(time left, INT_MAX) ms (posix_remaining_ms(), rte_posix_osadapter_poll.h): a send/receive timeout or connect_timeout_ms above INT_MAX ms (about 24.8 days) waits INT_MAX ms per poll(), where it used to end at once.
- Socket buffers: the OS default unless config->rcvbuf_bytes / sndbuf_bytes is non-zero; then set and read back before the handshake (posix_socket_apply_buffers(), REQ-OAL-NETLINK-015): a refusal fails the open with RTE_STATUS_INTERNAL_ERROR, a capped size is reported (DEGRADED) and the link kept.
Definition in file rte_posix_osadapter_netlink.c.