]> granicus.if.org Git - apache/commitdiff
* server/listen.c (open_listeners): If 0.0.0.0 is found before [::]
authorJoe Orton <jorton@apache.org>
Thu, 25 Aug 2005 15:56:43 +0000 (15:56 +0000)
committerJoe Orton <jorton@apache.org>
Thu, 25 Aug 2005 15:56:43 +0000 (15:56 +0000)
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

server/listen.c

index b322023f27aa10369893076ae03b8fed7089d6d7..fc584742aa45e67b445b8b40ee9c05760123a2ee 100644 (file)
@@ -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