summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-04 13:44:12 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-04 13:44:12 +0200
commit8288714853952aca6b3511268b9d772f1b7f489f (patch)
treef2a2b82bbf915a8e12853f6f85f3a930a0632d0a /docs
parentd85dbf5c0be71d870cc9b60510a2d43a9efc9f69 (diff)
downloadmeshbay-8288714853952aca6b3511268b9d772f1b7f489f.tar.gz
fix(node): make ice_interfaces match adapters on Windows (W9)
`ice_interfaces` compared the operator's entry against ifaddr's `adapter.name` only -- the kernel name on Linux (`wlp3s0f0`), but the adapter GUID on Windows (`{846EE342-...}`). A setting written on Linux, or copied into a Windows node's node.toml, matched no adapter at all. The failure was silent and total rather than partial: aioice binds one socket per host address, so an empty list means no sockets, no host candidates, and an SDP offering only a reflexive address. The settings field is free text with no picker, and on Windows the operator sees neither the GUID nor the description -- `ipconfig` shows the connection name -- so an entry now matches the adapter name, the device description, or one of the adapter's own IPv4 addresses, case-insensitively. An address is the one identifier visible on every platform. A filter that matches nothing now falls back to the unfiltered list with a warning. Losing the 5 s timeout saving is a regression; being silently unconnectable is a defect. Also fixes IPv4/IPv6 discrimination in the same loop: the two were told apart by falling through to an `elif` that index-probed `ip.ip[0]` and `ip.ip[2]`, which on an IPv4 str yields characters that compared unequal by luck rather than by design. Now discriminated by isinstance. WINDOWS-PORT.md claimed Transport had "no platform dependency"; it does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtfG7z6wHWj8RKHCvxQtY1
Diffstat (limited to 'docs')
-rw-r--r--docs/WINDOWS-PORT.md28
1 files changed, 27 insertions, 1 deletions
diff --git a/docs/WINDOWS-PORT.md b/docs/WINDOWS-PORT.md
index 239dbd1..ceba2b8 100644
--- a/docs/WINDOWS-PORT.md
+++ b/docs/WINDOWS-PORT.md
@@ -27,7 +27,7 @@ it matters most:
| `meshbay_common/` (all other modules) | **Ready** | Crypto, protocol, keyderive — no OS dependency |
| `roots.py` | **Ready** | Uses `fold()`, `portable_name_problem()`, `as_posix()` for virtual paths, Windows drive examples in docstrings |
| `indexer/indexer.py` | **Ready** | `as_posix()` for index paths, `long_path()` for file I/O, reconciliation loop for dropped `ReadDirectoryChangesW` events |
-| Transport (WebRTC, QUIC, MNP) | **Ready** | asyncio + aiortc, no platform dependency |
+| Transport (WebRTC, QUIC, MNP) | **Ready** | asyncio + aiortc. One platform dependency: `ice_filter.py` matches adapters by `ifaddr` name, which is a kernel name on Linux and a GUID on Windows — see W9 |
| Roster, bundle store, audit, chat store | **Ready** | SQLite + pathlib throughout |
| `test_paths.py` | **Ready** | Case folding, NFC, reserved names, reserved characters, trailing dot/space — already covers Windows filesystem rules |
| Electron `preload.js` | **Ready** | Pure IPC bridge, no platform code |
@@ -394,6 +394,30 @@ when `sys.platform == "win32"`.
**Estimated scope:** ~20 lines, cosmetic.
+### 5.8 ICE interface naming (W9)
+
+**Scope:** `transport/ice_filter.py`
+
+`ice_interfaces` restricts ICE gathering to named adapters. The filter compared
+the operator's entry against `ifaddr`'s `adapter.name` only — the kernel name
+on Linux (`wlp3s0f0`), but the adapter **GUID** on Windows
+(`{846EE342-7039-11DE-9D20-806E6F6E6963}`). A setting written on Linux, or
+copied into a Windows guest's `node.toml`, therefore matched no adapter at all.
+
+The failure was silent and total rather than partial: aioice binds one socket
+per host address, so an empty list means no sockets, no host candidates, and an
+SDP offering only a server-reflexive address. Behind two NATs — a VM on a
+libvirt NAT inside a LAN — that address is unreachable for a peer on the
+intermediate LAN, so ICE never completes and the symptom reads as a network
+fault, not a config one.
+
+An entry now matches the adapter name, the device description
+(`adapter.nice_name`, which is what Windows populates), or one of the adapter's
+own IPv4 addresses — the settings field is free text with no picker, so
+operators write whichever identifier they can see. A filter that matches
+nothing falls back to the unfiltered list with a warning: losing the 5 s
+timeout saving is a regression, being unconnectable is a defect.
+
---
## 6. Execution order
@@ -405,6 +429,7 @@ W5 File permissions ✅ done
W7 CLI messages ✅ done
W6 ffmpeg discovery ✅ done
W8 test suite green on win32 ✅ done (encoding sweep + skipif; 784 pass)
+W9 ICE interface naming ✅ done (name/description/IP match + fail-open)
──── milestone: daemon runs on Windows ✅ (verified end to end) ────
W3 Daemon lifecycle ✅ done — Startup-folder .vbs (Task Scheduler needs admin)
──── milestone: daemon starts/stops on Windows ✅ ────
@@ -417,6 +442,7 @@ W4 Packaging ✅ built — one per-user NSIS installer, client
```
W1–W2–W5–W6–W7–W8 shipped as a run of mechanical commits, testable on Linux.
+W9 came out of a live guest that could not connect at all.
W3 and W4 were the real work.
---