listen: set IP_FREEBIND so binding to a not-yet-present address works#27
Open
DevenDucommun wants to merge 1 commit into
Open
listen: set IP_FREEBIND so binding to a not-yet-present address works#27DevenDucommun wants to merge 1 commit into
DevenDucommun wants to merge 1 commit into
Conversation
When uhttpd is configured to listen on a specific address (instead of
the 0.0.0.0/[::] wildcard) and starts before the network is fully
configured, bind() fails with EADDRNOTAVAIL ("Address not available")
and that listener is dropped. If it was the only configured address,
uhttpd exits with "No sockets bound, unable to continue" and the admin
interface stays unreachable until a manual restart.
Set IP_FREEBIND / IPV6_FREEBIND on the socket before bind() so the
kernel allows binding to an address that is not assigned to a local
interface yet. The socket starts serving as soon as the address is
configured, which removes the startup race without relying on the
init script's interface-up trigger (which misses DHCP, alias and VLAN
addresses that are not statically mapped to an interface).
The options are best effort and guarded with #ifdef; a failed
setsockopt is logged but not fatal, so kernels without FREEBIND keep
the previous behaviour.
Signed-off-by: Deven Ducommun <deven.ducommun@gmail.com>
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes openwrt/openwrt#18551
When uhttpd listens on a specific address instead of the 0.0.0.0/[::] wildcard, and it starts before the network is fully up, bind() fails with EADDRNOTAVAIL and the listener is dropped. If that was the only configured address, uhttpd prints "bind(): Address not available" followed by "No sockets bound, unable to continue" and the web UI never comes back without a manual restart. People have been hitting this on 23.05 through 25.12, especially with VLAN/management interfaces where the init script's interface-up trigger does not map the listen IP to an interface.
This sets IP_FREEBIND / IPV6_FREEBIND before bind() so the kernel lets us bind to an address that is not assigned yet. The socket starts serving the moment the address appears, so the startup race goes away without depending on the trigger heuristic. The options are best effort and #ifdef guarded, and a failed setsockopt is logged but not fatal.
Tested by building uhttpd from this branch and reproducing the issue in a Linux container:
Verified both IPv4 (IP_FREEBIND) and IPv6 (IPV6_FREEBIND) paths, and confirmed both constants are defined under glibc and musl.
This patch was developed with AI assistance. I have reviewed, understood, and tested the change.