code wiki / (root) / nx_udp.nx

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}