halrmt: Allow IPv4 as fallback when IPv6 is disabled. - #4405
Conversation
| return -1; | ||
| } | ||
| } | ||
| setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); |
There was a problem hiding this comment.
Same as #4403: this depends on net.ipv6.bindv6only being 0. With that sysctl at
1, socket(AF_INET6, ...) succeeds so the fallback never fires and IPv4 clients
get ECONNREFUSED. Confirmed:
v6only=0 IPv4 client: connected OK
v6only=1 IPv4 client: connect FAILED (Connection refused)
Explicit setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, ...) on the IPv6
branch?
| addr.addr6.sin6_port = htons(port); | ||
| socklen_t slen = sizeof(addr.addr6); | ||
|
|
||
| sockfd = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); |
There was a problem hiding this comment.
Is EAFNOSUPPORT the only failure worth falling back on? EACCES/EPERM from a
restricted netns or LSM policy reach the same point, and bind() to :: can fail
independently of socket(). Reason not to fall back on any IPv6 failure?
| struct sockaddr_in6 csa6; | ||
| struct sockaddr_in csa4; | ||
| } csa; | ||
| socklen_t csal = isipv4 ? sizeof(csa.csa4) : sizeof(csa.csa6); |
There was a problem hiding this comment.
accept4() writes the real length back, so sizeof(csa) works for both families.
Would sockaddr_storage plus getnameinfo(..., NI_NUMERICHOST | NI_NUMERICSERV)
remove the union, isipv4, and the duplicated logging branch below altogether?
The new halrmt server uses v4-mapped-on-v6 to have one socket accept both IPv6 and IPv4 connections. However, if IPv6 is disabled at the kernel command line (or not compiled in), then it would fail to create a listening socket. This PR adds an IPv4-only fallback in case IPv6 fails.