code wiki / _hdl_build / nx_room_live_gate.nx

nx_room_live_gate.nx source

↩ module page · 336 lines · 14767 B

1import "nx_gate_base.nx" 2import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 3// nx_room_live_gate.nx -- ENGINEER gate: MULTIPLE USERS IN A LIVE VIDEO ROOM. 4// 5// Operator 2026-06-10: "make sure that the team actually tests that multiple 6// users can be in a video room and interact." The loopback signaling gate 7// proves relay SEMANTICS; THIS gate proves the WHOLE USER PATH on the real 8// public stack: DNS -> TCP -> TLS 1.3 (cert chain validated against the real 9// Mozilla store) -> wss upgrade on nishifamily.com:443 -> RFC 6455 frames in 10// the room's ACTUAL wire format (the same 13-byte kind/id/seq header the 11// browser client speaks) -> N-party relay back to every other peer. 12// 13// Three sovereign clients (A, B, C) join the same room as three USERS: 14// - all three complete the wss upgrade (101) through the public domain 15// - A says hello (text) -> B AND C receive it verbatim 16// - B sends a VIDEO frame (binary, kind 'V' + id + seq + 8KB JPEG-shaped 17// payload) -> A AND C receive it bit-exact + parse it 18// - C sends an AUDIO frame (binary, kind 'A' + id + seq + rate + PCM) 19// -> A AND B receive it bit-exact 20// - A pings -> pong comes back to A only 21// - A leaves -> B->C still relays (room survives churn) 22// 23// Every media byte crosses the open internet through OUR daemon -- nothing 24// is loopback, nothing is mocked. Requires /tmp/mozilla_certdata.txt 25// (runner stages it from data/). 26// license_tier: ORIGINAL 27 28import "nx_syscalls.nx" 29import "nx_gate_emit_lib.nx" 30import "nx_x509_trust_store.nx" 31import "nx_trust_store_load_from_certdata.nx" 32import "nx_tls13_client_validate_certificate.nx" 33import "nx_tls13_client_session_run.nx" 34import "nx_dns_resolve_a_record.nx" 35import "nx_https_url_connect.nx" 36import "nx_websocket_frame.nx" 37import "nx_websocket_client_upgrade.nx" 38 39 40// Slot layout for the per-connection state array `c` (*i64, RG_SLOTS entries, allocated by this 41// file). The whole block was missing -- defined in NO file in the tree -- so nx_parse stopped at the 42// first use (RG_S) and both gates had been unbuildable. These are private indices, so any distinct 43// assignment is correct; RG_SLOTS is the allocation count. 44const RG_FD: i64 = 0 45const RG_S: i64 = 1 46const RG_ACC: i64 = 2 47const RG_ACC_CAP: i64 = 3 48const RG_ACC_LEN: i64 = 4 49const RG_ACC_OFF: i64 = 5 50const RG_SLOTS: i64 = 6 51 52 53func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 54" as *u8); return ok } 55func rg_tls_send(c: *i64, buf: *u8, n: i64) -> i64 { 56 let s: *Tls13ClientSession = c[RG_S] as *Tls13ClientSession 57 let rec: *u8 = sys_mmap(n + 64) 58 let hdr: *u8 = rec 59 let ct: *u8 = rec + NX_TLS13_RECORD_HEADER_LEN 60 let tag: *u8 = rec + NX_TLS13_RECORD_HEADER_LEN + n + 1 61 let v: i64 = nx_tls13_record_encrypt_v2( 62 s.cipher_suite, s.client_app_traffic_key, s.client_app_iv, 63 s.client_app_seq, buf, n, NX_TLS13_CT_APPLICATION_DATA, 0, 64 hdr, ct, tag) 65 s.client_app_seq = s.client_app_seq + 1 66 if v != NX_TLS13_REC_VERDICT_OK { return 0 - 1 } 67 let total: i64 = NX_TLS13_RECORD_HEADER_LEN + n + 1 + NX_TLS13_RECORD_TAG_LEN 68 var off: i64 = 0 69 while off < total { 70 let w: i64 = sys_write(c[RG_FD], (rec as i64 + off) as *u8, total - off) 71 if w <= 0 { return 0 - 1 } 72 off = off + w 73 } 74 return 0 75} 76 77// pump ONE TLS record from the wire into the accumulator (app data only; 78// NewSessionTicket etc. skipped). Returns bytes appended, 0 if the record 79// was non-app, negative on error/close. 80func rg_pump(c: *i64) -> i64 { 81 let s: *Tls13ClientSession = c[RG_S] as *Tls13ClientSession 82 let rec: *u8 = sys_mmap(16700) 83 let total: i64 = nx_tls13_read_record_from_fd(c[RG_FD], rec, 16700) 84 if total < 0 { return 0 - 1 } 85 let ct_len: i64 = total - NX_TLS13_RECORD_HEADER_LEN - NX_TLS13_RECORD_TAG_LEN 86 if ct_len <= 0 { return 0 - 1 } 87 let plain: *u8 = sys_mmap(ct_len + 16) 88 let ctp: *i64 = sys_mmap(16) as *i64 89 let lnp: *i64 = sys_mmap(16) as *i64 90 let v: i64 = nx_tls13_record_decrypt_v2( 91 s.cipher_suite, s.server_app_traffic_key, s.server_app_iv, 92 s.server_app_seq, rec, rec + NX_TLS13_RECORD_HEADER_LEN, ct_len, 93 rec + total - NX_TLS13_RECORD_TAG_LEN, plain, ctp, lnp) 94 s.server_app_seq = s.server_app_seq + 1 95 if v != NX_TLS13_REC_VERDICT_OK { return 0 - 2 } 96 if *ctp == NX_TLS13_CT_ALERT { return 0 - 3 } 97 if *ctp != NX_TLS13_CT_APPLICATION_DATA { return 0 } 98 let acc: *u8 = c[RG_ACC] as *u8 99 var w: i64 = c[RG_ACC_LEN] 100 if w + *lnp > c[RG_ACC_CAP] { return 0 - 4 } 101 var i: i64 = 0 102 while i < *lnp { acc[w + i] = plain[i]; i = i + 1 } 103 c[RG_ACC_LEN] = w + *lnp 104 return *lnp 105} 106 107// parse the next complete WS frame out of the accumulator, pumping the 108// wire as needed (bounded). Returns 0 + fills f, or negative. 109func rg_next_frame(c: *i64, f: *WsFrame) -> i64 { 110 var tries: i64 = 0 111 while tries < 64 { 112 let acc: *u8 = c[RG_ACC] as *u8 113 let v: i64 = ws_parse_frame(acc, c[RG_ACC_LEN], c[RG_ACC_OFF], f) 114 if v == 0 { 115 c[RG_ACC_OFF] = c[RG_ACC_OFF] + f.frame_len 116 return 0 117 } 118 let p: i64 = rg_pump(c) 119 if p < 0 { return p } 120 tries = tries + 1 121 } 122 return 0 - 9 123} 124 125// masked client->server WS frame over TLS 126func rg_send_ws(c: *i64, opcode: i64, payload: *u8, n: i64, mask: i64) -> i64 { 127 let buf: *u8 = sys_mmap(n + 32) 128 let hl: i64 = ws_build_header(buf, n + 32, 1, opcode, 1, mask, n) 129 if hl < 0 { return 0 - 1 } 130 var i: i64 = 0 131 while i < n { buf[hl + i] = payload[i]; i = i + 1 } 132 ws_apply_mask(buf, hl, n, mask) 133 return rg_tls_send(c, buf, hl + n) 134} 135 136// connect + TLS handshake + wss upgrade one client into the room. 137// Returns 0 on success. 138func rg_join(c: *i64, ipv4: i64, sni: *u8, sni_n: i64, path: *u8, path_n: i64, 139 store: *TrustStore, seed: i64) -> i64 { 140 let fd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 141 if fd < 0 { return 0 - 1 } 142 sys_set_socket_timeout(fd, 15) 143 let sa: *u8 = sys_mmap(16) 144 nx_https_build_sockaddr(sa, ipv4, 443) 145 if nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(fd); return 0 - 2 } 146 147 let cr: *u8 = sys_mmap(32) 148 let priv: *u8 = sys_mmap(32) 149 var i: i64 = 0 150 while i < 32 { cr[i] = ((seed * 37 + i * 11 + 5) & 0xff) as u8; priv[i] = ((seed * 53 + i * 7 + 9) & 0xff) as u8; i = i + 1 } 151 152 let vraw: *u8 = sys_mmap(64) 153 let val_ctx: *TlsValidationContext = vraw as *TlsValidationContext 154 val_ctx.store = store 155 val_ctx.sni_host = sni 156 val_ctx.sni_host_len = sni_n 157 val_ctx.now_epoch = sys_now_realtime_sec() 158 159 let r: i64 = nx_tls13_client_session_run(fd, sni, sni_n, cr, priv, val_ctx) 160 if r < 0 { g_puts(" tls run verdict=" as *u8); g_pn(r); g_puts("\n" as *u8); sys_close(fd); return 0 - 3 } 161 c[RG_FD] = fd 162 c[RG_S] = r 163 c[RG_ACC] = sys_mmap(262144) as i64 164 c[RG_ACC_LEN] = 0 165 c[RG_ACC_OFF] = 0 166 c[RG_ACC_CAP] = 262144 167 168 // wss upgrade THROUGH the TLS session 169 let req: *u8 = sys_mmap(2048) 170 let key24: *u8 = sys_mmap(32) 171 let rn: i64 = nx_ws_client_build_request(req, 2048, sni, sni_n, path, path_n, 443, 0, key24) 172 if rn <= 0 { return 0 - 4 } 173 if rg_tls_send(c, req, rn) < 0 { return 0 - 5 } 174 // pump until the header terminator 175 var hend: i64 = 0 - 1 176 var tries: i64 = 0 177 while tries < 32 { 178 let acc: *u8 = c[RG_ACC] as *u8 179 var j: i64 = 0 180 while j + 3 < c[RG_ACC_LEN] { 181 var hit: i64 = 1 182 if acc[j] != (13 as u8) { hit = 0 } 183 if acc[j+1] != (10 as u8) { hit = 0 } 184 if acc[j+2] != (13 as u8) { hit = 0 } 185 if acc[j+3] != (10 as u8) { hit = 0 } 186 if hit == 1 { hend = j + 4; j = c[RG_ACC_LEN] } else { j = j + 1 } 187 } 188 if hend > 0 { tries = 32 } else { 189 if rg_pump(c) < 0 { return 0 - 6 } 190 tries = tries + 1 191 } 192 } 193 if hend < 0 { return 0 - 6 } 194 let acc2: *u8 = c[RG_ACC] as *u8 195 let uv: i64 = nx_ws_client_validate_response(acc2, hend, key24) 196 if uv != NX_WSCU_OK { g_puts(" upgrade verdict=" as *u8); g_pn(uv); g_puts("\n" as *u8); return 0 - 7 } 197 c[RG_ACC_OFF] = hend 198 return 0 199} 200 201// build the room's BINARY media payload: [kind][8-byte id][u32 seq LE][body] 202func rg_media(out: *u8, kind: i64, id: *u8, seq: i64, body: *u8, n: i64) -> i64 { 203 out[0] = kind as u8 204 var i: i64 = 0 205 while i < 8 { out[1 + i] = id[i]; i = i + 1 } 206 out[9] = (seq & 255) as u8 207 out[10] = ((seq / 256) & 255) as u8 208 out[11] = ((seq / 65536) & 255) as u8 209 out[12] = ((seq / 16777216) & 255) as u8 210 i = 0 211 while i < n { out[13 + i] = body[i]; i = i + 1 } 212 return 13 + n 213} 214 215func rg_eq(a: *u8, ao: i64, b: *u8, n: i64) -> i64 { 216 var i: i64 = 0 217 while i < n { if a[ao + i] != b[i] { return 0 } i = i + 1 } 218 return 1 219} 220 221// receive next frame on c and byte-compare against expected payload 222func rg_expect(c: *i64, f: *WsFrame, want: *u8, want_n: i64, want_op: i64) -> i64 { 223 if rg_next_frame(c, f) != 0 { return 0 } 224 if f.opcode != want_op { return 0 } 225 if f.payload_len != want_n { return 0 } 226 let acc: *u8 = c[RG_ACC] as *u8 227 return rg_eq(acc, f.payload_off, want, want_n) 228} 229 230func main() -> i64 { 231 g_puts("nx_room_live gate (3 USERS in one LIVE public video room)\n" as *u8) 232 var pass: i64 = 0 233 var total: i64 = 0 234 235 // ---- real Mozilla trust store ---- 236 let cpath: *u8 = "/tmp/mozilla_certdata.txt" as *u8 237 let lr: i64 = nx_trust_store_load_from_certdata(cpath, 300, 4194304) 238 if lr <= 0 { g_puts("FAIL trust store load (stage /tmp/mozilla_certdata.txt)\n" as *u8); return 2 } 239 let store: *TrustStore = lr as *TrustStore 240 241 // ---- DNS once ---- 242 let host: *u8 = "nishifamily.com" as *u8 243 let hn: i64 = 15 244 let dr: *DnsResolveResult = nx_dns_resolve_default(host, hn, sys_now_realtime_sec()) 245 if dr.verdict != NX_DNS_R_OK { g_puts("FAIL dns\n" as *u8); return 2 } 246 247 let path: *u8 = "/signal/liveroomgate" as *u8 248 let pn: i64 = g_slen(path) 249 250 // ---- three users join ---- 251 let ca: *i64 = sys_mmap(RG_SLOTS * 8) as *i64 252 let cb: *i64 = sys_mmap(RG_SLOTS * 8) as *i64 253 let cc: *i64 = sys_mmap(RG_SLOTS * 8) as *i64 254 let ja: i64 = rg_join(ca, dr.ipv4_packed, host, hn, path, pn, store, 1) 255 let jb: i64 = rg_join(cb, dr.ipv4_packed, host, hn, path, pn, store, 2) 256 let jc: i64 = rg_join(cc, dr.ipv4_packed, host, hn, path, pn, store, 3) 257 pass = pass + g_check("3 users joined: TLS1.3 (real-CA validated) + wss 101 x3, public domain" as *u8, 258 (ja == 0) + (jb == 0) + (jc == 0) == 3); total = total + 1 259 if ja != 0 { g_pn(ja); return 1 } 260 if jb != 0 { return 1 } 261 if jc != 0 { return 1 } 262 263 let fraw: *u8 = sys_mmap(128) 264 let f: *WsFrame = fraw as *WsFrame 265 266 // ---- A says hello -> B and C ---- 267 let hello: *u8 = "{\"from\":\"useraaaa\",\"type\":\"hello\",\"name\":\"alice\"}" as *u8 268 let hello_n: i64 = g_slen(hello) 269 rg_send_ws(ca, WS_OP_TEXT, hello, hello_n, 0x11223344) 270 pass = pass + g_check("user B received A's hello (text, verbatim)" as *u8, 271 rg_expect(cb, f, hello, hello_n, WS_OP_TEXT)); total = total + 1 272 pass = pass + g_check("user C received A's hello too (N-party)" as *u8, 273 rg_expect(cc, f, hello, hello_n, WS_OP_TEXT)); total = total + 1 274 275 // ---- B sends a VIDEO frame (room wire format, JPEG-shaped 8KB) ---- 276 let vbody: *u8 = sys_mmap(8000) 277 var i: i64 = 0 278 while i < 8000 { vbody[i] = ((i * 31 + 7) & 0xff) as u8; i = i + 1 } 279 let vfrm: *u8 = sys_mmap(8200) 280 let vn: i64 = rg_media(vfrm, 0x56, "userbbbb" as *u8, 42, vbody, 8000) 281 rg_send_ws(cb, WS_OP_BINARY, vfrm, vn, 0x55667788) 282 pass = pass + g_check("user A received B's VIDEO frame bit-exact (8KB binary)" as *u8, 283 rg_expect(ca, f, vfrm, vn, WS_OP_BINARY)); total = total + 1 284 pass = pass + g_check("user C received B's VIDEO frame bit-exact too" as *u8, 285 rg_expect(cc, f, vfrm, vn, WS_OP_BINARY)); total = total + 1 286 // parse the wire header out of C's copy (the contract the browser speaks) 287 let acc_c: *u8 = cc[RG_ACC] as *u8 288 let voff: i64 = f.payload_off 289 var hdr_ok: i64 = 1 290 if (acc_c[voff] & 0xff) != 0x56 { hdr_ok = 0 } 291 if rg_eq(acc_c, voff + 1, "userbbbb" as *u8, 8) != 1 { hdr_ok = 0 } 292 var rseq: i64 = acc_c[voff + 9] & 0xff 293 rseq = rseq + ((acc_c[voff + 10] & 0xff) * 256) 294 rseq = rseq + ((acc_c[voff + 11] & 0xff) * 65536) 295 rseq = rseq + ((acc_c[voff + 12] & 0xff) * 16777216) 296 if rseq != 42 { hdr_ok = 0 } 297 pass = pass + g_check("VIDEO wire header parses (kind=V id=userbbbb seq=42)" as *u8, hdr_ok); total = total + 1 298 299 // ---- C sends an AUDIO frame (rate in-band + PCM pattern) ---- 300 let abody: *u8 = sys_mmap(4100) 301 abody[0] = 0x80 as u8; abody[1] = 0xbb as u8; abody[2] = 0; abody[3] = 0 // 48000 LE 302 i = 0 303 while i < 4096 { abody[4 + i] = ((i * 13 + 5) & 0xff) as u8; i = i + 1 } 304 let afrm: *u8 = sys_mmap(4300) 305 let an: i64 = rg_media(afrm, 0x41, "usercccc" as *u8, 7, abody, 4100) 306 rg_send_ws(cc, WS_OP_BINARY, afrm, an, 0x99aabbcc) 307 pass = pass + g_check("user A received C's AUDIO frame bit-exact (PCM, rate in-band)" as *u8, 308 rg_expect(ca, f, afrm, an, WS_OP_BINARY)); total = total + 1 309 pass = pass + g_check("user B received C's AUDIO frame bit-exact too" as *u8, 310 rg_expect(cb, f, afrm, an, WS_OP_BINARY)); total = total + 1 311 312 // ---- ping/pong stays per-user ---- 313 rg_send_ws(ca, WS_OP_PING, "pp" as *u8, 2, 0x13579bdf) 314 var pong_ok: i64 = 0 315 if rg_next_frame(ca, f) == 0 { if f.opcode == WS_OP_PONG { pong_ok = 1 } } 316 pass = pass + g_check("A ping -> pong back to A (control not relayed)" as *u8, pong_ok); total = total + 1 317 318 // ---- A leaves; B<->C still interact ---- 319 let cbuf: *u8 = sys_mmap(8) 320 cbuf[0] = 3; cbuf[1] = 0xe8 as u8 // 1000 BE 321 rg_send_ws(ca, WS_OP_CLOSE, cbuf, 2, 0x2468ace0) 322 sys_close(ca[RG_FD]) 323 sys_sleep_ms(200) 324 let bye2: *u8 = "{\"from\":\"userbbbb\",\"type\":\"chat\",\"text\":\"still here?\"}" as *u8 325 let bye2_n: i64 = g_slen(bye2) 326 rg_send_ws(cb, WS_OP_TEXT, bye2, bye2_n, 0x0f1e2d3c) 327 pass = pass + g_check("after A left, B's message still reaches C (room survives churn)" as *u8, 328 rg_expect(cc, f, bye2, bye2_n, WS_OP_TEXT)); total = total + 1 329 330 sys_close(cb[RG_FD]) 331 sys_close(cc[RG_FD]) 332 333 g_puts("---- room_live gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 334 if pass == total { return 0 } 335 return 1 336}