code wiki / _hdl_build / nx_email_live_gate.nx
nx_email_live_gate.nx source
↩ module page · 179 lines · 7959 B
1// nx_email_live_gate.nx -- LIVE LOOPBACK: a real SMTP delivery to
2// self@jasonewest.com, end to end over a socket, every byte OUR stack.
3//
4// fork pattern (per _h2_serve_loopback_gate): parent = the live MTA
5// server (nx_mta_serve_conn = R7 FSM + R4 dedot + R3 store delivery);
6// child = an SMTP CLIENT built from R1 (nx_smtp_client builders +
7// dot-stuffing + reply parse) that connects and sends a real message.
8// After reaping the child the parent FETCHES the delivered message from
9// the store and asserts it is byte-identical to what was sent.
10//
11// GREEN iff: client walked 220->EHLO->MAIL->RCPT->DATA(354)->body->250
12// ->QUIT(221) with matching codes; the server delivered 1 copy; and the
13// stored message for self@jasonewest.com equals the sent body exactly.
14//
15// Evidence -> knowledge/status/jmail_live.log (JMAILGATE ... verdict=GREEN)
16// license_tier: ORIGINAL
17import "nx_email_mta_io.nx"
18import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host
19import "nx_smtp_client.nx"
20import "nx_syscalls.nx"
21
22const JM_PORT: i64 = 0x2444 // 9284
23const JM_LOG: *u8 = "knowledge/status/jmail_live.log"
24const JM_PREFIX: *u8 = "knowledge/status/jmail/"
25const JM_DOMAIN: *u8 = "jasonewest.com"
26const JM_MBOX: *u8 = "self@jasonewest.com"
27
28func g_addr(out: *u8, port: i64) -> i64 {
29 out[0] = 2 as u8; out[1] = 0 as u8
30 out[2] = ((port >> 8) & 0xff) as u8
31 out[3] = (port & 0xff) as u8
32 out[4] = 127 as u8; out[5] = 0 as u8; out[6] = 0 as u8; out[7] = 1 as u8
33 var i: i64 = 8
34 while i < 16 { out[i] = 0 as u8; i = i + 1 }
35 return 0
36}
37func g_write(fd: i64, buf: *u8, n: i64) -> i64 {
38 var w: i64 = 0
39 while w < n { let k: i64 = sys_write(fd, (buf as i64 + w) as *u8, n - w); if k <= 0 { return 0 - 1 } w = w + k }
40 return 0
41}
42func g_recv_line(fd: i64, buf: *u8, cap: i64) -> i64 {
43 var i: i64 = 0
44 while i < cap - 1 {
45 let r: i64 = sys_read(fd, (buf as i64 + i) as *u8, 1)
46 if r <= 0 { return i }
47 let c: i64 = buf[i] & 0xff
48 i = i + 1
49 if c == 10 { return i }
50 }
51 return i
52}
53func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
54func memeq(a: *u8, b: *u8, len: i64) -> i64 { var i: i64 = 0; while i < len { if a[i] != b[i] { return 0 } i = i + 1 } return 1 }
55
56// read one (possibly multiline) SMTP reply, return its code or -1.
57func g_read_reply(fd: i64, buf: *u8, cmpl: *i64, cons: *i64) -> i64 {
58 var total: i64 = 0
59 var code: i64 = 0 - 1
60 var done: i64 = 0
61 while done == 0 {
62 let l: i64 = g_recv_line(fd, (buf as i64 + total) as *u8, 4096 - total)
63 if l <= 0 { done = 1 } else {
64 total = total + l
65 let c: i64 = nx_smtp_parse_reply(buf, total, cmpl, cons)
66 if c >= 0 && *cmpl == 1 { code = c; done = 1 }
67 }
68 }
69 return code
70}
71
72// child: the SMTP client. Sends `stuffed` (dot-stuffed body incl
73// terminator) of length dslen. Returns 0 ok / named code on failure.
74func g_run_client(addr: *u8, stuffed: *u8, dslen: i64) -> i64 {
75 var spin: i64 = 0
76 while spin < 400000 { spin = spin + 1 }
77 let cfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
78 if cfd < 0 { return 11 }
79 if nx_connect_bounded(cfd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { return 12 }
80 let rbuf: *u8 = sys_mmap(4096)
81 let snd: *u8 = sys_mmap(4096)
82 let cmpl: *i64 = sys_mmap(8) as *i64
83 let cons: *i64 = sys_mmap(8) as *i64
84
85 if g_read_reply(cfd, rbuf, cmpl, cons) != 220 { return 20 }
86 var l: i64 = nx_smtp_build_ehlo(snd, 4096, "client.remote" as *u8, 13)
87 g_write(cfd, snd, l)
88 let c1: i64 = g_read_reply(cfd, rbuf, cmpl, cons)
89 if c1 < 200 || c1 >= 300 { return 21 }
90 l = nx_smtp_build_mail_from(snd, 4096, "alice@remote.test" as *u8, 17)
91 g_write(cfd, snd, l)
92 let c2: i64 = g_read_reply(cfd, rbuf, cmpl, cons)
93 if c2 < 200 || c2 >= 300 { return 22 }
94 l = nx_smtp_build_rcpt_to(snd, 4096, JM_MBOX, slen(JM_MBOX))
95 g_write(cfd, snd, l)
96 let c3: i64 = g_read_reply(cfd, rbuf, cmpl, cons)
97 if c3 < 200 || c3 >= 300 { return 23 }
98 l = nx_smtp_build_simple(snd, 4096, "DATA" as *u8)
99 g_write(cfd, snd, l)
100 if g_read_reply(cfd, rbuf, cmpl, cons) != 354 { return 24 }
101 g_write(cfd, stuffed, dslen)
102 let c5: i64 = g_read_reply(cfd, rbuf, cmpl, cons)
103 if c5 < 200 || c5 >= 300 { return 25 }
104 l = nx_smtp_build_simple(snd, 4096, "QUIT" as *u8)
105 g_write(cfd, snd, l)
106 g_read_reply(cfd, rbuf, cmpl, cons)
107 sys_close(cfd)
108 return 0
109}
110
111func jm_log(green: i64, delivered: i64, child_code: i64) -> i64 {
112 let fd: i64 = sys_openat_append(JM_LOG, 420)
113 if fd < 0 { return 0 }
114 g_write(fd, "JMAILGATE authored=organ live=loopback-smtp domain=jasonewest.com mailbox=self@jasonewest.com " as *u8, slen("JMAILGATE authored=organ live=loopback-smtp domain=jasonewest.com mailbox=self@jasonewest.com " as *u8))
115 if green == 1 { g_write(fd, "delivered=1 fetch_byteexact=PASS verdict=GREEN\n" as *u8, slen("delivered=1 fetch_byteexact=PASS verdict=GREEN\n" as *u8)) }
116 else { g_write(fd, "verdict=RED\n" as *u8, slen("verdict=RED\n" as *u8)) }
117 sys_close(fd)
118 return 0
119}
120
121func main() -> i64 {
122 // reset store dir
123 sys_mkdir("knowledge/status/jmail" as *u8, 511)
124 let rfd: i64 = sys_openat_wr("knowledge/status/jmail/manifest.txt" as *u8, 420)
125 if rfd >= 0 { sys_close(rfd) }
126
127 // the message + its dot-stuffed DATA payload (shared pre-fork)
128 let msg: *u8 = "Subject: First real delivery\r\nFrom: alice@remote.test\r\nTo: self@jasonewest.com\r\nDate: Sat, 14 Jun 2026 00:00:00 +0000\r\n\r\nHello self. This is the first message delivered over the sovereign wire.\r\n" as *u8
129 let mlen: i64 = slen(msg)
130 let stuffed: *u8 = sys_mmap(8192)
131 let dslen: i64 = nx_smtp_dot_stuff(msg, mlen, stuffed, 8192)
132
133 let addr: *u8 = sys_mmap(16)
134 g_addr(addr, JM_PORT)
135 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
136 if lfd < 0 { jm_log(0, 0, 0); sys_exit(93); return 93 }
137 if sys_bind(lfd, addr, 16) < 0 { jm_log(0, 0, 0); sys_exit(94); return 94 }
138 if sys_listen(lfd, 4) < 0 { jm_log(0, 0, 0); sys_exit(95); return 95 }
139
140 let pid: i64 = sys_fork()
141 if pid < 0 { jm_log(0, 0, 0); sys_exit(96); return 96 }
142 if pid == 0 {
143 let crc: i64 = g_run_client(addr, stuffed, dslen)
144 sys_exit(crc); return crc
145 }
146
147 let scfd: i64 = sys_accept(lfd)
148 if scfd < 0 { jm_log(0, 0, 0); sys_exit(97); return 97 }
149 let delivered: i64 = nx_mta_serve_conn(scfd, JM_PREFIX, JM_DOMAIN, slen(JM_DOMAIN), 1)
150 sys_close(scfd)
151
152 let status: *i64 = sys_mmap(8) as *i64
153 sys_wait4(pid, status, 0)
154 let child_code: i64 = (status[0] >> 8) & 0xff
155
156 // verify the stored message
157 let pp: *i64 = sys_mmap(8) as *i64
158 let ll: *i64 = sys_mmap(8) as *i64
159 var fetch_ok: i64 = 0
160 let cnt: i64 = nx_mbox_count(JM_PREFIX, JM_MBOX)
161 if cnt == 1 && nx_mbox_get_n(JM_PREFIX, JM_MBOX, 0, pp, ll) == 1 {
162 if ll[0] == mlen && memeq(pp[0] as *u8, msg, mlen) == 1 { fetch_ok = 1 }
163 }
164
165 var green: i64 = 0
166 if child_code == 0 && delivered >= 1 && fetch_ok == 1 { green = 1 }
167
168 g_write(1, "JMAILGATE authored=organ live=loopback-smtp mailbox=self@jasonewest.com child_code=" as *u8, slen("JMAILGATE authored=organ live=loopback-smtp mailbox=self@jasonewest.com child_code=" as *u8))
169 // print child_code + delivered + verdict
170 let nb: *u8 = sys_mmap(8); nb[0] = (48 + (child_code % 10)) as u8; g_write(1, nb, 1)
171 g_write(1, " delivered=" as *u8, 11)
172 let db: *u8 = sys_mmap(8); db[0] = (48 + (delivered % 10)) as u8; g_write(1, db, 1)
173 if green == 1 { g_write(1, " fetch_byteexact=PASS verdict=GREEN\n" as *u8, slen(" fetch_byteexact=PASS verdict=GREEN\n" as *u8)) }
174 else { g_write(1, " verdict=RED\n" as *u8, slen(" verdict=RED\n" as *u8)) }
175 jm_log(green, delivered, child_code)
176
177 if green == 1 { sys_exit(0); return 0 }
178 sys_exit(1); return 1
179}