nx_udp.nx source
↩ module page · 99 lines · 3845 B
1// nx_udp.nx -- sovereign UDP socket primitives.
2//
3// Phase 0 of the Nishi comms stack per docs/NISHI_COMMS_ROADMAP.md.
4// Open a UDP socket, optionally bind to a port, send + receive
5// packets. No libc. No external networking library.
6//
7// What it does today:
8// - open UDP socket (SOCK_DGRAM)
9// - bind to a local port (for receiving)
10// - sendto an IPv4 dest
11// - recvfrom into a caller buffer
12//
13// What it doesn't do yet:
14// - DNS lookup (caller packs IPv4 manually). L21b queued.
15// - IPv6. Phase 1+.
16// - Multicast. Niche; later.
17// - Connected-UDP convenience. Trivial wrap.
18//
19// genealogy_id: rfc_768_udp + linux_socket_api + rfc_5389_stun
20// lineage_id: nishi_comms_udp_floor_q10
21//
22// nx_safety_envelope:
23// intended_use: "UDP socket primitives -- foundation for
24// DNS, NTP, STUN, IoT discovery, low-latency
25// comms"
26// sil_target: SIL2 (network primitive; failure modes
27// include reorder / drop / spoof
28// which higher layers must handle)
29// asil_target: QM
30// dal_target: DAL C
31// evidence: [POSIX_socket_classical_basis,
32// sealed_verdict_enum, no_FP,
33// sys_sendto_recvfrom_balance_audited]
34// hazard_register: [bug-tape-source-address-spoofing-trusted,
35// bug-tape-fragment-reassembly-DoS,
36// bug-tape-amplification-attack-reflector]
37// residual_risk: "UDP has NO authentication. Caller MUST
38// treat source addresses as untrusted.
39// Amplification mitigation requires response-
40// size limits (upstream). Substrate provides
41// bytes-only; semantics are protocol-specific."
42// verdict: NOT_YET_EVALUATED
43
44import "nx_syscalls_x86_64.nx"
45
46// Sealed verdict for a UDP operation.
47const NX_UDP_VERDICT_UNKNOWN: i64 = 0
48const NX_UDP_VERDICT_OK: i64 = 1
49const NX_UDP_VERDICT_SOCKET_FAIL: i64 = 2
50const NX_UDP_VERDICT_BIND_FAIL: i64 = 3
51const NX_UDP_VERDICT_SEND_FAIL: i64 = 4
52const NX_UDP_VERDICT_RECV_FAIL: i64 = 5
53const NX_UDP_VERDICT_N: i64 = 6
54
55const SOCK_DGRAM: i64 = 2
56
57// Open a UDP socket. Returns fd or -errno.
58func nx_udp_open() -> i64 {
59 return sys_socket(AF_INET, SOCK_DGRAM, 0)
60}
61
62// Bind a UDP socket to (INADDR_ANY, port). Returns 0 / -errno.
63func nx_udp_bind_any(fd: i64, port: i64) -> i64 {
64 let addr: *u8 = sys_mmap(16)
65 sockaddr_in_init(addr, port)
66 return sys_bind(fd, addr, 16)
67}
68
69// Pack an IPv4 dest sockaddr at `out` (16 bytes). Caller's
70// convenience helper; identical layout to sockaddr_in_init but for an
71// outbound dest rather than a bind-self address.
72func nx_udp_sockaddr_dest(out: *u8, a: i64, b: i64, c: i64, d: i64, port: i64) -> i64 {
73 out[0] = 2; out[1] = 0
74 out[2] = (port >> 8) & 0xff
75 out[3] = port & 0xff
76 out[4] = a; out[5] = b; out[6] = c; out[7] = d
77 out[8] = 0; out[9] = 0; out[10] = 0; out[11] = 0
78 out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 0
79 return 16
80}
81
82// Send a UDP datagram. Returns bytes sent or -errno.
83func nx_udp_send(fd: i64, buf: *u8, n: i64, addr16: *u8) -> i64 {
84 return sys_sendto(fd, buf, n, addr16, 16)
85}
86
87// Receive a UDP datagram. Returns bytes received or -errno.
88// `peer_addr` (if non-NULL) gets the sender's 16-byte sockaddr_in;
89// `peer_addr_len` is in/out (caller sets to 16, kernel fills actual).
90func nx_udp_recv(fd: i64, buf: *u8, n: i64, peer_addr: *u8, peer_addr_len: *i64) -> i64 {
91 return sys_recvfrom(fd, buf, n, peer_addr, peer_addr_len)
92}
93
94// Sealed-enum validity gate.
95func nx_udp_verdict_is_valid(v: i64) -> i64 {
96 if v < 0 { return 0 }
97 if v >= NX_UDP_VERDICT_N { return 0 }
98 return 1
99}