Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions FORK_PRS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ become its own scoped PR. Issue numbers filled in once created.
| 9 | ✅ [#28](https://github.com/fugo101/microlink/issues/28) (done) | [`antmanler/microlink`](https://github.com/antmanler/microlink) | `2a7ba328` | WG netif MTU 1420→1280 (Tailscale-standard). Verified still needed: despite `CLAUDE.md` documenting `CONFIG_LWIP_IP4_REASSEMBLY=y` as required, no example's `sdkconfig.defaults` actually sets it, and ESP-IDF's own Kconfig default for `LWIP_IP4_REASSEMBLY` is `n` — so on a stock build, reassembly really is off and 1420-byte inner packets over a 1500-byte WiFi MTU silently fragment-and-drop. Landed together with issue #26 (same commit, same files). | 1 |
| 10 | ✅ [#29](https://github.com/fugo101/microlink/issues/29) (done) | [`liestrela/microlink`](https://github.com/liestrela/microlink) | `1649d987` | Gate ESP32 temp-sensor feature behind `CONFIG_SOC_TEMP_SENSOR_SUPPORTED` — `esp_driver_tsens` was an unconditional `REQUIRES`, breaks build on SoC variants without a temp sensor. Cherry-picked verbatim, no adaptation needed. | 1 |
| 11 | ✅ [#30](https://github.com/fugo101/microlink/issues/30) (done) | `cplewes` vs `Csontikka` (conflict) | `cplewes` `83a102be`/`01d51697` vs [`Csontikka/microlink`](https://github.com/Csontikka/microlink) `dd5714c4`→`2e68e546` | `ip_input()` vs `netif->input`/`tcpip_input` threading fix for decrypted WG RX pbufs — cplewes fixes a UAF this way, Csontikka's own branch later reverted the equivalent fix citing a throughput regression (~30pps cap). **Resolved by verification, not a port**: `git blame` shows `components/wireguard_lwip/src/wireguardif.c`'s RX hand-off has called `device->netif->input(pbuf, device->netif)` since the submodule's very first commit (`193aac6`, 2026-08-14, predates this survey), with its own comment citing a double-free at `pbuf.c:753` as the reason. `ml_wg_mgr.c:320` sets `netif->input = tcpip_input` unconditionally, so this call always dispatches to `tcpip_input` — both `cplewes`'s and Csontikka's first fix (`dd5714c4`) independently arrive at the same place we already were. Csontikka's later revert (`2e68e546`) only makes sense in a codebase where `netif->input` gets reconfigured back to raw `ip_input` elsewhere; ours never does, so the ~30pps throughput-ceiling tradeoff they measured is a separate, real, but *architectural* question (would need something like `ml_zerocopy.c`'s raw-PCB pattern extended to WG RX) — not in scope for this issue, and not something our own testing docs currently flag as a problem. No code change needed. | 2 |
| 12 | [#31](https://github.com/fugo101/microlink/issues/31) | `Csontikka/microlink` | `647c2ab0` | `LOCK_TCPIP_CORE` around `netif_set_link_up/down` — compare against our documented `netif->state` NULL-and-restore workaround in `ESP_IDF_6X_COMPAT.md` before adopting | 2 |
| 12 | [#31](https://github.com/fugo101/microlink/issues/31) | `Csontikka/microlink` | `647c2ab0` | `LOCK_TCPIP_CORE` around `netif_set_link_up/down` — compare against our documented `netif->state` NULL-and-restore workaround in `ESP_IDF_6X_COMPAT.md` before adopting. **Investigated, not needed**: `LOCK_TCPIP_CORE()`/`UNLOCK_TCPIP_CORE()` expand to nothing when `LWIP_TCPIP_CORE_LOCKING` is disabled (this fork's default in every example — confirmed in `lwip/tcpip.h`), so the fix is a no-op here. Its `ip_input()`→`tcpip_input()` change also duplicates what this fork already does independently (see issue #30's resolution). The rest of the commit disables WireGuard's cryptokey-routing source-IP validation entirely ("accept all source IPs") plus scattered debug `printf`s — a security-relevant scope change contradicting the `GrieferPig/microlink` "not worth pursuing" entry below (praised for having *correct* src-IP validation), not something to fold in silently. No port planned. | 2 |
| 13 | ✅ [#32](https://github.com/fugo101/microlink/issues/32) (done) | `Csontikka/microlink` | `5bda1783` | Peer direct-handshake init was one-shot; peers with dropped/unanswered handshakes stayed permanently blackholed — retry every 30s via timestamp instead of boolean latch. Adapted, not literal cherry-pick: the source commit's diff still cleared `peer->active` after `wireguardif_connect()`, which issue #26/#28's PR #53 (same session) proved permanently blocks a peer's handshake — kept that fix removed while porting the retry-timestamp logic. | 2 |
| 14 | [#33](https://github.com/fugo101/microlink/issues/33) | `Csontikka/microlink` | `2e68e546`, `f1de3143` | DISCO trust-expiry gate (15s→60s, checks `last_rx` first), NAT-rebind handshake-skip when data path still alive, SPIRAM pbuf headroom fix for `wg_udp_output_cb`. **2/3 done**: the trust-expiry gate and NAT-rebind handshake-skip landed (both self-contained to `ml_wg_mgr.c`/`microlink_internal.h`, no submodule involvement). The SPIRAM pbuf change deliberately deferred — it rewrites `wg_udp_output_cb`'s allocation (the same function PR #53 just changed for thread safety), uses a hand-computed `LWIP_MEM_ALIGN_SIZE` header offset the source fork's own history shows they got wrong once already (shipped corrupted data), and can't be verified without real hardware. Not worth the risk in this sandbox; issue stays open for that piece. The bundled diagnostic-dump function (`dump_wg_state_snapshot`) was skipped as debug cruft, same as prior sessions' extractions. | 2 |
| 15 | [#34](https://github.com/fugo101/microlink/issues/34) | `Csontikka/microlink` | `b7442d0f` | Handshake retries throttled to 1/tick round-robin instead of firing to every eligible peer in one tick (was blocking the caller ~280ms with 7 peers) | 2 |
| 15 | [#34](https://github.com/fugo101/microlink/issues/34) | `Csontikka/microlink` | `b7442d0f` | Handshake retries throttled to 1/tick round-robin instead of firing to every eligible peer in one tick (was blocking the caller ~280ms with 7 peers). **Adapted, landed in the `wireguard_lwip` submodule** (not this repo — the fix lives entirely in `wireguardif.c`): [`fugo101/wireguard-lwip#15`](https://github.com/fugo101/wireguard-lwip/pull/15), merged. Awaiting the submodule's release-please PR ([`#16`](https://github.com/fugo101/wireguard-lwip/pull/16), "release 1.0.2") to merge, then a follow-up PR here bumping the submodule pointer (same two-step flow as issue #43's TAI64N fix, `#46`). | 2 |
| 16 | [#35](https://github.com/fugo101/microlink/issues/35) | `Csontikka/microlink` | `7a24a9b3`, `4d3b3add` | DERP client backpressure/reconnect-storm fixes: don't tear down on TLS write backpressure, TCP_NODELAY + coalesced writes, fix a hot-spinning I/O loop, split into concurrent reader/writer tasks — check overlap against cplewes's DERP session-resumption fix (#6) before scoping. **Investigated, needs a dedicated session**: the reader/writer task split is a real architectural conflict, not just a diff to adapt — `ml_derp.c`'s own file header documents this fork's `derp_tx` as a deliberate single task specifically so no TLS mutex is needed ("eliminates the need for a TLS mutex since only one task touches the SSL context"). Splitting it would need real synchronization design, not a surgical port. The backpressure/TCP_NODELAY/hot-spin fixes are smaller and probably extractable independently, but weren't triaged individually this pass — do that first next time rather than trying to take the whole bundle. Also touches `components/wireguard_lwip/` (submodule boundary, same as #31/#34/#42). | 2 |
| 17 | [#36](https://github.com/fugo101/microlink/issues/36) | `Csontikka/microlink` | `27806be3` | `microlink_stop()` never closed `derp.sockfd`/`coord_sock`, letting `derp_tx` outlive the teardown wait → UAF — reconcile against cplewes's teardown UAF fix (#2), may be the same root cause. **Investigated, not needed here**: this fork's `microlink_stop()` (from issue #21/#22's PR #47) never frees context until `ml_join_tasks()` proves every worker exited, and `ml_derp.c`'s blocking loops already call `ml_shutdown_pending()` on every SO_RCVTIMEO-bounded iteration (100-200ms) to bail out cooperatively — the source commit's "shutdown() the socket to force-wake a blocked task" fixes a UAF that doesn't exist here. Leaving open in case future review disagrees, but no port planned. | 2 |
| 18 | [#37](https://github.com/fugo101/microlink/issues/37) | `Csontikka/microlink` | `cbdf1603`, `aad403af`, `533f1f88`, `46e34917`, `017b3588`, `372ca277` | H2 frame reassembly across `noise_recv()` read boundaries — large MapResponses spanning reads deterministically corrupt the stream ("implausible message size"); genuine protocol-correctness bug independent of control-plane backend. **Triaged into 4 pieces — 1/4 landed**: (1) `cbdf1603` (`https://` login_server + Headscale Noise key fetch), `aad403af` ("deliver the netmap from the long-poll stream, Headscale ≥0.26"), and `372ca277` (Headscale v0.28 single-stream compat) are all pure Headscale-control-plane compatibility, out of scope per `CLAUDE.md` (Tailscale-only) — excluded, no port. (2) `533f1f88` bundles two fixes: its stream-liveness watchdog (a second clock fed only by genuine stream-5 DATA frames, so a front end that keeps ACKing our PINGs can't hide a dead server-side mapSession) is real, backend-independent, and **landed** — this fork's existing watchdog (`last_activity_ms`) resets on any inbound *or even outbound-send* activity, so it had exactly this blind spot. Its second half (reorder `ML_EVT_COORD_REGISTERED` to fire after the streamed netmap, not before) is **not applicable**: that race only exists on Csontikka's Headscale ≥0.26 empty-initial-fetch path; this fork's `do_fetch_peers()` always populates `ml->vpn_ip` synchronously before returning, so `ML_EVT_COORD_REGISTERED` already fires after the VPN IP is known — skipped. (3) `46e34917` (DERP relay liveness + peer sweep) needs reconciliation against issue #14's already-landed DERP TLS leak fix (PR #44) before scoping — likely partial overlap, not yet investigated in detail. (4) `017b3588`, the actual H2-reassembly fix this row was originally filed for, is large (287+/-101 lines) and rewrites `do_map_exchange()` — the same hottest, most failure-sensitive control-plane parsing path already flagged as needing hardware to verify for issue #38 — deferred to a dedicated session with real testing. | 2 |
| 19 | [#38](https://github.com/fugo101/microlink/issues/38), [#39](https://github.com/fugo101/microlink/issues/39) | [`djorr5/microlink`](https://github.com/djorr5/microlink) | `67b230b2` | Two independent changes, split into two issues: (a) dynamic H2 RX window sizing based on free heap for RAM-constrained boards, roughly halving MapResponse-parsing PSRAM footprint; (b) `ip4_route_src_hook` to force tailnet-range traffic onto the WG netif directly. **Investigated**: no submodule involvement, both fully in-repo (`ml_h2.c`/`ml_coord.c` for (a), new `ml_lwip_hooks.c` for (b)). (a) is real and reasonably self-contained but rewrites the hottest control-plane parsing path (`do_fetch_peers()`'s buffer allocation and read loop) without hardware to verify it — needs a dedicated session with real testing, not a quick port. (b) is likely **redundant**: lwIP's own `ip4_route()` already scans `netif_list` for a netmask match *before* ever consulting `LWIP_HOOK_IP4_ROUTE_SRC` (confirmed by reading `ip4.c`), and `wg_init_interface()` already registers the WG netif directly into `netif_list` with the correct `/10` netmask — so the hook's netmask-match logic duplicates what already happens. Might still matter in a narrow edge case (netif up/link-up flapping during rebind) but not clearly worth the new file + build wiring for that alone. | 2 |
| 20 | [#40](https://github.com/fugo101/microlink/issues/40) | [`AELovelace/LAIN-MicrolinkRouter`](https://github.com/AELovelace/LAIN-MicrolinkRouter) | `e1239460` | `microlink_set_exit_node()` — default-route exit-node support while preserving per-peer `/32` routes, with routing-loop and liveness fixes. New capability, not a bugfix — needs a product decision (does any current/future downstream want SoftAP/NAPT exit-node routing?) before it's worth the review cost | 2 |
| 21 | [#41](https://github.com/fugo101/microlink/issues/41) | [`caslavskola/microlink`](https://github.com/caslavskola/microlink) | `0265718e` | PSA crypto init migration for mbedTLS 4.x. **Investigated, not needed**: ESP-IDF 6.x's own `mbedtls` component already calls `psa_crypto_init()` automatically at boot (`ESP_SYSTEM_INIT_FN`, priority 104, `components/mbedtls/port/esp_psa_crypto_init.c`) — an explicit call in `microlink_init()` would be pure redundancy. The commit also rewrites `ml_noise.c`'s ChaCha20-Poly1305 from `mbedtls_chachapoly_*` to raw PSA `psa_aead_encrypt/decrypt` calls, but this fork already has a working, cleaner solution via `mbedtls/private/chachapoly.h` (documented in `ESP_IDF_6X_COMPAT.md`) — the source commit's version is messier (leftover `//to remove` debug logging, commented-out ChatGPT-added diagnostics) and fixes nothing we're missing. No port planned. | 2 |
| 22 | [#42](https://github.com/fugo101/microlink/issues/42) | `caslavskola/microlink` | `9ac49212` | Peer endpoint tracking dropped the "packet arrived via DERP" signal after the first packet, causing replies to attempt bad direct routing — genuine bug, but the commit bundles debug cruft and a divergent netif-flag rewrite; extract just the DERP-routing-flag fix | 2 |
| 22 | [#42](https://github.com/fugo101/microlink/issues/42) | `caslavskola/microlink` | `9ac49212` | Peer endpoint tracking dropped the "packet arrived via DERP" signal after the first packet, causing replies to attempt bad direct routing — genuine bug, but the commit bundles debug cruft and a divergent netif-flag rewrite; extract just the DERP-routing-flag fix. **Adapted, landed in the `wireguard_lwip` submodule** (extracted just the `last_rx_via_derp` flag, skipped the `netif_set_link_up/down` rewrite and debug logging): [`fugo101/wireguard-lwip#15`](https://github.com/fugo101/wireguard-lwip/pull/15) (same PR as issue #34, both fixes are small and independent), merged. Awaiting the submodule's release-please PR ([`#16`](https://github.com/fugo101/wireguard-lwip/pull/16), "release 1.0.2") to merge, then a follow-up PR here bumping the submodule pointer. | 2 |
| 23 | [#43](https://github.com/fugo101/microlink/issues/43) | [`dj-oyu/microlink`](https://github.com/dj-oyu/microlink) | multiple (different/pre-refactor file naming) | Bundle of fixes needing adaptation to our `ml_*.c` layout: ~~TAI64N via `gettimeofday()` (fixes replay-rejection after reboot)~~ **superseded — see `UPSTREAM_PRS.md`'s upstream PR #22 (partial) absorption, commit `6a4447c5`: cleaner source, no pre-refactor adaptation needed, don't redo this from dj-oyu**; DERP→direct re-handshake trilogy (`a30160a8`, `eb3dce06`, `c505539d`), `LOCK_TCPIP_CORE` no-op bug fixed via `tcpip_try_callback` (check `ml_net_io.c`/`ml_zerocopy.c` exposure), DISCO PONG rate-limiting (1/5s per peer once direct path established) | 2 |

## Investigated, not worth pursuing
Expand Down