code wiki / (root) / nx_dns_client_probe.nx

nx_dns_client_probe.nx source

↩ module page · 84 lines · 2764 B

1// nx_dns_client_probe.nx -- substrate-side UDP DNS verifier. 2// 3// Sends a real DNS query to 127.0.0.1:5353 + verifies the answer. 4// Used by bench/nx_dns_serve_loopback.sh as the live verification 5// step for the DNS daemon. Sovereign per cardinal: no dig, no 6// nslookup, no python; substrate talks to substrate. 7// 8// Returns 0 on success (answer matches expected RDATA 192.0.2.42) 9// or a numeric error code per failure mode. 10// 11// expect_exit: 0 12 13import "nx_syscalls_x86_64.nx" 14import "nx_dns.nx" 15const SOCK_MAGIC_5353: i64 = 5353 16 17const SOCK_DGRAM_C: i64 = 2 18 19func bytes_eq(a: *u8, b: *u8, n: i64) -> i64 { 20 var i: i64 = 0 21 while i < n { 22 if a[i] != b[i] { return 0 } 23 i = i + 1 24 } 25 return 1 26} 27 28func main() -> i64 { 29 // Build sockaddr_in 127.0.0.1:5353 30 let addr: *u8 = sys_mmap(16) 31 addr[0] = 2 as u8; addr[1] = 0 as u8 32 addr[2] = 0x14 as u8; addr[3] = 0xe9 as u8 // port SOCK_MAGIC_5353 BE 33 addr[4] = 127 as u8; addr[5] = 0 as u8; addr[6] = 0 as u8; addr[7] = 1 as u8 34 addr[8] = 0 as u8; addr[9] = 0 as u8 35 addr[10] = 0 as u8; addr[11] = 0 as u8 36 addr[12] = 0 as u8; addr[13] = 0 as u8 37 addr[14] = 0 as u8; addr[15] = 0 as u8 38 39 // UDP socket 40 let fd: i64 = sys_socket(2, SOCK_DGRAM_C, 0) 41 if fd < 0 { return 10 } 42 43 // Build query for nishifamily.com 44 let qbuf: *u8 = sys_mmap(128) 45 let qn: i64 = nx_dns_build_query("nishifamily.com" as *u8, 15, 46 NX_DNS_TYPE_A, 0x1234, 47 qbuf, 128) 48 if qn < 0 { sys_close(fd); return 20 } 49 50 // sendto 51 let sent: i64 = sys_sendto(fd, qbuf, qn, addr, 16) 52 if sent < 0 { sys_close(fd); return 30 } 53 54 // recvfrom 55 let rbuf: *u8 = sys_mmap(512) 56 let from_addr: *u8 = sys_mmap(16) 57 let from_alen: *i64 = sys_mmap(8) as *i64 58 from_alen[0] = 16 59 let n_recv: i64 = sys_recvfrom(fd, rbuf, 512, from_addr, from_alen) 60 sys_close(fd) 61 if n_recv < 0 { return 40 } 62 if n_recv < 12 { return 41 } 63 64 // Verify response shape: 65 // tx_id echo (0x1234) 66 if rbuf[0] != 0x12 as u8 { return 50 } 67 if rbuf[1] != 0x34 as u8 { return 51 } 68 // QR=1 + AA=1 + rcode=0 => flags = 0x8400 69 if rbuf[2] != 0x84 as u8 { return 52 } 70 if rbuf[3] != 0x00 as u8 { return 53 } 71 // QDCOUNT = 1 72 if rbuf[5] != 1 as u8 { return 54 } 73 // ANCOUNT = 1 74 if rbuf[7] != 1 as u8 { return 55 } 75 76 // Parse the answer's RDATA (skip header + question + answer header). 77 // Expected RDATA: 192.0.2.42 in the LAST 4 bytes of the packet. 78 if rbuf[n_recv - 4] != 192 as u8 { return 60 } 79 if rbuf[n_recv - 3] != 0 as u8 { return 61 } 80 if rbuf[n_recv - 2] != 2 as u8 { return 62 } 81 if rbuf[n_recv - 1] != 42 as u8 { return 63 } 82 83 return 0 84}