nx_dns_server_daemon.nx source
↩ module page · 99 lines · 3568 B
1// nx_dns_server_daemon.nx -- live authoritative DNS daemon.
2//
3// Closes the DNS half of the sovereign hosting chain. Companion to
4// nx_audit_server_daemon.nx (TCP/HTTP daemon). Composes:
5//
6// nx_dns_authoritative.nx -- zone-table + query parse + response build
7// sys_socket / sys_bind / sys_recvfrom / sys_sendto (UDP)
8//
9// Binds to 127.0.0.1:5353 by default (unprivileged port; production
10// :53 requires CAP_NET_BIND_SERVICE or root). Per cardinal
11// user-owns-every-bit: caller picks the port. Per cardinal feedback-
12// bounded-loop-discipline: 1M-request budget on the accept loop.
13//
14// Zone configuration: hard-coded for this v0 to
15// nishifamily.com -> 192.0.2.42
16// audit.nishifamily.com -> 192.0.2.43
17// Future: read from a TOML / JSONL zone file via shipped nx_toml or
18// nx_jsonl primitives.
19//
20// expect_exit: 0 (clean exit after 1M-request budget; in normal
21// daemon operation the supervisor wrapper restarts).
22
23import "nx_syscalls_x86_64.nx"
24import "nx_dns_authoritative.nx"
25const NXDS_MAGIC_1024: i64 = 1024
26
27const NXDS_PORT: i64 = 5353
28const NXDS_REQ_CAP: i64 = 4096 // RFC 1035 ยง2.3.4 max UDP
29const NXDS_RESP_CAP: i64 = 4096
30const NXDS_REQUEST_BUDGET: i64 = 1000000
31const SOCK_DGRAM: i64 = 2
32
33func main() -> i64 {
34 // ---- Build sockaddr_in: 127.0.0.1:5353 (loopback) ----
35 let addr: *u8 = sys_mmap(16)
36 // AF_INET LE
37 addr[0] = 2 as u8; addr[1] = 0 as u8
38 // port 5353 BE
39 addr[2] = ((NXDS_PORT >> 8) & 0xff) as u8
40 addr[3] = (NXDS_PORT & 0xff) as u8
41 // 127.0.0.1
42 addr[4] = 127 as u8; addr[5] = 0 as u8; addr[6] = 0 as u8; addr[7] = 1 as u8
43 // padding
44 addr[8] = 0 as u8; addr[9] = 0 as u8
45 addr[10] = 0 as u8; addr[11] = 0 as u8
46 addr[12] = 0 as u8; addr[13] = 0 as u8
47 addr[14] = 0 as u8; addr[15] = 0 as u8
48
49 // ---- Socket: UDP / AF_INET ----
50 let fd: i64 = sys_socket(2, SOCK_DGRAM, 0)
51 if fd < 0 { return 10 }
52
53 // ---- Bind ----
54 let brc: i64 = sys_bind(fd, addr, 16)
55 if brc < 0 {
56 sys_close(fd)
57 return 20
58 }
59
60 // ---- Initialize zone table ----
61 let zone_raw: *u8 = sys_mmap(NX_DNS_ZONE_BYTES)
62 let zone: *NxDnsZone = zone_raw as *NxDnsZone
63 let names_buf: *u8 = sys_mmap(NXDS_MAGIC_1024)
64 let zrc: i64 = nx_dns_zone_init(zone, 64, names_buf, NXDS_MAGIC_1024)
65 if zrc != NXDA_OK {
66 sys_close(fd)
67 return 30
68 }
69 nx_dns_zone_add_a(zone, "nishifamily.com" as *u8, 15, 192, 0, 2, 42)
70 nx_dns_zone_add_a(zone, "audit.nishifamily.com" as *u8, 21, 192, 0, 2, 43)
71
72 // ---- Bounded recvfrom loop ----
73 var n_served: i64 = 0
74 while n_served < NXDS_REQUEST_BUDGET {
75 let req_buf: *u8 = sys_mmap(NXDS_REQ_CAP)
76 let src_addr: *u8 = sys_mmap(16)
77 let addrlen: *i64 = sys_mmap(8) as *i64
78 addrlen[0] = 16
79 let n_req: i64 = sys_recvfrom(fd, req_buf, NXDS_REQ_CAP, src_addr, addrlen)
80 if n_req <= 0 {
81 // recvfrom failed; continue (supervisor catches repeated failures).
82 n_served = n_served + 1
83 if n_served >= NXDS_REQUEST_BUDGET { return 0 }
84 }
85
86 if n_req > 0 {
87 let resp_buf: *u8 = sys_mmap(NXDS_RESP_CAP)
88 let n_resp: i64 = nx_dns_serve_query(zone, req_buf, n_req,
89 resp_buf, NXDS_RESP_CAP)
90 if n_resp > 0 {
91 sys_sendto(fd, resp_buf, n_resp, src_addr, addrlen[0])
92 }
93 n_served = n_served + 1
94 }
95 }
96
97 sys_close(fd)
98 return 0
99}