Merge pull request 'fix(companion): guarantee dual-path peering — LAN p2p + public anchor, always' (#109) from fix/guaranteed-anchor-peering into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m56s
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m56s
This commit is contained in:
commit
db2cafc657
@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "com.archipelago.app"
|
applicationId = "com.archipelago.app"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 22
|
versionCode = 23
|
||||||
versionName = "0.5.2"
|
versionName = "0.5.3"
|
||||||
|
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary = true
|
useSupportLibrary = true
|
||||||
|
|||||||
@ -12,6 +12,16 @@ import androidx.datastore.preferences.preferencesDataStore
|
|||||||
|
|
||||||
private val Context.fipsDataStore: DataStore<Preferences> by preferencesDataStore(name = "fips_prefs")
|
private val Context.fipsDataStore: DataStore<Preferences> by preferencesDataStore(name = "fips_prefs")
|
||||||
|
|
||||||
|
// Archipelago-operated public anchor (vps2). Baked in so EVERY pairing yields
|
||||||
|
// both paths — direct LAN p2p to the node AND a public rendezvous for
|
||||||
|
// away-from-home — even when the scanned node is old enough that its QR
|
||||||
|
// carries no fanchors. Keep in lockstep with
|
||||||
|
// core/archipelago/src/fips/anchors.rs (ARCHY_ANCHOR_*).
|
||||||
|
internal const val ARCHY_ANCHOR_NPUB =
|
||||||
|
"npub1dptaktwxv0mm245g2lqjykwm5ll0jpc6m3r4242ydfa9z7qe6urs3jvrak"
|
||||||
|
internal const val ARCHY_ANCHOR_ADDR = "146.59.87.168:8444"
|
||||||
|
internal const val ARCHY_ANCHOR_TRANSPORT = "tcp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mesh identity + known node peers. Follows the same plaintext-DataStore
|
* Mesh identity + known node peers. Follows the same plaintext-DataStore
|
||||||
* storage model as ServerPreferences (the server password lives there the
|
* storage model as ServerPreferences (the server password lives there the
|
||||||
@ -91,6 +101,21 @@ class FipsPreferences(private val context: Context) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Guarantee the public anchor: without it, a QR from an older node
|
||||||
|
// leaves the phone LAN-only and pairing/connecting dies off-LAN.
|
||||||
|
if (info.npub != ARCHY_ANCHOR_NPUB &&
|
||||||
|
incoming.none { it.optString("npub") == ARCHY_ANCHOR_NPUB }
|
||||||
|
) {
|
||||||
|
incoming += JSONObject().apply {
|
||||||
|
put("npub", ARCHY_ANCHOR_NPUB)
|
||||||
|
put("alias", "Archipelago anchor")
|
||||||
|
put("addresses", JSONArray().put(JSONObject().apply {
|
||||||
|
put("transport", ARCHY_ANCHOR_TRANSPORT)
|
||||||
|
put("addr", ARCHY_ANCHOR_ADDR)
|
||||||
|
put("priority", 40)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
val incomingNpubs = incoming.map { it.optString("npub") }.toSet()
|
val incomingNpubs = incoming.map { it.optString("npub") }.toSet()
|
||||||
context.fipsDataStore.edit { prefs ->
|
context.fipsDataStore.edit { prefs ->
|
||||||
val current = JSONArray(prefs[peersKey] ?: "[]")
|
val current = JSONArray(prefs[peersKey] ?: "[]")
|
||||||
|
|||||||
@ -185,8 +185,10 @@ fun ServerConnectScreen(
|
|||||||
useHttps = false,
|
useHttps = false,
|
||||||
port = "",
|
port = "",
|
||||||
)
|
)
|
||||||
// The tunnel + mesh route need a moment on cold start.
|
// The tunnel + mesh route need a moment on cold start — and on
|
||||||
for (attempt in 0 until 4) {
|
// a first-ever pairing the VPN consent dialog is on screen at
|
||||||
|
// the same time, so give the user time to tap it.
|
||||||
|
for (attempt in 0 until 6) {
|
||||||
if (attempt > 0) delay(2000)
|
if (attempt > 0) delay(2000)
|
||||||
reachable = testConnection(meshServer)
|
reachable = testConnection(meshServer)
|
||||||
if (reachable) break
|
if (reachable) break
|
||||||
|
|||||||
@ -18,8 +18,11 @@ user's hands.
|
|||||||
support; web scan modal hands live scanning to it.
|
support; web scan modal hands live scanning to it.
|
||||||
- npub-keyed saved servers (pairing contract item 1, PR #106).
|
- npub-keyed saved servers (pairing contract item 1, PR #106).
|
||||||
- Served APK refreshed: `neode-ui/public/packages/archipelago-companion.apk`
|
- Served APK refreshed: `neode-ui/public/packages/archipelago-companion.apk`
|
||||||
is now **0.5.2 / versionCode 22**, which additionally fixes the two field
|
is now **0.5.3 / versionCode 23**. On top of the 0.5.1 scanner fixes it
|
||||||
failures from the user's 5G test (screenshots, 21:54):
|
guarantees dual-path peering — the node's LAN endpoint (direct p2p, npub-
|
||||||
|
keyed dial hints) AND the Archipelago public anchor (vps2, baked into the
|
||||||
|
app so even an old node's QR can't leave the phone LAN-only) — and fixes
|
||||||
|
the two field failures from the user's 5G test (screenshots, 21:54):
|
||||||
- **Mesh VPN no longer kills the phone's internet** — the IPv6-only TUN
|
- **Mesh VPN no longer kills the phone's internet** — the IPv6-only TUN
|
||||||
never called `allowFamily(AF_INET)`, so Android blocked all IPv4 while
|
never called `allowFamily(AF_INET)`, so Android blocked all IPv4 while
|
||||||
the mesh was up. Now allowed (+ `allowBypass`).
|
the mesh was up. Now allowed (+ `allowBypass`).
|
||||||
@ -39,9 +42,15 @@ user's hands.
|
|||||||
3. The demo stack gets its images from CI (run 100 pushed today with the new
|
3. The demo stack gets its images from CI (run 100 pushed today with the new
|
||||||
web bundle) — confirm the Portainer stack re-pulled, or trigger its
|
web bundle) — confirm the Portainer stack re-pulled, or trigger its
|
||||||
redeploy, so the demo QR also serves vc21.
|
redeploy, so the demo QR also serves vc21.
|
||||||
4. Re-test the user's exact flow: node UI → Companion popup → download APK
|
4. **Node side is half the 5G story**: away-from-home reachability needs the
|
||||||
via QR → install (vc21 updates vc19/vc20 in place) → scan the pairing QR.
|
NODE connected to the public anchor too. On Framework PT (and any test
|
||||||
If the scan still fails on-device with vc21, capture `adb logcat` around
|
node): deploy current main (node-side npub-first `fips.pair-info`), then
|
||||||
the scan and report back — the parser accepts the npub-first QR
|
verify `sudo -n fipsctl show status` reports the anchor connected —
|
||||||
(`fanchors` self-anchor first), so a remaining failure would be camera-
|
`fips.reconnect` RPC if not. A phone can dial the anchor perfectly and
|
||||||
hardware-specific, not format.
|
still fail if the node never enrolled with it.
|
||||||
|
5. Re-test the user's exact flows with vc23 (updates any older install in
|
||||||
|
place): (a) pair ON the LAN, then switch the phone to 5G — the UI must
|
||||||
|
come up via the mesh ULA; (b) pair while ALREADY on 5G (never on the
|
||||||
|
node's LAN) — scan, VPN consent, and the connect must succeed through
|
||||||
|
the anchor. If either fails, capture `adb logcat` around the attempt and
|
||||||
|
`fipsctl show sessions` on the node, and report back.
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user