code wiki / (root) / nx_tls13_frag_gate.nx

nx_tls13_frag_gate.nx source

↩ module page · 122 lines · 7183 B

1// nx_tls13_frag_gate.nx -- THE GATE FOR TLS REQUEST FRAGMENTATION ARITHMETIC, 2026-09-04. 2// 3// SUBJECT: nx_tls13_frag_max / nx_tls13_frag_len / nx_tls13_frag_count, in-process. 4// 5// WHY THIS GATE EXISTS AT ALL. Until today nx_https_req_complete wrote every request as ONE TLS 6// record, so the transport had a hard ~16 KB ceiling that callers wore as hand-picked body constants. 7// MEASURED: a 6,100-byte payload produced an 8,369-byte body and was refused while 5,900 passed, and 8// the sovereign content shipper could not send the 48,402-byte chunks its own server offered -- around 9// forty abandoned transfers had piled up over eleven days while each failure reported only 10// "post failed". Fragmenting fixed it. But that change is in a shared transport every HTTPS client in 11// this estate imports, and it goes live for each of them silently, on their NEXT REBUILD. A change 12// with that blast radius must be testable without a socket. 13// 14// WHY IT GATES PURE ARITHMETIC AND NOT A LIVE SEND, on its sibling nx_https_post_lib_gate precedent: 15// a gate that opens a socket goes RED when someone else network fails, and its RED then indicts this 16// code for another outage. The split was extracted out of the loop precisely so it could be walked 17// exhaustively here as integer arithmetic over one argument. 18// 19// THE LOAD-BEARING TOOTH IS THE PARTITION. Every off-by-one in a chunking loop either DROPS bytes or 20// DUPLICATES them, and both survive a boundary test that only checks counts. Asserting that the 21// fragment lengths SUM BACK TO the request length is the check that cannot be passed by a wrong split. 22// 23// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 24import "nx_syscalls.nx" 25import "nx_gate_verdict.nx" 26import "nx_tls13_record.nx" 27 28// Walks a request of req_len the way the writer does and returns the SUM of the fragment lengths. 29// Returns 0 - 1 if the walk fails to terminate within a generous bound, so a non-advancing split is a 30// named failure rather than a hang -- an unbounded loop and a wrong answer are the same to a caller. 31func fg_walk_sum(req_len: i64, maxsteps: i64) -> i64 { 32 var off: i64 = 0 33 var sum: i64 = 0 34 var steps: i64 = 0 35 while off < req_len { 36 if steps >= maxsteps { return 0 - 1 } 37 let f: i64 = nx_tls13_frag_len(req_len, off) 38 if f <= 0 { return 0 - 1 } 39 sum = sum + f 40 off = off + f 41 steps = steps + 1 42 } 43 return sum 44} 45// Largest fragment produced while walking req_len; 0 for an empty request. 46func fg_walk_max(req_len: i64, maxsteps: i64) -> i64 { 47 var off: i64 = 0 48 var big: i64 = 0 49 var steps: i64 = 0 50 while off < req_len { 51 if steps >= maxsteps { return 0 - 1 } 52 let f: i64 = nx_tls13_frag_len(req_len, off) 53 if f <= 0 { return 0 - 1 } 54 if f > big { big = f } 55 off = off + f 56 steps = steps + 1 57 } 58 return big 59} 60 61func main() -> i64 { 62 let ctr: *i64 = gv_ctr() 63 let m: i64 = nx_tls13_frag_max() 64 65 // The bound is the record layer own limit minus the content-type byte. If this ever drifts from 66 // NX_TLS13_MAX_INNER_PLAINTEXT the writer is emitting records a conforming peer must reject, and 67 // the failure would arrive as an opaque connection reset rather than as anything naming a size. 68 gv_check_eq("frag-max-is-the-record-layer-inner-limit-minus-the-content-type-byte" as *u8, 69 m, NX_TLS13_MAX_INNER_PLAINTEXT - 1, ctr) 70 71 // Counts across the boundary. m and m+1 are the pair that decides whether a full record is split. 72 gv_check_eq("count-of-an-EMPTY-request-is-ZERO-records (ceiling division of zero is the case every hand-rolled split gets wrong)" as *u8, 73 nx_tls13_frag_count(0), 0, ctr) 74 gv_check_eq("count-of-one-byte-is-ONE-record" as *u8, nx_tls13_frag_count(1), 1, ctr) 75 gv_check_eq("count-of-EXACTLY-frag-max-is-ONE-record-not-two" as *u8, nx_tls13_frag_count(m), 1, ctr) 76 gv_check_eq("count-of-frag-max-PLUS-ONE-is-TWO-records (the boundary the old single-record writer could not cross)" as *u8, 77 nx_tls13_frag_count(m + 1), 2, ctr) 78 gv_check_eq("count-of-exactly-two-full-records-is-TWO" as *u8, nx_tls13_frag_count(2 * m), 2, ctr) 79 gv_check_eq("count-of-two-full-records-plus-one-is-THREE" as *u8, nx_tls13_frag_count(2 * m + 1), 3, ctr) 80 81 // THE PARTITION MUST SUM. A split that drops or duplicates a byte passes every count test above. 82 let s1: i64 = fg_walk_sum(1, 8) 83 let s2: i64 = fg_walk_sum(m, 8) 84 let s3: i64 = fg_walk_sum(m + 1, 8) 85 let s4: i64 = fg_walk_sum(64769, 32) // the real chunk-request body size measured on the wire 86 let s5: i64 = fg_walk_sum(411108, 64) // the real 400 KB artifact shipped through this path 87 gv_check_eq("PARTITION-SUMS-at-one-byte" as *u8, s1, 1, ctr) 88 gv_check_eq("PARTITION-SUMS-at-exactly-frag-max" as *u8, s2, m, ctr) 89 gv_check_eq("PARTITION-SUMS-one-byte-past-frag-max (the split that drops or duplicates a byte fails HERE and nowhere else)" as *u8, 90 s3, m + 1, ctr) 91 gv_check_eq("PARTITION-SUMS-at-the-measured-64769-byte-chunk-request" as *u8, s4, 64769, ctr) 92 gv_check_eq("PARTITION-SUMS-at-the-measured-411108-byte-artifact" as *u8, s5, 411108, ctr) 93 94 // No fragment may exceed the limit, or the peer rejects the record. 95 gv_check_eq("no-fragment-of-the-411108-byte-walk-EXCEEDS-frag-max" as *u8, fg_walk_max(411108, 64), m, ctr) 96 97 // Past the end the split must return zero, or the writer loop never terminates. 98 gv_check_eq("frag-len-PAST-the-end-is-zero-so-the-writer-loop-terminates" as *u8, 99 nx_tls13_frag_len(100, 100), 0, ctr) 100 gv_check_eq("frag-len-of-an-EMPTY-request-is-zero" as *u8, nx_tls13_frag_len(0, 0), 0, ctr) 101 102 // neg-control: a NEGATIVE offset must not be treated as a valid position. Without this a caller 103 // arithmetic error becomes an out-of-bounds read of the request buffer rather than a refusal. 104 gv_check_eq("neg-control-a-negative-offset-yields-zero-not-a-bogus-length" as *u8, 105 nx_tls13_frag_len(100, 0 - 5), 0, ctr) 106 // neg-control: a negative request length is not a request. 107 gv_check_eq("neg-control-a-negative-request-length-is-ZERO-records" as *u8, 108 nx_tls13_frag_count(0 - 1), 0, ctr) 109 110 // ANTI-VACUITY: the 411108 walk must actually have taken more than one record, otherwise every 111 // partition tooth above passed on a single-fragment case and proves nothing about SPLITTING. 112 let nrec: i64 = nx_tls13_frag_count(411108) 113 gv_check("anti-vacuity-the-large-walk-really-DID-split-into-multiple-records (without this the partition teeth pass on a one-record case and say nothing about fragmentation)" as *u8, 114 (nrec > 1) as i64, ctr) 115 116 gv_kv("frag_max", m) 117 gv_kv("records_for_411108", nrec) 118 gv_kv("records_for_64769", nx_tls13_frag_count(64769)) 119 gv_kv("walk_sum_411108", s5) 120 gv_kv("walk_max_fragment", fg_walk_max(411108, 64)) 121 return gv_verdict("tls13_frag" as *u8, ctr, "the TLS request split is bounded by the record layer own inner-plaintext limit, terminates, and its fragments sum back to the request length" as *u8) 122}