SafeAPI Backend POSIX
POSIX/Linux OAL backend for safeAPIFreamwork
Loading...
Searching...
No Matches
sapi_posix_backend_netlink.c File Reference

POSIX sapi_netlink backend: 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...

#include "safeapi/posix_backend/sapi_posix_backend.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "safeapi/oal/memory/sapi_mem_util.h"
#include "safeapi/oal/log/sapi_log.h"
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
Include dependency graph for sapi_posix_backend_netlink.c:

Go to the source code of this file.

Data Structures

Macros

#define _POSIX_C_SOURCE   200809L
#define POSIX_NETLINK_UDP_HELLO   ((uint8_t)0xA5U)
#define POSIX_NETLINK_UDP_HELLO_ACK   ((uint8_t)0x5AU)
#define POSIX_NETLINK_UDP_HELLO_PERIOD_MS   (20U)

Typedefs

typedef char posix_netlink_storage_fits_[(sizeof(posix_netlink_state_t)<=sizeof(sapi_netlink_storage_t)) ? 1 :-1]

Functions

static sapi_status_t set_nonblocking (int fd)
static void compute_deadline (sapi_duration_ms_t timeout_ms, struct timespec *out_deadline)
static int remaining_ms (const struct timespec *deadline)
static sapi_status_t open_listen_udp (const sapi_netlink_config_t *config, int *out_fd)
static sapi_status_t open_connect_udp (const sapi_netlink_config_t *config, int *out_fd)
static sapi_status_t backend_open (sapi_netlink_storage_t *storage, const sapi_netlink_config_t *config, sapi_netlink_handle_t *out_handle)
static sapi_status_t backend_send (sapi_netlink_handle_t handle, const void *message, size_t message_size, sapi_duration_ms_t timeout_ms)
static sapi_status_t backend_receive (sapi_netlink_handle_t handle, void *out_message, size_t buffer_size, sapi_duration_ms_t timeout_ms)
static sapi_status_t backend_close (sapi_netlink_handle_t handle)
const sapi_netlink_backend_t * sapi_posix_backend_netlink (void)
 The POSIX sapi_netlink backend (TCP sockets, LISTEN/CONNECT).

Variables

static const sapi_netlink_backend_t s_posix_netlink_backend

Detailed Description

POSIX sapi_netlink backend: 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 learns exactly one peer from the first valid HELLO it sees and connect()s to it - this backend models a single fixed point-to-point link (matching sapi_netlink's own scope), not a server accepting many clients.
  • No transport-level "peer disconnected" signal: UDP has no connection to tear down, so unlike the old TCP backend this one essentially never returns SAPI_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. sapi_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 backend 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 (SAPI_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.

Definition in file sapi_posix_backend_netlink.c.

Macro Definition Documentation

◆ _POSIX_C_SOURCE

#define _POSIX_C_SOURCE   200809L

Definition at line 1 of file sapi_posix_backend_netlink.c.

◆ POSIX_NETLINK_UDP_HELLO

#define POSIX_NETLINK_UDP_HELLO   ((uint8_t)0xA5U)

Handshake magic bytes - see this file's header for why these can never be confused with real application traffic once a link is open.

Definition at line 61 of file sapi_posix_backend_netlink.c.

◆ POSIX_NETLINK_UDP_HELLO_ACK

#define POSIX_NETLINK_UDP_HELLO_ACK   ((uint8_t)0x5AU)

Definition at line 62 of file sapi_posix_backend_netlink.c.

◆ POSIX_NETLINK_UDP_HELLO_PERIOD_MS

#define POSIX_NETLINK_UDP_HELLO_PERIOD_MS   (20U)

How often CONNECT re-sends HELLO while waiting for HELLO_ACK. Kept short: on a real multi-process startup, several links establish in sequence (e.g. a process opens its peer link before its negotiation link), and each CONNECT-role link's own convergence time adds to that chain - a coarser retry period here cascades into a much larger total startup latency across the whole topology, which callers with a tight end-to-end budget (e.g. SAFEAPI_EXAMPLE_AB_CHECKPOINT_MAX_DELAY_MS) can then exceed even though steady-state round-trip latency is fast.

Definition at line 71 of file sapi_posix_backend_netlink.c.

Typedef Documentation

◆ posix_netlink_storage_fits_

typedef char posix_netlink_storage_fits_[(sizeof(posix_netlink_state_t)<=sizeof(sapi_netlink_storage_t)) ? 1 :-1]

Definition at line 81 of file sapi_posix_backend_netlink.c.

Function Documentation

◆ backend_close()

sapi_status_t backend_close ( sapi_netlink_handle_t handle)
static

Definition at line 643 of file sapi_posix_backend_netlink.c.

◆ backend_open()

sapi_status_t backend_open ( sapi_netlink_storage_t * storage,
const sapi_netlink_config_t * config,
sapi_netlink_handle_t * out_handle )
static

Definition at line 451 of file sapi_posix_backend_netlink.c.

◆ backend_receive()

sapi_status_t backend_receive ( sapi_netlink_handle_t handle,
void * out_message,
size_t buffer_size,
sapi_duration_ms_t timeout_ms )
static

Definition at line 555 of file sapi_posix_backend_netlink.c.

◆ backend_send()

sapi_status_t backend_send ( sapi_netlink_handle_t handle,
const void * message,
size_t message_size,
sapi_duration_ms_t timeout_ms )
static

Definition at line 490 of file sapi_posix_backend_netlink.c.

◆ compute_deadline()

void compute_deadline ( sapi_duration_ms_t timeout_ms,
struct timespec * out_deadline )
static

Definition at line 99 of file sapi_posix_backend_netlink.c.

◆ open_connect_udp()

sapi_status_t open_connect_udp ( const sapi_netlink_config_t * config,
int * out_fd )
static

Definition at line 279 of file sapi_posix_backend_netlink.c.

◆ open_listen_udp()

sapi_status_t open_listen_udp ( const sapi_netlink_config_t * config,
int * out_fd )
static

Definition at line 131 of file sapi_posix_backend_netlink.c.

◆ remaining_ms()

int remaining_ms ( const struct timespec * deadline)
static

Milliseconds remaining until deadline, clamped to >= 0; -1 if now() itself fails (caller treats that as "no time left").

Definition at line 113 of file sapi_posix_backend_netlink.c.

◆ sapi_posix_backend_netlink()

const sapi_netlink_backend_t * sapi_posix_backend_netlink ( void )

The POSIX sapi_netlink backend (TCP sockets, LISTEN/CONNECT).

Definition at line 658 of file sapi_posix_backend_netlink.c.

◆ set_nonblocking()

sapi_status_t set_nonblocking ( int fd)
static

Definition at line 84 of file sapi_posix_backend_netlink.c.

Variable Documentation

◆ s_posix_netlink_backend

const sapi_netlink_backend_t s_posix_netlink_backend
static
Initial value:
= { backend_open, backend_send, backend_receive,
backend_close }

Definition at line 655 of file sapi_posix_backend_netlink.c.