freeport

package
v1.28.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package freeport provides a shared, dependency-free TCP host-port allocator: a dual-stack bindability probe and a predicate-injected free-port search. It is a leaf package (stdlib only) so both internal/cli (host-proxy dev servers) and internal/serviceops (the service port-ownership guard) can import it without an import cycle, and so the search logic stays unit-testable without binding real sockets.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bindable

func Bindable(port int) bool

Bindable reports whether a TCP port can be bound across the addresses lerd's published quadlets and host-proxy dev servers publish on. A bind test is stricter and more accurate than a dial test for "can we publish here": it catches a port reserved on any stack, not just one with a live listener.

Three probes must all succeed. The loopback specifics (127.0.0.1 and [::1]) catch a server on a specific loopback address, and the [::1] probe also catches a v6-only wildcard [::] since it covers ::1. The wildcard probe (net.Listen on "0.0.0.0", an IPv4 all-interfaces socket) catches a v4-wildcard server (e.g. a MySQL on bind-address 0.0.0.0) that a specific-address bind slips past under SO_REUSEADDR on BSD/macOS, which would otherwise read as free. On macOS a running lerd container's gvproxy holds the dual-stack wildcard, so the wildcard probe reports its port in use; gvproxy releases it synchronously when the container stops, so a reinstall still rebinds without a spurious shift. A host with no IPv6 loopback at all is tolerated — the v6 check is skipped rather than treated as busy.

The wildcard probe is released before the loopback pair is bound: on Linux a held wildcard listener blocks a subsequent specific bind in the same process (EADDRINUSE), so overlapping them would make every port read as busy. The loopback pair is still held atomically across the two stacks.

func FirstFree

func FirstFree(start int, taken func(int) bool) int

FirstFree returns the first port at or above start for which taken reports false. The predicate is injected so the search is unit-testable without binding real sockets; callers compose it from Bindable plus any reserved-port set of their own. start is clamped to >= 1. Returns 0 when nothing in [start, 65535] is free, so callers can decide their own fallback.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL