Skip to content

fix(daemon): keep the daemon port out of OS ephemeral ranges and bind loopback (#1700) - #1728

Merged
zackees merged 2 commits into
mainfrom
fix/1700-daemon-port-window
Oct 25, 2026
Merged

zackees merged 2 commits into
mainfrom
fix/1700-daemon-port-window

Conversation

@zackees

@zackees zackees commented Oct 25, 2026

Copy link
Copy Markdown
Member

Fixes #1700.

Cause

  • The non-Windows default daemon window was 49152–65535. Linux hands out outgoing source ports from ip_local_port_range, 32768–60999 by default. About 74% of possible daemon ports could therefore be taken by any unrelated outgoing connection on a busy CI runner.
  • When that happened, the daemon's 0.0.0.0:P bind failed with EADDRINUSE while nothing was listening. The retry loop then used up the CLI's 3×10 s spawn budget (daemon did not become healthy after 3 spawn attempts).

Change

  1. Port window. Non-Windows daemons now derive their port in 10000–32767, below both the Linux (32768–60999) and macOS (49152–65535) ephemeral ranges. Windows is unchanged at 10000–49151 (fix(paths): avoid Windows-excluded dynamic ports for daemon endpoints #1322). Ports remain keyed by version and identity, so daemon: endpoint isolation follow-up to #940 — key the default endpoint by cache-identity/checkout + deterministic version arbitration #1009 isolation and single-flight startup are untouched. Each version gets a new port once, which is harmless because the port is already version-derived.
  2. Loopback bind. The daemon binds 127.0.0.1 instead of 0.0.0.0.
    • Every client (CLI, PyO3) connects to 127.0.0.1, and nothing in the repo reaches the daemon from off-box.
    • The heap-dump handler already treated non-loopback callers as hostile.
    • A loopback bind also does not collide with an outgoing socket bound to another local address on the same port.
    • The FBUILD_DAEMON_PORT override still works.

Verification

  • Collision repro (crates/fbuild-core/src/platform/linux/ipc.rs). An outgoing socket bound to 127.0.0.2:P and connected to a local server makes a wildcard listener on P fail, while 127.0.0.1:P binds. This is the mechanism from the issue.
  • Port-range test (crates/fbuild-paths/src/lib.rs). It reads the host's live ip_local_port_range and asserts the default daemon port is outside it. On main this checkout's port was 52817, inside 32768–60999, so the test fails there and passes here. The existing range tests were updated to the new window.
  • Workspace clippy with -D warnings is clean, and the fbuild-daemon, fbuild-paths and fbuild-cli tests pass.
  • Real build. fbuild build tests/platform/uno -e uno succeeded, with the daemon on LISTEN 127.0.0.1:11393.

Not covered

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 27 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 325bb11 and 21f3b13.

Files ignored due to path filters: 1
  • ci/platform_boundary_research.tsv is excluded by !**/*.tsv
Files selected for processing: 7
  • CLAUDE.md
  • crates/CLAUDE.md
  • crates/fbuild-core/src/platform/linux/ipc.rs
  • crates/fbuild-daemon/src/handlers/health.rs
  • crates/fbuild-daemon/src/main.rs
  • crates/fbuild-paths/README.md
  • crates/fbuild-paths/src/lib.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zackees
zackees force-pushed the fix/1700-daemon-port-window branch from 89a994c to 1434230 Compare October 25, 2026 04:45
… loopback (#1700)

On Linux the default daemon window (49152-65535) overlapped the kernel's
ephemeral range (32768-60999), so an unrelated outgoing connection could hold
the daemon's port; the 0.0.0.0 bind then failed with EADDRINUSE while nothing
listened, and startup burned its spawn budget retrying.

Non-Windows daemons now take 10000-32767, below the Linux and macOS ephemeral
ranges, and bind 127.0.0.1 instead of 0.0.0.0 (every client connects to
loopback). Adds a Linux repro of the wildcard-vs-loopback collision and a test
against the host's live ip_local_port_range.
@zackees
zackees force-pushed the fix/1700-daemon-port-window branch from 1434230 to 21f3b13 Compare October 25, 2026 04:57
@zackees
zackees merged commit 6e9e0b4 into main Oct 25, 2026
24 checks passed
@zackees
zackees deleted the fix/1700-daemon-port-window branch October 25, 2026 05:07
@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

fix(daemon): avoid startup stalls when wildcard bind collides without a listener

1 participant