Skip to content

test: use IP_PORTRANGE_HIGH on FreeBSD for dynamic port allocation#34336

Closed
w0xlt wants to merge 1 commit intobitcoin:masterfrom
w0xlt:freebsd_high_port_range
Closed

test: use IP_PORTRANGE_HIGH on FreeBSD for dynamic port allocation#34336
w0xlt wants to merge 1 commit intobitcoin:masterfrom
w0xlt:freebsd_high_port_range

Conversation

@w0xlt
Copy link
Contributor

@w0xlt w0xlt commented Jan 19, 2026

On FreeBSD, the default ephemeral port range (10000-65535) overlaps with the test framework's static port range (11000-26000), possibly causing intermittent "address already in use" failures when tests use dynamic port allocation (port=0).

This PR adds a helper that sets IP_PORTRANGE_HIGH via setsockopt() before binding, requesting ports from 49152-65535 instead, which avoids the overlap, as suggested in #34331 (comment) by @maflcko .

From FreeBSD's sys/netinet/in.h:

#define IP_PORTRANGE         19
#define IP_PORTRANGE_HIGH    1
#define IPPORT_EPHEMERALFIRST 10000  /* default range start */
#define IPPORT_HIFIRSTAUTO   49152   /* high range start */

See also: FreeBSD https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 man page.

I’ll leave the PR as a draft since I haven’t tested it on FreeBSD yet and would like to gather feedback on the approach.

Fixes #34331

On FreeBSD, the default ephemeral port range (10000-65535) overlaps
with the test framework's static port range (11000-26000), causing
intermittent "address already in use" failures when tests use dynamic
port allocation (port=0).

Add a helper function that sets the IP_PORTRANGE socket option to
IP_PORTRANGE_HIGH before binding, which requests ports from the high
range (49152-65535) instead. This range does not overlap with the
test framework's static ports.

Constants from FreeBSD's netinet/in.h:
- IP_PORTRANGE = 19
- IP_PORTRANGE_HIGH = 1

Fixes: bitcoin#34331

Co-Authored-By: MarcoFalke <*~=\`'#}+{/-|&$^_@721217.xyz>
@DrahtBot DrahtBot added the Tests label Jan 19, 2026
@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 19, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34336.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

@w0xlt w0xlt marked this pull request as draft January 19, 2026 10:33
@hebasto
Copy link
Member

hebasto commented Jan 19, 2026

cc @vasild

@vasild
Copy link
Contributor

vasild commented Jan 19, 2026

    sock.setsockopt(socket.IPPROTO_IP, IP_PORTRANGE, IP_PORTRANGE_HIGH)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument

It is possible to configure the port range system-wide with, e.g.:

root# sysctl net.inet.ip.portrange.first=32768

@w0xlt w0xlt closed this Jan 19, 2026
@w0xlt w0xlt deleted the freebsd_high_port_range branch January 19, 2026 14:51
@vasild
Copy link
Contributor

vasild commented Jan 19, 2026

This works and has the intended effect, from a C++ program:

    int val{IP_PORTRANGE_HIGH};
    setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &val, sizeof(val));

@w0xlt w0xlt restored the freebsd_high_port_range branch January 19, 2026 17:44
@w0xlt
Copy link
Contributor Author

w0xlt commented Jan 19, 2026

Reopening. I’ve now tested it on FreeBSD and it works.

@w0xlt
Copy link
Contributor Author

w0xlt commented Jan 19, 2026

The issue was caused by feature_proxy.py using IPv6 sockets. On FreeBSD, IPv6 requires IPV6_PORTRANGE with IPPROTO_IPV6.

hebasto added a commit that referenced this pull request Jan 29, 2026
… allocation

2845f10 test: extend FreeBSD ephemeral port range fix to P2P listeners (node)
34bed0e test: use IP_PORTRANGE_HIGH on FreeBSD for dynamic port allocation (woltx)

Pull request description:

  Reopening #34336. I’ve now tested it on FreeBSD and confirmed it works.

  On FreeBSD, the default ephemeral port range (10000-65535) overlaps with the test framework's static port range (11000-26000), possibly causing intermittent "address already in use" failures when tests use dynamic port allocation (`port=0`).

  This PR adds a helper that sets `IP_PORTRANGE_HIGH` via `setsockopt()` before binding, requesting ports from 49152-65535 instead, which avoids the overlap, as suggested in #34331 (comment) by @maflcko .

  From FreeBSD's [sys/netinet/in.h](https://cgit.freebsd.org/src/tree/sys/netinet/in.h):
    ```c
    #define IP_PORTRANGE         19
    #define IP_PORTRANGE_HIGH    1
    #define IPPORT_EPHEMERALFIRST 10000  /* default range start */
    #define IPPORT_HIFIRSTAUTO   49152   /* high range start */
  ```

  See also: FreeBSD https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 man page.

  Fixes #34331

ACKs for top commit:
  vasild:
    ACK 2845f10
  hebasto:
    ACK 2845f10, I have reviewed the code and it looks OK.

Tree-SHA512: ce501ce3e8a4023e07bad572df2b85d6829becf133813e4529aebba83e4eba59fa8b48e9d2197ebbb226adaf3054fad720775a787244d6b38c0078ee086102f4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

qa: Failure in p2p_fingerprint.py

4 participants