code wiki / _hdl_build / _h2_multistream_interop_gate.nx
_h2_multistream_interop_gate.nx source
↩ module page · 275 lines · 13072 B
1// _h2_multistream_interop_gate.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, B1 rung(6)
2// R4-H2-009), NOT credited as team self-authoring (EoE back-fill owed).
3//
4// THE SOVEREIGN EXTERNAL-INTEROP GATE ORGAN for persistent multi-stream h2. This
5// REPLACES the ad-hoc inline curl orchestration I ran by hand at rung(6) (and the
6// kind of committed .sh harness BL-025 forbids) with a SINGLE self-contained
7// sovereign organ: it stands up OUR persistent multi-stream ALPN-h2 server AND
8// drives an EXTERNAL curl --http2 against it AND emits a machine-checkable verdict
9// -- all in one process tree, no shell, no committed script. Run it and it tells
10// you GREEN/RED; nothing to orchestrate by hand.
11//
12// TOPOLOGY (design B -- self-contained, chosen because the runtime has no
13// sys_unlink/sys_nanosleep so composing the prebuilt daemon ELF would race on a
14// STALE cert.pem; here the PARENT mints a FRESH cert each run and binds BEFORE
15// forking, so there is no stale-key risk and no readiness race):
16// parent: mint fresh Ed25519 SAN=localhost leaf (shared nx_h2_test_leaf) +
17// export PEM /tmp/nx_h2_gate_cert.pem + bind 127.0.0.1:9445 + listen.
18// pipe2 -> fork:
19// child : dup3 pipe-write over stdout, execve /usr/bin/curl --http2 with 4
20// same-origin URLs (the multiplex/reuse test) + -w num_connects.
21// parent: accept ONE connection -> h2_serve_connection_multi (cap=16) ->
22// served count; drain curl's captured stdout; wait4 curl -> exit.
23// VERDICT GREEN iff: served == 4 (4 streams answered on the ONE accepted conn)
24// AND curl_exit == 0 (every transfer succeeded) AND http200_count == 4 AND
25// newconn_count == 1 (curl opened exactly ONE TCP connection for all 4 transfers
26// = real reuse/multiplex, the discriminating measurement). curl is the LAST-MILE
27// interop ORACLE (nghttp2/OpenSSL) -- unfakeable; OUR side is 100% sovereign.
28//
29// HONEST scope: ONE connection / 4 sequential-or-multiplexed streams (curl decides
30// reuse vs multiplex; both prove persistence). This organ is the REPRODUCIBLE
31// gate; the rung(6) capability itself is R4-H2-008 (already DONE).
32//
33// COMPOSES (each imported once): nx_h2_serve_multi (the persistent driver +
34// transitive framing/tls transport stones), nx_h2_test_leaf (shared cert/PEM),
35// nx_x25519_ephemeral + nx_csprng (per-connection handshake entropy), nx_syscalls
36// (sockets/fork/execve/pipe/wait4/dup3).
37//
38// license_tier: INDEPENDENT_REDERIVE
39// genealogy_id: international-research-sources/ietf/rfc_9113 + rfc_7301 + rfc_8446
40// lineage_id: nishi_h2_multistream_interop_gate_b1r6
41
42import "nx_syscalls.nx"
43import "nx_h2_serve_multi.nx"
44import "nx_h2_test_leaf.nx"
45import "nx_x25519_ephemeral.nx"
46import "nx_csprng.nx"
47
48const IG_PORT_REAL: i64 = 9445
49const IG_NURLS: i64 = 4
50
51func ig_addr(out: *u8, port: i64) -> i64 {
52 out[0] = 2 as u8; out[1] = 0 as u8
53 out[2] = ((port >> 8) & 0xff) as u8
54 out[3] = (port & 0xff) as u8
55 out[4] = 127 as u8; out[5] = 0 as u8; out[6] = 0 as u8; out[7] = 1 as u8
56 var i: i64 = 8
57 while i < 16 { out[i] = 0 as u8; i = i + 1 }
58 return 0
59}
60
61// count non-overlapping occurrences of pat[0..patlen) in buf[0..blen). (NB: do
62// NOT name the inner flag 'match' -- it is a NishiLang reserved keyword that
63// silently compiles to an empty .s; use 'same'.)
64func ig_count_sub(buf: *u8, blen: i64, pat: *u8, patlen: i64) -> i64 {
65 var c: i64 = 0
66 var i: i64 = 0
67 while i + patlen <= blen {
68 var same: i64 = 1
69 var j: i64 = 0
70 while j < patlen {
71 if buf[i + j] != pat[j] { same = 0; j = patlen } else { j = j + 1 }
72 }
73 if same == 1 { c = c + 1 }
74 i = i + 1
75 }
76 return c
77}
78
79func ig_wn(fd: i64, v: i64) -> i64 {
80 var x: i64 = v; if x < 0 { sys_write(fd, "-" as *u8, 1); x = 0 - x }
81 let t: *u8 = sys_mmap(28); var k: i64 = 0
82 if x == 0 { t[0] = 48 as u8; k = 1 }
83 while x > 0 { t[k] = (48 + (x % 10)) as u8; x = x / 10; k = k + 1 }
84 while k > 0 { k = k - 1; sys_write(fd, (((t as i64) + k) as *u8), 1) }
85 return 0
86}
87
88func ig_log(green: i64, served: i64, curl_exit: i64, h200: i64, newconn: i64) -> i64 {
89 let lfd: i64 = sys_openat_append("knowledge/status/h2_multistream.log" as *u8, 0x1a4)
90 if lfd < 0 { return 0 }
91 sys_write(lfd, "B1-R6-H2-INTEROP-GATE organ=_h2_multistream_interop_gate served=" as *u8, 64)
92 ig_wn(lfd, served)
93 sys_write(lfd, " curl_exit=" as *u8, 11); ig_wn(lfd, curl_exit)
94 sys_write(lfd, " http200_count=" as *u8, 15); ig_wn(lfd, h200)
95 sys_write(lfd, " newconn_count=" as *u8, 15); ig_wn(lfd, newconn)
96 if green == 1 {
97 sys_write(lfd, " verdict=GREEN (4 streams on 1 external curl conn, self-contained no .sh)\n" as *u8, 74)
98 } else {
99 sys_write(lfd, " verdict=RED\n" as *u8, 12)
100 }
101 sys_close(lfd)
102 return 0
103}
104
105// write a NUL-terminated literal (length computed -> no off-by-one count bugs).
106func ig_puts(fd: i64, s: *u8) -> i64 {
107 var n: i64 = 0
108 while s[n] != (0 as u8) { n = n + 1 }
109 sys_write(fd, s, n)
110 return 0
111}
112
113// R4-H2-010 advertise gate log line: distinct marker so reconcile can flip the
114// advertise row independently of the interop-gate row.
115func ig_log_adv(adv_ok: i64, interop_green: i64) -> i64 {
116 let lfd: i64 = sys_openat_append("knowledge/status/h2_multistream.log" as *u8, 0x1a4)
117 if lfd < 0 { return 0 }
118 ig_puts(lfd, "B1-R6-H2-MCS-ADVERTISE organ=_h2_multistream_interop_gate SETTINGS_MAX_CONCURRENT_STREAMS=100 byte-KAT=" as *u8)
119 if adv_ok == 1 { ig_puts(lfd, "PASS" as *u8) } else { ig_puts(lfd, "FAIL" as *u8) }
120 ig_puts(lfd, " interop=" as *u8)
121 if interop_green == 1 { ig_puts(lfd, "GREEN" as *u8) } else { ig_puts(lfd, "RED" as *u8) }
122 var av: i64 = 0
123 if adv_ok == 1 { if interop_green == 1 { av = 1 } } // advertise proven iff KAT + curl accepted it
124 if av == 1 { ig_puts(lfd, " verdict=GREEN\n" as *u8) } else { ig_puts(lfd, " verdict=RED\n" as *u8) }
125 sys_close(lfd)
126 return 0
127}
128
129func main() -> i64 {
130 sys_write(1, "_h2_multistream_interop_gate: sovereign self-contained external-curl interop gate (forks curl, no .sh)\n" as *u8, 101)
131
132 // body served on every stream
133 let body: *u8 = sys_mmap(64)
134 let bsrc: *u8 = "hello from nishi h2 interop gate" as *u8
135 var blen: i64 = 0
136 while bsrc[blen] != (0 as u8) { body[blen] = bsrc[blen]; blen = blen + 1 }
137
138 // fresh cert + PEM (shared organ)
139 let cert_der: *u8 = sys_mmap(8192)
140 let cert_len: *i64 = sys_mmap(8) as *i64
141 let ed_priv: *u8 = sys_mmap(32)
142 if h2tl_make_cert(cert_der, cert_len, ed_priv) < 0 {
143 sys_write(1, " FAIL cert mint\n" as *u8, 17); ig_log(0, 0 - 90, 0, 0, 0); sys_exit(90); return 90
144 }
145 let pem_path: *u8 = "/tmp/nx_h2_gate_cert.pem\x00"
146 if h2tl_write_pem(cert_der, cert_len[0], pem_path as *u8) < 0 {
147 sys_write(1, " FAIL pem write\n" as *u8, 17); ig_log(0, 0 - 91, 0, 0, 0); sys_exit(91); return 91
148 }
149
150 // bind + listen BEFORE fork (no readiness race)
151 let addr: *u8 = sys_mmap(16)
152 ig_addr(addr, IG_PORT_REAL)
153 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
154 if lfd < 0 { ig_log(0, 0 - 94, 0, 0, 0); sys_exit(94); return 94 }
155 let optval: *u8 = sys_mmap(4)
156 optval[0] = 1 as u8; optval[1] = 0 as u8; optval[2] = 0 as u8; optval[3] = 0 as u8
157 sys_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, optval, 4)
158 if sys_bind(lfd, addr, 16) < 0 { ig_log(0, 0 - 95, 0, 0, 0); sys_exit(95); return 95 }
159 if sys_listen(lfd, 8) < 0 { ig_log(0, 0 - 96, 0, 0, 0); sys_exit(96); return 96 }
160
161 // curl writes its -w output to a FILE (not a pipe): the parent reads it AFTER
162 // reaping curl, and a file read returns EOF naturally -- this avoids the
163 // pipe-read deadlock where a single leaked write-end fd blocks read() forever.
164 let curl_out_path: *u8 = "/tmp/ig_curl_out.txt\x00"
165
166 // build curl argv (null-terminated *i64 array of *u8 string pointers)
167 let argv: *i64 = sys_mmap(8 * 32) as *i64
168 argv[0] = "/usr/bin/curl\x00" as *u8 as i64
169 argv[1] = "-4\x00" as *u8 as i64
170 argv[2] = "-s\x00" as *u8 as i64
171 argv[3] = "--http2\x00" as *u8 as i64
172 argv[4] = "--cacert\x00" as *u8 as i64
173 argv[5] = pem_path as *u8 as i64
174 argv[6] = "-w\x00" as *u8 as i64
175 argv[7] = "ic=%{response_code} nc=%{num_connects}\n\x00" as *u8 as i64
176 argv[8] = "-o\x00" as *u8 as i64
177 argv[9] = "/dev/null\x00" as *u8 as i64
178 argv[10] = "-o\x00" as *u8 as i64
179 argv[11] = "/dev/null\x00" as *u8 as i64
180 argv[12] = "-o\x00" as *u8 as i64
181 argv[13] = "/dev/null\x00" as *u8 as i64
182 argv[14] = "-o\x00" as *u8 as i64
183 argv[15] = "/dev/null\x00" as *u8 as i64
184 argv[16] = "https://localhost:9445/a\x00" as *u8 as i64
185 argv[17] = "https://localhost:9445/b\x00" as *u8 as i64
186 argv[18] = "https://localhost:9445/c\x00" as *u8 as i64
187 argv[19] = "https://localhost:9445/d\x00" as *u8 as i64
188 argv[20] = 0
189 let envp: *i64 = sys_mmap(16) as *i64
190 envp[0] = 0
191
192 let pid: i64 = sys_fork()
193 if pid == 0 {
194 // child: curl, stdout -> the results file (create/trunc, 0644)
195 let cfd: i64 = sys_openat_wr(curl_out_path as *u8, 0x1a4)
196 if cfd >= 0 { sys_dup3(cfd, 1, 0) }
197 if cfd >= 0 { sys_close(cfd) }
198 sys_execve("/usr/bin/curl\x00" as *u8, argv, envp)
199 sys_exit(127) // only if execve failed
200 }
201
202 // ---- parent: serve ONE connection (multi-stream), then read curl's output ----
203 let scfd: i64 = sys_accept(lfd)
204 if scfd < 0 { ig_log(0, 0 - 97, 0, 0, 0); sys_close(lfd); sys_exit(97); return 97 }
205 let srand: *u8 = sys_mmap(32)
206 let sxpriv: *u8 = sys_mmap(32)
207 if nx_csprng_fill(srand, 32) != 0 { sys_close(scfd); ig_log(0, 0 - 92, 0, 0, 0); sys_exit(92); return 92 }
208 if x25519_keypair_private(sxpriv) != 0 { sys_close(scfd); ig_log(0, 0 - 93, 0, 0, 0); sys_exit(93); return 93 }
209 let served: i64 = h2_serve_connection_multi(scfd, srand, sxpriv, cert_der, cert_len[0], ed_priv, body, blen, 16)
210 sys_close(scfd)
211 sys_close(lfd)
212
213 // reap curl FIRST (its output file is fully flushed once it has exited)
214 let st: *i64 = sys_mmap(16) as *i64
215 sys_wait4(pid, st, 0)
216 let curl_exit: i64 = (st[0] >> 8) & 0xff
217
218 // read curl's -w output from the file (a file read returns EOF naturally)
219 let cap_out: i64 = 4096
220 let outbuf: *u8 = sys_mmap(cap_out)
221 var got_total: i64 = 0
222 let rfd: i64 = sys_openat_rd(curl_out_path as *u8)
223 if rfd >= 0 {
224 var reading: i64 = 1
225 while reading == 1 {
226 let want: i64 = cap_out - got_total
227 if want <= 0 { reading = 0 }
228 if reading == 1 {
229 let g: i64 = sys_read(rfd, (outbuf as i64 + got_total) as *u8, want)
230 if g <= 0 { reading = 0 } else { got_total = got_total + g }
231 }
232 }
233 sys_close(rfd)
234 }
235
236 // measure
237 let h200: i64 = ig_count_sub(outbuf, got_total, "ic=200" as *u8, 6)
238 let newconn: i64 = ig_count_sub(outbuf, got_total, "nc=1\n" as *u8, 5)
239
240 // R4-H2-010 advertise byte-KAT: encode the EXACT SETTINGS frame our driver
241 // sends (same consts from nx_h2_serve_multi) and assert the wire bytes carry
242 // SETTINGS (type 0x04) + ident MAX_CONCURRENT_STREAMS (0x03) + value 100.
243 // Combined with the interop GREEN below (curl ACCEPTED that very frame), this
244 // proves the advertise -- KAT alone is our-encoder-self-test, curl alone is
245 // tolerant; together = real + interoperable.
246 let skat: *u8 = sys_mmap(64)
247 let skn: i64 = h2_frame_write_settings_param(skat, 0, NX_H2_SETTINGS_MAX_CONCURRENT_STREAMS, NX_H2_MAX_CONCURRENT_STREAMS)
248 var adv_ok: i64 = 1
249 if skn != 15 { adv_ok = 0 } // 9B frame header + 6B param
250 if (skat[3] & 0xff) != 0x04 { adv_ok = 0 } // frame type = SETTINGS
251 if (skat[10] & 0xff) != 0x03 { adv_ok = 0 } // ident lo byte = MAX_CONCURRENT_STREAMS
252 if (skat[14] & 0xff) != 100 { adv_ok = 0 } // value lo byte = 100
253
254 // echo captured curl output for the human log
255 sys_write(1, " curl said: " as *u8, 13)
256 sys_write(1, outbuf, got_total)
257
258 var green: i64 = 0
259 if served == IG_NURLS { if curl_exit == 0 { if h200 == IG_NURLS { if newconn == 1 { green = 1 } } } }
260 ig_log(green, served, curl_exit, h200, newconn)
261 ig_log_adv(adv_ok, green)
262 sys_write(1, " advertise byte-KAT (MAX_CONCURRENT_STREAMS=100): " as *u8, 51)
263 if adv_ok == 1 { sys_write(1, "PASS\n" as *u8, 5) } else { sys_write(1, "FAIL\n" as *u8, 5) }
264
265 if green == 1 {
266 sys_write(1, " VERDICT GREEN: 4 streams on 1 external curl connection (self-contained, no .sh)\n" as *u8, 81)
267 sys_exit(0); return 0
268 }
269 sys_write(1, " VERDICT RED: served=" as *u8, 22); ig_wn(1, served)
270 sys_write(1, " curl_exit=" as *u8, 11); ig_wn(1, curl_exit)
271 sys_write(1, " http200=" as *u8, 9); ig_wn(1, h200)
272 sys_write(1, " newconn=" as *u8, 9); ig_wn(1, newconn)
273 sys_write(1, "\n" as *u8, 1)
274 sys_exit(1); return 1
275}