code wiki / _hdl_build / _h2_multistream_curl_daemon.nx

_h2_multistream_curl_daemon.nx source

↩ module page · 278 lines · 13835 B

1// _h2_multistream_curl_daemon.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, authored 2// under the B1 rung(6) PERSISTENT-MULTI-STREAM external-curl interop step of the 3// R4-H2 HTTP/2-transport ladder), NOT credited as team self-authoring (back-fill 4// via the emitter-of-emitters once the daemon-from-spec organ exists). 5// 6// THE PERSISTENT MULTI-STREAM ALPN-h2 SERVE DAEMON: stands up OUR sovereign 7// ALPN-h2 TLS 1.3 server on 127.0.0.1:9444 and serves an EXTERNAL, INDEPENDENT h2 8// client (curl --http2 with libnghttp2/OpenSSL) that issues MULTIPLE same-origin 9// GETs. Unlike _h2_serve_curl_daemon.nx (which ACCEPTS HCD_N=3 SEPARATE 10// connections because its single-stream driver GOAWAYs after each request), this 11// daemon ACCEPTS EXACTLY ONE connection and serves up to MCD_MAX request streams 12// on it via the persistent driver h2_serve_connection_multi (runtime/ 13// nx_h2_serve_multi.nx). An external curl given K same-origin URLs therefore 14// REUSES that ONE TCP connection (total num_connects across the K transfers = 1). 15// 16// MEASURED EXCEED + DISCRIMINATION (the gate): 17// POS (this daemon, persistent): curl url1 url2 ... urlK on 127.0.0.1:9444 -> 18// all K transfers HTTP/2 200, TOTAL num_connects = 1 (the connection is 19// REUSED across streams 1,3,5,...,2K-1). 20// NEG control (_h2_serve_curl_daemon, single-stream, port 9443): the SAME K 21// URLs -> each transfer opens a FRESH connection (total num_connects = K), 22// because the single-stream driver GOAWAYs + closes after each request. 23// The num_connects measurement DISCRIMINATES persistent multi-stream from 24// connection-per-request -- it is not a tautology. 25// 26// FLOW (main): 27// - mint a self-signed Ed25519 X.509 leaf (SAN=localhost) -- the SAME 28// sovereign cert path the proven daemon uses (mcd_make_cert). 29// - EXPORT that DER cert to a PEM file (/tmp/nx_h2_ms_cert.pem) so an external 30// curl can trust it via --cacert (composes nx_base64 b64_encode). 31// - socket / SO_REUSEADDR / bind 127.0.0.1:9444 / listen; print 32// "BOUND 127.0.0.1:9444" so the orchestrator's readiness gate fires. 33// - ONE accept -> fresh handshake entropy -> h2_serve_connection_multi 34// (MCD_MAX cap) -> close -> exit 0; the driver returns the COUNT of streams 35// served (>=1), else an honest negative -> stop-on-RED, no fake-green. 36// 37// HONEST verdict discipline: this organ's job is to BIND + SERVE >1 external h2 38// request STREAM on ONE connection. GREEN (server side) iff the handshake 39// completed and >=2 request streams were parsed + answered :status 200 on the SAME 40// connection. The EXTERNAL curl judgement ("using HTTP/2" + "Re-using existing 41// connection" + total num_connects=1 + K x "HTTP/2 200") is the interop phase, 42// judged from curl's OWN output, not from this organ's exit code. 43// 44// FOUNDED ON (composes, each imported EXACTLY ONCE; the persistent driver organ 45// re-exports the framing + 3 tls13 transport stones transitively): 46// - nx_h2_serve_multi.nx: h2_serve_connection_multi (the persistent driver). 47// - nx_x25519_ephemeral / nx_csprng / nx_ed25519_signature: keys + randomness. 48// - hub/nx_x509_build / nx_x509 / nx_x509_trust_store: self-signed leaf builder. 49// - nx_base64.nx: b64_encode for the PEM export (cert-trust interop path). 50// - nx_syscalls.nx: sockets + file I/O. 51// 52// license_tier: INDEPENDENT_REDERIVE 53// genealogy_id: international-research-sources/ietf/rfc_9113 (s5 multiplexing) + rfc_8446 + rfc_7301 + rfc_5280 + rfc_4648 54// lineage_id: nishi_h2_multistream_curl_daemon_b1r6 55 56import "nx_syscalls.nx" 57import "nx_h2_serve_multi.nx" // B1 rung(6): the PERSISTENT multi-stream driver 58 // (h2_serve_connection_multi) -- re-exports the 59 // framing + 3 tls13 transport stones transitively. 60import "nx_x25519_ephemeral.nx" 61import "nx_csprng.nx" 62import "nx_ed25519_signature.nx" 63import "hub/nx_x509_build.nx" 64import "nx_x509.nx" 65import "nx_x509_trust_store.nx" 66import "nx_base64.nx" 67 68// Max request streams this daemon will serve on the ONE accepted connection before 69// the driver winds down (honest backstop; the real stop is the client's close/ 70// GOAWAY once it has fired all its URLs). 16 >> the gate's K so the client drives 71// the count, never this cap. 72const MCD_MAX: i64 = 16 73 74// 9444 (one above the single-stream daemon's 9443 so both can run for the 75// pos-vs-neg discrimination without a port clash). 76const MCD_PORT_REAL: i64 = 9444 77 78// ---- public-domain civil-date math (Howard Hinnant) -- inline (renamed mcd_) so 79// we do not import bin/nx_cert_gen.nx (which carries its own main()). ---- 80func mcd_civil_from_days(days: i64, out_y: *i64, out_m: *i64, out_d: *i64) -> i64 { 81 let z: i64 = days + 719468 82 let era: i64 = if z >= 0 then z / 146097 else (z - 146096) / 146097 83 let doe: i64 = z - era * 146097 84 let yoe: i64 = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 85 let y: i64 = yoe + era * 400 86 let doy: i64 = doe - (365 * yoe + yoe / 4 - yoe / 100) 87 let mp: i64 = (5 * doy + 2) / 153 88 let d: i64 = doy - (153 * mp + 2) / 5 + 1 89 var m: i64 = mp + 3 90 if mp < 10 { m = mp + 3 } else { m = mp - 9 } 91 var yy: i64 = y 92 if m <= 2 { yy = y + 1 } 93 out_y[0] = yy; out_m[0] = m; out_d[0] = d 94 return 0 95} 96func mcd_format_generalized_time(unix_sec: i64, out_15: *u8) -> i64 { 97 let days: i64 = unix_sec / 86400 98 let sod: i64 = unix_sec - days * 86400 99 let hh: i64 = sod / 3600 100 let mm: i64 = (sod - hh * 3600) / 60 101 let ss: i64 = sod - hh * 3600 - mm * 60 102 let yp: *i64 = sys_mmap(8) as *i64 103 let mp: *i64 = sys_mmap(8) as *i64 104 let dp: *i64 = sys_mmap(8) as *i64 105 mcd_civil_from_days(days, yp, mp, dp) 106 let y: i64 = yp[0]; let mo: i64 = mp[0]; let d: i64 = dp[0] 107 out_15[0] = ((0x30 + ((y / 1000) % 10)) & 0xff) as u8 108 out_15[1] = ((0x30 + ((y / 100) % 10)) & 0xff) as u8 109 out_15[2] = ((0x30 + ((y / 10) % 10)) & 0xff) as u8 110 out_15[3] = ((0x30 + ( y % 10)) & 0xff) as u8 111 out_15[4] = ((0x30 + (mo / 10)) & 0xff) as u8 112 out_15[5] = ((0x30 + (mo % 10)) & 0xff) as u8 113 out_15[6] = ((0x30 + (d / 10)) & 0xff) as u8 114 out_15[7] = ((0x30 + (d % 10)) & 0xff) as u8 115 out_15[8] = ((0x30 + (hh / 10)) & 0xff) as u8 116 out_15[9] = ((0x30 + (hh % 10)) & 0xff) as u8 117 out_15[10] = ((0x30 + (mm / 10)) & 0xff) as u8 118 out_15[11] = ((0x30 + (mm % 10)) & 0xff) as u8 119 out_15[12] = ((0x30 + (ss / 10)) & 0xff) as u8 120 out_15[13] = ((0x30 + (ss % 10)) & 0xff) as u8 121 out_15[14] = 0x5A as u8 // 'Z' 122 return 0 123} 124 125// Build the 16-byte sockaddr_in for 127.0.0.1:port. 126func mcd_addr(out: *u8, port: i64) -> i64 { 127 out[0] = 2 as u8; out[1] = 0 as u8 // AF_INET 128 out[2] = ((port >> 8) & 0xff) as u8 // port hi (network order) 129 out[3] = (port & 0xff) as u8 // port lo 130 out[4] = 127 as u8; out[5] = 0 as u8; out[6] = 0 as u8; out[7] = 1 as u8 // 127.0.0.1 131 var i: i64 = 8 132 while i < 16 { out[i] = 0 as u8; i = i + 1 } 133 return 0 134} 135 136// Generate the self-signed Ed25519 leaf (SAN=localhost). 137func mcd_make_cert(out_cert_der: *u8, out_cert_len: *i64, out_priv: *u8) -> i64 { 138 if nx_csprng_fill(out_priv, 32) != 0 { return 0 - 1 } 139 let pub32: *u8 = sys_mmap(32) 140 if ed25519_pub_from_priv(out_priv, pub32) != 0 { return 0 - 2 } 141 let now: i64 = sys_now_realtime_sec() 142 let nb: *u8 = sys_mmap(16) 143 let na: *u8 = sys_mmap(16) 144 mcd_format_generalized_time(now - 86400, nb) 145 mcd_format_generalized_time(now + 365 * 86400, na) 146 let san_name: *u8 = sys_mmap(16); nx_str_cpy(san_name, "localhost" as *u8) 147 let san_ptrs: *i64 = sys_mmap(8) as *i64; san_ptrs[0] = san_name as i64 148 let san_lens: *i64 = sys_mmap(8) as *i64; san_lens[0] = 9 149 let domain: *u8 = sys_mmap(16); nx_str_cpy(domain, "localhost" as *u8) 150 let inp: *NxX509BuildInputs = sys_mmap(256) as *NxX509BuildInputs 151 let in_rc: i64 = nx_x509_inputs_init(inp, domain, 9, san_ptrs, san_lens, 1, 152 out_priv, pub32, nb, na, now) 153 if in_rc != NX_X509_OK { return 0 - 3 } 154 let cdn: *i64 = sys_mmap(8) as *i64; cdn[0] = 0 155 let brc: i64 = nx_x509_build_self_signed(inp, out_cert_der, 8192, cdn) 156 if brc != NX_X509_OK { return 0 - 4 } 157 out_cert_len[0] = cdn[0] 158 return 0 159} 160 161// ---- PEM export (composes nx_base64 b64_encode, re-wrapped at 64 cols). ---- 162func mcd_write_pem(cert_der: *u8, der_len: i64, path_z: *u8) -> i64 { 163 let b64cap: i64 = 4 * ((der_len + 2) / 3) + 8 164 let b64buf: *u8 = sys_mmap(b64cap) 165 let b64n: i64 = b64_encode(cert_der, der_len, b64buf) 166 if b64n <= 0 { return 0 - 1 } 167 let fd: i64 = sys_openat_wr(path_z, 0x1a4) 168 if fd < 0 { return 0 - 2 } 169 if sys_write(fd, "-----BEGIN CERTIFICATE-----\n" as *u8, 28) != 28 { sys_close(fd); return 0 - 3 } 170 var off: i64 = 0 171 while off < b64n { 172 var line: i64 = 64 173 if b64n - off < 64 { line = b64n - off } 174 let w: i64 = sys_write(fd, ((b64buf as i64) + off) as *u8, line) 175 if w != line { sys_close(fd); return 0 - 4 } 176 if sys_write(fd, "\n" as *u8, 1) != 1 { sys_close(fd); return 0 - 5 } 177 off = off + line 178 } 179 if sys_write(fd, "-----END CERTIFICATE-----\n" as *u8, 26) != 26 { sys_close(fd); return 0 - 6 } 180 sys_close(fd) 181 return 0 182} 183 184// ---- verdict log: knowledge/status/h2_multistream.log ---- 185// served_count >= 2 on ONE connection -> GREEN(server-side); else RED+code. ---- 186func mcd_log(verdict_green: i64, served_or_code: i64) -> i64 { 187 let lfd: i64 = sys_openat_append("knowledge/status/h2_multistream.log" as *u8, 0x1a4) 188 if lfd < 0 { return 0 } 189 sys_write(lfd, "B1-R6-H2-MULTISTREAM organ=_h2_multistream_curl_daemon " as *u8, 55) 190 if verdict_green == 1 { 191 sys_write(lfd, "alpn=h2 one-conn streams-served=" as *u8, 32) 192 } else { 193 sys_write(lfd, "verdict=RED code=" as *u8, 17) 194 } 195 var v: i64 = served_or_code; if v < 0 { sys_write(lfd, "-" as *u8, 1); v = 0 - v } 196 let t: *u8 = sys_mmap(28); var kk: i64 = 0 197 if v == 0 { t[0] = 48 as u8; kk = 1 } 198 while v > 0 { t[kk] = (48 + (v % 10)) as u8; v = v / 10; kk = kk + 1 } 199 while kk > 0 { kk = kk - 1; sys_write(lfd, (((t as i64)+kk) as *u8), 1) } 200 if verdict_green == 1 { 201 sys_write(lfd, " verdict=GREEN(server-side: >1 stream on 1 conn)\n" as *u8, 49) 202 } else { 203 sys_write(lfd, "\n" as *u8, 1) 204 } 205 sys_close(lfd) 206 return 0 207} 208 209func main() -> i64 { 210 sys_write(1, "_h2_multistream_curl_daemon: OUR sovereign persistent ALPN-h2 server (1 conn, many streams) for EXTERNAL curl\n" as *u8, 109) 211 212 // ---- body the server serves to every stream ---- 213 let body: *u8 = sys_mmap(64) 214 let bsrc: *u8 = "hello from nishi h2 server (persistent multi-stream)" as *u8 215 var blen: i64 = 0 216 while bsrc[blen] != (0 as u8) { body[blen] = bsrc[blen]; blen = blen + 1 } 217 218 // ---- mint cert + export PEM ---- 219 let cert_der: *u8 = sys_mmap(8192) 220 let cert_len: *i64 = sys_mmap(8) as *i64 221 let ed_priv: *u8 = sys_mmap(32) 222 if mcd_make_cert(cert_der, cert_len, ed_priv) < 0 { 223 sys_write(1, " FAIL cert build\n" as *u8, 18); mcd_log(0, 0 - 90); sys_exit(90); return 90 224 } 225 sys_write(1, " cert minted (SAN=localhost, Ed25519 self-signed)\n" as *u8, 51) 226 let pem_path: *u8 = sys_mmap(64) 227 nx_str_cpy(pem_path, "/tmp/nx_h2_ms_cert.pem" as *u8) 228 if mcd_write_pem(cert_der, cert_len[0], pem_path) < 0 { 229 sys_write(1, " FAIL pem write\n" as *u8, 17); mcd_log(0, 0 - 91); sys_exit(91); return 91 230 } 231 sys_write(1, " cert.pem written /tmp/nx_h2_ms_cert.pem\n" as *u8, 42) 232 233 let srand: *u8 = sys_mmap(32) 234 let sxpriv: *u8 = sys_mmap(32) 235 236 // ---- socket / SO_REUSEADDR / bind 127.0.0.1:9444 / listen ---- 237 let addr: *u8 = sys_mmap(16) 238 mcd_addr(addr, MCD_PORT_REAL) 239 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 240 if lfd < 0 { mcd_log(0, 0 - 94); sys_exit(94); return 94 } 241 let optval: *u8 = sys_mmap(4) 242 optval[0] = 1 as u8; optval[1] = 0 as u8; optval[2] = 0 as u8; optval[3] = 0 as u8 243 sys_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, optval, 4) 244 if sys_bind(lfd, addr, 16) < 0 { mcd_log(0, 0 - 95); sys_exit(95); return 95 } 245 if sys_listen(lfd, 4) < 0 { mcd_log(0, 0 - 96); sys_exit(96); return 96 } 246 sys_write(1, "BOUND 127.0.0.1:9444\n" as *u8, 21) 247 248 // ---- ONE accept -> serve MANY streams on it ---- 249 let scfd: i64 = sys_accept(lfd) 250 if scfd < 0 { mcd_log(0, 0 - 97); sys_close(lfd); sys_exit(97); return 97 } 251 if nx_csprng_fill(srand, 32) != 0 { 252 sys_close(scfd); mcd_log(0, 0 - 92); sys_close(lfd); sys_exit(92); return 92 253 } 254 if x25519_keypair_private(sxpriv) != 0 { 255 sys_close(scfd); mcd_log(0, 0 - 93); sys_close(lfd); sys_exit(93); return 93 256 } 257 let sr: i64 = h2_serve_connection_multi(scfd, srand, sxpriv, cert_der, cert_len[0], ed_priv, body, blen, MCD_MAX) 258 sys_close(scfd) 259 sys_close(lfd) 260 261 if sr < 2 { 262 // <2 streams served = persistence NOT demonstrated -> honest RED, no fake-green. 263 sys_write(1, " FAIL persistent multi-stream not demonstrated (served<2)\n" as *u8, 58) 264 mcd_log(0, sr) 265 var ec: i64 = sr; if ec < 0 { ec = 0 - sr } 266 if ec == 0 { ec = 1 } 267 sys_exit(ec); return ec 268 } 269 270 sys_write(1, "SERVED MULTI: streams=" as *u8, 22) 271 let t2: *u8 = sys_mmap(8); var v2: i64 = sr; var n2: i64 = 0 272 if v2 == 0 { t2[0] = 48 as u8; n2 = 1 } 273 while v2 > 0 { t2[n2] = (48 + (v2 % 10)) as u8; v2 = v2 / 10; n2 = n2 + 1 } 274 while n2 > 0 { n2 = n2 - 1; sys_write(1, (((t2 as i64)+n2) as *u8), 1) } 275 sys_write(1, " on ONE connection, :status 200 each, exiting 0\n" as *u8, 48) 276 mcd_log(1, sr) 277 sys_exit(0); return 0 278}