From: Jeff Trawick Date: Tue, 30 Jul 2002 14:52:12 +0000 (+0000) Subject: When deciding on the default address family for listening sockets, X-Git-Tag: 2.0.40~78 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e0a6a5f0084f111209827f6d4e625a7faadf7ed;p=apache When deciding on the default address family for listening sockets, make sure we can actually bind to an AF_INET6 socket before deciding that we should default to AF_INET6. This fixes a startup problem on certain levels of OpenUNIX. PR: 10235 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@96237 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 9543f5c3cd..6c0fdcdc62 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,10 @@ Changes with Apache 2.0.40 + *) When deciding on the default address family for listening sockets, + make sure we can actually bind to an AF_INET6 socket before + deciding that we should default to AF_INET6. This fixes a startup + problem on certain levels of OpenUNIX. PR 10235. [Jeff Trawick] + *) Replace usage of atol() to parse strings when we might want a larger-than-long value with apr_atoll(), which returns long long. This allows HTTPD to deal with larger files correctly. diff --git a/server/listen.c b/server/listen.c index ab7df87131..60f936f4a8 100644 --- a/server/listen.c +++ b/server/listen.c @@ -219,19 +219,28 @@ static void find_default_family(apr_pool_t *p) #if APR_HAVE_IPV6 /* We know the platform supports IPv6, but this particular * system may not have IPv6 enabled. See if we can get an - * AF_INET6 socket. + * AF_INET6 socket and bind to an ephemeral port. (On most + * systems, getting an AF_INET6 socket is a sufficient test. + * On certain levels of OpenUNIX, getting the socket is + * successful but bind always returns ENETUNREACH.) */ if (default_family == APR_UNSPEC) { + apr_status_t sock_rv; apr_socket_t *tmp_sock; + apr_sockaddr_t *sa; - if (apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, - p) == APR_SUCCESS) { - apr_socket_close(tmp_sock); + if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, p)) + == APR_SUCCESS && + apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS && + apr_bind(tmp_sock, sa) == APR_SUCCESS) { default_family = APR_INET6; } else { default_family = APR_INET; } + if (sock_rv == APR_SUCCESS) { + apr_socket_close(tmp_sock); + } } #endif }