summaryrefslogtreecommitdiff
path: root/server/listen.c
diff options
context:
space:
mode:
authorJoe Orton <jorton@apache.org>2005-08-25 15:56:43 +0000
committerJoe Orton <jorton@apache.org>2005-08-25 15:56:43 +0000
commit67e8ce3fc82bc42210a534cbe0b71e3fb2d0235e (patch)
treeeea1a154134bb67ecfb9b7e6fc51111a32061b80 /server/listen.c
parent4f75bd350859ee044c009dda66b2da942db8a541 (diff)
downloadhttpd-67e8ce3fc82bc42210a534cbe0b71e3fb2d0235e.tar.gz
* server/listen.c (open_listeners): If 0.0.0.0 is found before [::]
for the same port, switch them so that the bind to [::] is attempted first. Submitted by: colm, jorton git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@240096 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/listen.c')
-rw-r--r--server/listen.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/server/listen.c b/server/listen.c
index b322023f27..fc584742aa 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -376,6 +376,30 @@ static int open_listeners(apr_pool_t *pool)
else {
#if APR_HAVE_IPV6
int v6only_setting;
+
+ /* If we have the unspecified IPv4 address (0.0.0.0) and
+ * the unspecified IPv6 address (::) is next, we need to
+ * swap the order of these in the list. We always try to
+ * bind to IPv6 first, then IPv4, since an IPv6 socket
+ * might be able to receive IPv4 packets if V6ONLY is not
+ * enabled, but never the other way around. */
+ if (lr->next != NULL
+ && IS_INADDR_ANY(lr->bind_addr)
+ && lr->bind_addr->port == lr->next->bind_addr->port
+ && IS_IN6ADDR_ANY(lr->next->bind_addr)) {
+ /* Exchange lr and lr->next */
+ ap_listen_rec *next = lr->next;
+ lr->next = next->next;
+ next->next = lr;
+ if (previous) {
+ previous->next = next;
+ }
+ else {
+ ap_listeners = next;
+ }
+ lr = next;
+ }
+
/* If we are trying to bind to 0.0.0.0 and the previous listener
* was :: on the same port and in turn that socket does not have
* the IPV6_V6ONLY flag set; we must skip the current attempt to