← Back to PRs

#17257: fix(bonjour): stop mDNS flood on multi-NIC same-LAN setups (#17222)

by yinghaosang open 2026-02-15 15:37 View on GitHub →
gateway stale size: M trusted-contributor
## Summary Running `openclaw gateway` on a machine with multiple network interfaces on the same LAN (e.g. both ethernet and WiFi) causes an mDNS flood — every device on the network starts continuously querying `openclaw.local` and the machine responds from both IPs, making the LAN unusable. Closes #17222 lobster-biscuit ## Root Cause `startGatewayBonjourAdvertiser` calls ciao's `getResponder()` with no options, so the mDNS responder binds to all network interfaces. When two interfaces share the same LAN (like `enp5s0` at 192.168.1.130 and `wlan0` at 192.168.1.118), ciao advertises and responds on both, triggering a flood of conflicting mDNS responses with cache-flush bits set. ## Changes - Before: mDNS responder binds to all interfaces — multi-NIC same-LAN setups cause mDNS storms - After: responder is restricted to the primary LAN interface via `pickPrimaryLanIPv4()` (prefers en0/eth0, falls back to first external IPv4) The fix adds a `networkInterface` option to `GatewayBonjourAdvertiseOpts` and passes it through to ciao's `getResponder({ interface })`. The caller in `server-discovery-runtime.ts` resolves the primary LAN IP using the existing `pickPrimaryLanIPv4()` helper. ## Tests - `src/infra/bonjour.test.ts` — 2 new tests: verifies `getResponder` receives the `interface` option when `networkInterface` is set, and receives `undefined` when omitted. Both fail before fix, pass after. - All 9 bonjour tests pass, all 75 infra tests pass, all 44 gateway tests pass - `pnpm build && pnpm check` pass <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR fixes an mDNS flood issue on machines with multiple network interfaces on the same LAN (e.g., both Ethernet and WiFi). The fix pins the ciao mDNS responder to a single primary LAN interface via the existing `pickPrimaryLanIPv4()` helper, rather than binding to all interfaces which caused conflicting mDNS responses. - Added `networkInterface` option to `GatewayBonjourAdvertiseOpts` and wired it through to ciao's `getResponder({ interface })` in `src/infra/bonjour.ts` - `server-discovery-runtime.ts` resolves the primary LAN IP via `pickPrimaryLanIPv4()` (prefers `en0`/`eth0`, falls back to first external IPv4) and passes it as `networkInterface` - The `undefined` case (no LAN IP found) is handled correctly — ciao falls back to binding all interfaces, preserving existing behavior for single-NIC setups - Well-tested: 3 new unit tests in `bonjour.test.ts` and 2 new integration tests in `server-discovery-runtime.test.ts` <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it's a targeted, well-tested fix that gracefully falls back to existing behavior when no primary LAN IP is found. - The change is minimal and focused: a single new option threaded through existing plumbing, with a correct ternary guard that avoids passing `{ interface: undefined }` to ciao. The `undefined` fallback preserves existing behavior for single-NIC setups. All edge cases (set, omitted, explicitly undefined) are covered by tests. No security concerns, no breaking API changes, and no unintended side effects. - No files require special attention. <sub>Last reviewed commit: e4e4dfa</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs