code wiki / (root) / nx_route_probe.nx

nx_route_probe.nx source

↩ module page · 92 lines · 3347 B

1// nx_route_probe.nx -- latency-probed multi-path relay selection. 2// 3// Primitive 2 of NISHI_S_CLASS_ROUTING_ROADMAP: at call start, probe 4// every candidate relay's RTT live, combine with packet loss + a 5// jurisdiction penalty, and pick the lowest-cost path -- so a 6// Texas<->Belarus call prefers a Frankfurt relay over a US one even 7// when the US one is a hair faster (avoid US/adversary-jurisdiction 8// transit by policy). All Nishi: composes nx_udp_rv + sys_now_us; 9// the relays are our own nx_turn_relay (which answers STUN BINDING). 10// 11// cost(path) = rtt_ms + 30 * loss_pct + jurisdiction_penalty_ms 12// 13// The jurisdiction penalty is POLICY (operator-editable), not a magic 14// number baked in source -- the caller passes the avoid-jurisdiction 15// from ~/.nishi/jurisdiction config per 16// [[feedback-no-hardcoded-secrets-config-driven]]. 17 18import "../runtime/nx_udp_rv.nx" 19 20const NX_ROUTE_JUR_PENALTY_MS: i64 = 50 // policy weight; caller may override 21 22// Pure: combined path cost. KAT-able. 23func nx_route_cost(rtt_ms: i64, loss_pct: i64, jur_penalty_ms: i64) -> i64 { 24 return rtt_ms + 30 * loss_pct + jur_penalty_ms 25} 26 27// Pure: index of the minimum cost, or -1 if n<=0. KAT-able. 28func nx_route_select(costs: *i64, n: i64) -> i64 { 29 if n <= 0 { return 0 - 1 } 30 var best: i64 = 0 31 var bc: i64 = costs[0] 32 var i: i64 = 1 33 while i < n { 34 if costs[i] < bc { bc = costs[i]; best = i } 35 i = i + 1 36 } 37 return best 38} 39 40// Pure: jurisdiction penalty. 50ms-equiv if the relay sits in the 41// jurisdiction the call wants to avoid, else 0. 42func nx_route_jur_penalty(relay_jur: i64, avoid_jur: i64) -> i64 { 43 if relay_jur == avoid_jur { return NX_ROUTE_JUR_PENALTY_MS } 44 return 0 45} 46 47func _rp_pfd_set_fd(buf: *u8, fd: i64) -> i64 { 48 buf[0]=fd&0xff; buf[1]=(fd>>8)&0xff; buf[2]=(fd>>16)&0xff; buf[3]=(fd>>24)&0xff 49 return 0 50} 51func _rp_pfd_set_events(buf: *u8, ev: i64) -> i64 { 52 buf[4]=ev&0xff; buf[5]=(ev>>8)&0xff 53 return 0 54} 55 56// Build a 20-byte STUN BINDING request (the relay answers 0x0101). 57func _rp_stun_binding(out: *u8, tx: *u8) -> i64 { 58 out[0]=0x00; out[1]=0x01 59 out[2]=0x00; out[3]=0x00 60 out[4]=0x21; out[5]=0x12; out[6]=0xa4; out[7]=0x42 61 var i: i64 = 0 62 while i < 12 { out[8+i] = tx[i]; i = i + 1 } 63 return 20 64} 65 66// Live: measure RTT (microseconds) to a relay via STUN BINDING. 67// Returns rtt_us (>=0) or -1 on timeout / send failure. 68func nx_route_probe_rtt(fd: i64, relay16: *u8, timeout_ms: i64) -> i64 { 69 let tx: *u8 = sys_mmap(16) 70 var i: i64 = 0 71 while i < 12 { tx[i] = (i * 13 + 1) & 0xff; i = i + 1 } 72 let req: *u8 = sys_mmap(32) 73 _rp_stun_binding(req, tx) 74 let t0: i64 = sys_now_us() 75 if nx_udpr_send(fd, req, 20, relay16) != 20 { return 0 - 1 } 76 let pf: *u8 = sys_mmap(8) 77 _rp_pfd_set_fd(pf, fd) 78 _rp_pfd_set_events(pf, 1) 79 let r: i64 = sys_poll(pf, 1, timeout_ms) 80 if r <= 0 { return 0 - 1 } 81 let rbuf: *u8 = sys_mmap(256) 82 let from: *u8 = sys_mmap(16) 83 let fl: *i64 = sys_mmap(16) as *i64 84 *fl = 16 85 let n: i64 = nx_udpr_recv(fd, rbuf, 256, from, fl) 86 if n < 20 { return 0 - 1 } 87 // Must be a STUN success (0x0101) with the magic cookie. 88 if rbuf[0] != 0x01 { return 0 - 1 } 89 if rbuf[1] != 0x01 { return 0 - 1 } 90 if rbuf[4] != 0x21 { return 0 - 1 } 91 return sys_now_us() - t0 92}