httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r664705 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS server/listen.c
Date Mon, 09 Jun 2008 13:36:43 GMT
Author: jim
Date: Mon Jun  9 06:36:42 2008
New Revision: 664705

URL: http://svn.apache.org/viewvc?rev=664705&view=rev
Log:
Merge r664535 from trunk:

core: Fix address-in-use startup failure on some platforms caused
by attempting to set up an IPv4 listener which overlaps with an 
existing IPv6 listener.

The failure occurred on the second pass of the open-logs hook in
a configuration such as the following:

  Listen 8080
  Listen 0.0.0.0:8081
  Listen [::]:8081

During the first pass, the two port 8081 listen recs were 
adjacent and existing logic prevented binding to 0.0.0.0:8081.
On the second pass, they were not adjacent and we then tried
to bind to 0.0.0.0:8081, leading to failure on some platforms
(seen on SLES 9 and Ubuntu 7.10, not seen on many other Unix-ish
platforms).

Leave a note about other unhandled configurations.

Submitted by: trawick
Reviewed by: jim

Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/server/listen.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=664705&r1=664704&r2=664705&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Mon Jun  9 06:36:42 2008
@@ -5,6 +5,10 @@
      mod_proxy_balancer: Prevent CSRF attacks against the balancer-manager
      interface.  [Joe Orton]
 
+  *) core: Fix address-in-use startup failure on some platforms caused
+     by creating an IPv4 listener which overlaps with an existing IPv6
+     listener.  [Jeff Trawick]
+
   *) mod_proxy: Make all proxy modules nocanon aware and do not add the
      query string again in this case. PR 44803.
      [Jim Jagielski, Ruediger Pluem]

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=664705&r1=664704&r2=664705&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Mon Jun  9 06:36:42 2008
@@ -84,14 +84,6 @@
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
- * core: Fix address-in-use startup failure on some platforms caused
-   by attempting to set up an IPv4 listener which overlaps with an
-   existing IPv6 listener.
-   Trunk version of patch:
-         http://svn.apache.org/viewvc?rev=664535&view=rev
-   Backport version for 2.2.x of patch:
-         Trunk version of patch works
-   +1: trawick, jim, rpluem
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]

Modified: httpd/httpd/branches/2.2.x/server/listen.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/server/listen.c?rev=664705&r1=664704&r2=664705&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/server/listen.c (original)
+++ httpd/httpd/branches/2.2.x/server/listen.c Mon Jun  9 06:36:42 2008
@@ -377,14 +377,22 @@
         }
         else {
 #if APR_HAVE_IPV6
+            ap_listen_rec *cur;
             int v6only_setting;
+            int skip = 0;
 
             /* 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. */
+             * enabled, but never the other way around.
+             * Note: In some configurations, the unspecified IPv6 address
+             * could be even later in the list.  This logic only corrects
+             * the situation where it is next in the list, such as when
+             * apr_sockaddr_info_get() returns an IPv4 and an IPv6 address,
+             * in that order.
+             */
             if (lr->next != NULL
                 && IS_INADDR_ANY(lr->bind_addr)
                 && lr->bind_addr->port == lr->next->bind_addr->port
@@ -402,26 +410,32 @@
                 lr = next;
             }
 
-            /* If we are trying to bind to 0.0.0.0 and the previous listener
+            /* If we are trying to bind to 0.0.0.0 and a 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
              * listen (which would generate an error). IPv4 will be handled
              * on the established IPv6 socket.
              */
-            if (previous != NULL
-                && IS_INADDR_ANY(lr->bind_addr)
-                && lr->bind_addr->port == previous->bind_addr->port
-                && IS_IN6ADDR_ANY(previous->bind_addr)
-                && apr_socket_opt_get(previous->sd, APR_IPV6_V6ONLY,
-                                      &v6only_setting) == APR_SUCCESS
-                && v6only_setting == 0) {
-
-                /* Remove the current listener from the list */
-                previous->next = lr->next;
-                lr = previous; /* maintain current value of previous after
-                                * post-loop expression is evaluated
-                                */
-                continue;
+            if (IS_INADDR_ANY(lr->bind_addr)) {
+                for (cur = ap_listeners; cur != lr; cur = cur->next) {
+                    if (lr->bind_addr->port == cur->bind_addr->port
+                        && IS_IN6ADDR_ANY(cur->bind_addr)
+                        && apr_socket_opt_get(cur->sd, APR_IPV6_V6ONLY,
+                                              &v6only_setting) == APR_SUCCESS
+                        && v6only_setting == 0) {
+
+                        /* Remove the current listener from the list */
+                        previous->next = lr->next;
+                        lr = previous; /* maintain current value of previous after
+                                        * post-loop expression is evaluated
+                                        */
+                        skip = 1;
+                        break;
+                    }
+                }
+                if (skip) {
+                    continue;
+                }
             }
 #endif
             if (make_sock(pool, lr) == APR_SUCCESS) {



Mime
View raw message