Skip to content

ensurePortAvailable in startSshPortForward misses IPv4-only occupants (same address-family flaw as #94379) #94596

Description

@wangwllu

Follow-up to #94379 / #94394.

After #94394 landed the caller-scoped ensurePortAvailable(port, host?), the Chrome CDP caller was fixed, but startSshPortForward in src/infra/ssh-tunnel.ts still calls it host-less:

await ensurePortAvailable(localPort);

This re-introduces the exact #94379 flaw on the SSH-tunnel surface: on a dual-stack host the host-less probe binds the IPv6 wildcard :: and misses an IPv4-only occupant, so the preflight reports a busy port as free.

It's also internally inconsistent — every other probe in this module is pinned to IPv4 loopback:

  • pickEphemeralPortlisten(0, "127.0.0.1")
  • canConnectLocalconnect({ host: "127.0.0.1" })
  • the forward itself → -L ${localPort}:127.0.0.1:${remotePort}

Fix: pass the interface this caller actually owns, matching #94394's pattern:

await ensurePortAvailable(localPort, "127.0.0.1");

Lower harm than the Chrome path (it only affects SSH-tunnel port selection, and it already falls back to an ephemeral port on EADDRINUSE), but it's the same root cause and a one-line scoped fix. Happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExclude from stale automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions