Skip to content

fix(tauri): mobile mDNS browse falls back to instance name for node-id (#318) - #320

Merged
momics merged 1 commit into
mainfrom
momics-fix-318-mobile-mdns-instance-name-fallba
Jul 6, 2026
Merged

fix(tauri): mobile mDNS browse falls back to instance name for node-id (#318)#320
momics merged 1 commit into
mainfrom
momics-fix-318-mobile-mdns-instance-name-fallba

Conversation

@momics

@momics momics commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Closes #318

Problem

Mobile mDNS browse (iOS NWBrowser, Android NsdManager) hard-required a pk TXT record to accept a discovered node. Desktop/server nodes advertised via iroh's iroh-mdns-address-lookup (swarm-discovery) publish the node-id as the DNS-SD instance name (lowercase base32 endpoint id) and emit no pk TXT. Result: both mobile browsers silently skipped every desktop-advertised node — a phone could not discover a laptop/server on the same LAN.

Fix

Teach both mobile browse parsers to fall back to the DNS-SD instance name as the node-id when the pk TXT/attribute is absent, after validating it parses as a canonical iroh endpoint id. The pk-present path is untouched, so mobile→mobile and desktop→mobile discovery (which already rely on the pk TXT set by the mobile advertise path) are unchanged.

iOS — packages/iroh-http-tauri/ios/Sources/IrohHttpPlugin.swift

handleBrowseResults now extracts the DNS-SD instance name from result.endpoint first, then resolves the node-id as: pk TXT if present and non-empty → else the instance name if it validates → else skip. Added isValidEndpointId(_:).

Android — packages/iroh-http-tauri/android/src/main/java/com/iroh/http/IrohHttpPlugin.kt

onServiceResolved resolves the node-id as: pk attribute if present and non-empty → else resolved.serviceName if it validates → else return. Added isValidEndpointId(...).

Base32 validation

A node-id is a 32-byte Ed25519 public key encoded as lowercase RFC 4648 base32 without padding (confirmed in crates/iroh-http-core/src/encoding.rsbase32::Alphabet::Rfc4648Lower { padding: false }, and the same alphabet in packages/iroh-http-tauri/src/tests.rs). 32 bytes → exactly 52 chars from the a-z / 2-7 alphabet. Both helpers require length == 52 and that every char is in a-z or 2-7, rejecting malformed/non-base32 names instead of crashing.

Truncation check: the advertise side caps instance names at 63 chars (Swift args.pk.prefix(63), Kotlin args.pk.take(63)). A 52-char id is well under 63, so it is never truncated and the fallback always recovers the full id.

Verification

  • CI-verified: npm run ci is green — Rust/JS build, clippy, tauri crate tests (19 + 4 + 1 doc), and tauri permissions all pass. This proves the change did not break the Rust/JS build, the tauri crate, or permissions. (The test:tauri:guest step reports vitest: command not found, a local-env gap unrelated to this change; the script still exits 0.)
  • Not exercised by CI: the iOS Swift and Android Kotlin code is not compiled/run by npm run ci. There is no Swift/Kotlin unit-test harness in the plugin, so no native test was added. Correctness was reasoned by reading the surrounding native code and matching the exact on-wire encoding.

Manual cross-device repro (required before merge)

Desktop→mobile discovery of a node with no pk TXT:

  1. On a desktop, start an advertiser on the LAN, e.g. via the node or deno adapter's mDNS advertise API (iroh swarm-discovery publishes the base32 node-id as the DNS-SD instance name, no pk TXT).
  2. On an iOS device/simulator on the same Wi-Fi, run the tauri app and call mdns_browse_start / poll. Expect: a discovered event whose nodeId equals the desktop node's base32 id.
  3. Repeat on an Android emulator/device.
  4. Dial the discovered nodeId and confirm the connection succeeds.
  5. Regression: confirm a mobile→mobile advertise (which sets the pk TXT) is still discovered on both platforms.

Notes

#318)

Mobile browse parsers (iOS NWBrowser, Android NsdManager) hard-required a
`pk` TXT record. Desktop/server nodes advertised via iroh swarm-discovery
publish the base32 endpoint id as the DNS-SD *instance name* and emit no
`pk` TXT, so mobile silently skipped every desktop-advertised node.

Both browse parsers now fall back to the DNS-SD instance name as the
node-id when the `pk` TXT/attribute is absent, validating it parses as a
canonical iroh endpoint id (52-char lowercase RFC 4648 base32, `a-z`/`2-7`)
before accepting. Malformed names are rejected, not crashed on. The
`pk`-present path (mobile→mobile, desktop→mobile) is unchanged.

Closes #318

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@momics
momics merged commit d209bd9 into main Jul 6, 2026
7 checks passed
@momics
momics deleted the momics-fix-318-mobile-mdns-instance-name-fallba branch July 20, 2026 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile mDNS browse cannot discover desktop-advertised iroh nodes (pk-TXT vs instance-name mismatch)

1 participant