app: nat.stun_5780 — NAT mapping/filtering discovery, verified vs live server
Hand-rolled RFC 5389/5780 STUN client (stdlib only) that exercises the server's stun-5780 capability: one socket, three binding requests (primary, OTHER-ADDRESS alternate IP, CHANGE-REQUEST port) — the comparison classifies NAT mapping and filtering behavior. Verified on the OnePlus: local 10.13.102.124 -> mapped 178.191.120.247:53259 (behind_nat true), alternate address answered from the server's second IP, mapping endpoint-independent, filtering address/port-dependent. Finding nat.symmetric (medium) for the P2P-hostile case. Two real bugs found by running it: port preservation was misread as "no NAT" (compare addresses, not ports), and an unbound socket reports the wildcard local address (resolve via a throwaway connected socket). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
dd9ecf5032
commit
483de5ca54
@@ -414,3 +414,19 @@ Ran the app on the OnePlus with Shizuku running (`echolot-app/reports/CPH2747-ap
|
||||
Both privilege tiers now work end to end in the production app on real hardware, alongside the
|
||||
canary-DNS loop against the live server. 6 tests/run: link.snapshot, icmp.ping4, icmp.ping6,
|
||||
net.captive_portal, dns.canary, link.ip_monitor(shizuku).
|
||||
|
||||
## App: nat.stun_5780 — NAT behavior discovery verified against the live server (2026-08-01)
|
||||
Client-side RFC 5389/5780 STUN (hand-rolled, stdlib only) exercising the server's `stun-5780`
|
||||
capability. Three binding requests from ONE socket: primary, the server's OTHER-ADDRESS
|
||||
(alternate IP), and CHANGE-REQUEST(port). Verified on the OnePlus
|
||||
(`echolot-app/reports/CPH2747-app-run4-stun.json`):
|
||||
- local `10.13.102.124` → mapped `178.191.120.247:53259`, `behind_nat: true`
|
||||
- `other_address 89.185.109.151:3479` — the server's second IP answered, so RFC 5780 works
|
||||
end to end (client ↔ our own STUN implementation)
|
||||
- **mapping: endpoint-independent** (same external port toward a different destination → P2P
|
||||
friendly); **filtering: address/port-dependent** (no reply to CHANGE-REQUEST → unsolicited
|
||||
inbound is dropped). Classic full-cone-mapping + port-restricted-filtering NAT.
|
||||
Finding wired: `nat.symmetric` (medium) when mapping is address/port-dependent.
|
||||
Two bugs caught by running it for real: port preservation was misread as "no NAT" (now compares
|
||||
ADDRESSES), and an unbound socket reports the wildcard as its local address (now resolved via a
|
||||
throwaway connected socket). 7 tests/run.
|
||||
|
||||
Reference in New Issue
Block a user