code wiki / (root) / nx_sov_endpoint.nx

nx_sov_endpoint.nx source

↩ module page · 153 lines · 5397 B

1// nx_sov_endpoint.nx -- the ONE place that knows how to reach our own edge. 2// 3// WHY THIS EXISTS. Every caller that talks to the sovereign edge has been 4// hand-writing its own endpoint: `https://nishifamily.com`, or the loopback 5// connect-override `127.0.0.1:8443`, or a bare `:443`. The working answer has 6// been carried between sessions as folklore -- "use 127.0.0.1:8443 for our own 7// domains" -- which is a workaround living in prose, not a fix living in code. 8// When :443 degrades, every one of those call sites fails independently and 9// each one has to be rediscovered by hand. 10// 11// MEASURED 2026-07-31, not recalled. From this laptop, against the live host: 12// :8443 sovereign client 5/5 OK raw TCP 20/20 TLS1.3, LE cert 13// :443 sovereign client 0/5 OK raw TCP 18/20 flaps between 14// serving our real 15// cert and actively 16// refusing 17// The flap is a listener that is NOT one of ours -- `nx_hostctl status` lists 18// no sovereign service on :443 -- so we cannot supervise it and must not 19// depend on it. :8443 is sites.elf, ours, and was stable across every probe. 20// 21// THE RULE THIS ENCODES: 8443 before 443, loopback before the wire. It is 22// policy plus a reason, in data, so that a future edit that reorders these has 23// to confront the measurement rather than quietly restore the folklore. The 24// note string is not decoration -- the gate requires every endpoint to carry 25// one, so the policy cannot be changed silently. 26// 27// This module is deliberately PURE: ordering and URL construction only, no 28// sockets. A resolver that probed the network could not be gated offline, and 29// an ungated resolver on the path to every fetch is worse than folklore. 30// 31// license_tier: ORIGINAL 32import "nx_syscalls.nx" 33const NX_MAGIC_8443: i64 = 8443 34 35const NX_SOV_N_ENDPOINT: i64 = 3 36 37// Rank 0 is tried first. Lower is better. 38func nx_sov_endpoint_host(i: i64) -> *u8 { 39 if i == 0 { return "127.0.0.1" as *u8 } 40 if i == 1 { return "nishifamily.com" as *u8 } 41 if i == 2 { return "nishifamily.com" as *u8 } 42 return 0 as *u8 43} 44 45func nx_sov_endpoint_port(i: i64) -> i64 { 46 if i == 0 { return NX_MAGIC_8443 } 47 if i == 1 { return NX_MAGIC_8443 } 48 if i == 2 { return 443 } 49 return 0 50} 51 52// Why this endpoint sits where it does. Required to be non-empty. 53func nx_sov_endpoint_note(i: i64) -> *u8 { 54 if i == 0 { return "loopback to sites.elf; never leaves the box, no DNS, no WAN" as *u8 } 55 if i == 1 { return "sovereign edge over the wire; 5/5 OK and TLS1.3 on 2026-07-31" as *u8 } 56 if i == 2 { return "LAST RESORT: unsupervised listener, 0/5 from our client 2026-07-31" as *u8 } 57 return 0 as *u8 58} 59 60// Whether endpoint i is loopback. An explicit registry field, not a 61// test on the host string -- inferring it from a leading digit would 62// silently misclassify any future host whose name starts that way. 63func nx_sov_endpoint_is_loopback(i: i64) -> i64 { 64 if i == 0 { return 1 } 65 if i == 1 { return 0 } 66 if i == 2 { return 0 } 67 return 0 68} 69 70// A port we have measured as unreliable. Callers that must report a 71// degraded path can ask rather than re-deriving the judgement. 72func nx_sov_port_is_degraded(port: i64) -> i64 { 73 if port == 443 { return 1 } 74 return 0 75} 76 77func nx_sov_len(s: *u8) -> i64 { 78 var n: i64 = 0 79 if s == (0 as *u8) { return 0 } 80 while s[n] != (0 as u8) { n = n + 1 } 81 return n 82} 83 84func nx_sov_put(out: *u8, off: i64, s: *u8) -> i64 { 85 var i: i64 = 0 86 var o: i64 = off 87 if s == (0 as *u8) { return off } 88 while s[i] != (0 as u8) { 89 out[o] = s[i] 90 o = o + 1 91 i = i + 1 92 } 93 out[o] = 0 as u8 94 return o 95} 96 97func nx_sov_put_num(out: *u8, off: i64, v: i64) -> i64 { 98 let tmp: *u8 = sys_mmap(32) 99 var x: i64 = v 100 var d: i64 = 0 101 var o: i64 = off 102 if x <= 0 { 103 out[o] = 0x30 as u8 104 o = o + 1 105 out[o] = 0 as u8 106 return o 107 } 108 while x > 0 { 109 tmp[d] = ((x % 10) + 0x30) as u8 110 x = x / 10 111 d = d + 1 112 } 113 while d > 0 { 114 out[o] = tmp[d - 1] 115 o = o + 1 116 d = d - 1 117 } 118 out[o] = 0 as u8 119 return o 120} 121 122// Build "https://<host>:<port>" for endpoint i. Returns length, or -1 123// for an index that names no endpoint -- a caller handed a bad index 124// must get a refusal, never a plausible-looking default URL. 125func nx_sov_endpoint_url(i: i64, out: *u8) -> i64 { 126 var o: i64 = 0 127 if i < 0 { return 0 - 1 } 128 if i >= NX_SOV_N_ENDPOINT { return 0 - 1 } 129 out[0] = 0 as u8 130 o = nx_sov_put(out, o, "https://" as *u8) 131 o = nx_sov_put(out, o, nx_sov_endpoint_host(i)) 132 o = nx_sov_put(out, o, ":" as *u8) 133 o = nx_sov_put_num(out, o, nx_sov_endpoint_port(i)) 134 return o 135} 136 137// The endpoint a caller should try FIRST. 138func nx_sov_endpoint_preferred(out: *u8) -> i64 { 139 return nx_sov_endpoint_url(0, out) 140} 141 142// The endpoint an OFF-BOX caller should try first -- loopback is 143// useless from the laptop, so skip rank 0. 144func nx_sov_endpoint_preferred_remote(out: *u8) -> i64 { 145 var i: i64 = 0 146 while i < NX_SOV_N_ENDPOINT { 147 if nx_sov_endpoint_is_loopback(i) == 0 { 148 return nx_sov_endpoint_url(i, out) 149 } 150 i = i + 1 151 } 152 return 0 - 1 153}