feat(companion): embedded FIPS mesh replaces WireGuard for remote access

- Android/rust/archy-fips-core: leaf-only fips node as a JNI cdylib (fips
  pinned to the fips-native fork rev with VpnService fd support), built by
  gradle via cargo-ndk (arm64), tested on host
- ArchyVpnService: split-tunnel VpnService routing only fd00::/8 (MTU 1280,
  foreground specialUse); FipsManager handles the one-time VPN consent and
  silent auto-start — no settings surface at all
- pairing QR now fully configures the mesh: fnpub/fip/fhost/fudp/ftcp plus
  fanchors (the node's seed-anchor list, npub@addr/transport) so the phone
  can rendezvous through public anchors when the LAN endpoint is unreachable
- default seed anchors gain the two dual-transport join.fips.network test
  anchors (23.182.128.74:443/tcp, 217.77.8.91:443/tcp); anchor adverts are
  Nostr kind-37195 events
- device token rides the password field end-to-end: backend accepts tokens
  wherever it accepts the password, so scan = instant login (WebSocket auth
  + WebView form injection unchanged); token logins skip TOTP
- ServerEntry.meshIp + IPv6-bracketed URLs; WebView retries the mesh address
  on main-frame errors, auto-login and origin checks honor it
- companion v0.5.0 (versionCode 20), arm64 abiFilter; FipsNative.available
  gates everything so non-arm64 still runs as a plain companion

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-07-22 22:06:32 +01:00
co-authored by Claude Fable 5
parent b88609e0ff
commit 4b91765cc7
25 changed files with 1119 additions and 33 deletions
+28 -1
View File
@@ -81,6 +81,31 @@ pub fn archy_anchor() -> SeedAnchor {
}
}
/// Public FIPS-network anchors from join.fips.network (adverts published as
/// Nostr kind-37195 `fips-overlay-v1` events, refreshed hourly). Of the eight
/// live test anchors (2026-07-22), these two are the dual-transport ones —
/// they answer on TCP as well as UDP, and TCP is what traverses restrictive
/// networks. The remaining six are UDP-only; add them per-node via
/// `fips.add-seed-anchor` if more rendezvous diversity is wanted.
pub fn fips_network_anchors() -> Vec<SeedAnchor> {
vec![
SeedAnchor {
npub: "npub10yffd020a4ag8zcy75f9pruq3rnghvvhd5hphl9s62zgp35s560qrksp9u"
.to_string(),
address: "23.182.128.74:443".to_string(),
transport: "tcp".to_string(),
label: "FIPS network anchor (join.fips.network)".to_string(),
},
SeedAnchor {
npub: "npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98"
.to_string(),
address: "217.77.8.91:443".to_string(),
transport: "tcp".to_string(),
label: "FIPS network anchor (join.fips.network)".to_string(),
},
]
}
/// The default anchor set carried implicitly by `load()` on nodes that have
/// never edited their anchor list, so every node dials them without operator
/// action. Multiple anchors so one unreachable rendezvous host can't strand a
@@ -88,7 +113,9 @@ pub fn archy_anchor() -> SeedAnchor {
/// network can reach wins. The Archipelago-operated anchor is listed first
/// because it is reachable from the widest set of networks.
pub fn default_public_anchors() -> Vec<SeedAnchor> {
vec![archy_anchor(), default_public_anchor()]
let mut anchors = vec![archy_anchor(), default_public_anchor()];
anchors.extend(fips_network_anchors());
anchors
}
/// One seed-anchor entry. `address` must be directly dialable (IP or