]> granicus.if.org Git - apache/commitdiff
More fun with IPv6 Listen statements.
authorJustin Erenkrantz <jerenkrantz@apache.org>
Thu, 14 Aug 2003 00:05:26 +0000 (00:05 +0000)
committerJustin Erenkrantz <jerenkrantz@apache.org>
Thu, 14 Aug 2003 00:05:26 +0000 (00:05 +0000)
- Remove the default_family declaration as it is no longer used.
- Fix segfault if checking NULL sa->hostname.
- Cycle through the bind_addr list if we get an error creating an IPv6 socket
  and we're IPv6 enabled and the binding address is NULL.  The odds are that
  we just can't support IPv6.  (The twist is that apr_sockaddr_info_get should
  return bind_addr's for IPv6 and IPv4.  This strikes me as slightly more
  elegant than the find_default_family hack.)

This should get us working on Linux and Netware again.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@100994 13f79535-47bb-0310-9956-ffa450edef68

server/listen.c

index a8977d0110fa0494d439846494e98c248b55e892..c91da9f8dbfa8940c9f1b3722301d8e39aa7be70 100644 (file)
 
 ap_listen_rec *ap_listeners = NULL;
 
-#if APR_HAVE_IPV6
-static int default_family = APR_UNSPEC;
-#else
-static int default_family = APR_INET;
-#endif
-
 static ap_listen_rec *old_listeners;
 static int ap_listenbacklog;
 static int send_buffer_size;
@@ -249,8 +243,12 @@ static const char *alloc_listener(process_rec *process, char *addr, apr_port_t p
         /* Some listeners are not real so they will not have a bind_addr. */
         if (sa) {
             apr_sockaddr_port_get(&oldport, sa);
-            if (!strcmp(sa->hostname, addr) && port == oldport) {
-                /* re-use existing record */
+            /* If both ports are equivalent, then if their names are equivalent,
+             * then we will re-use the existing record.
+             */
+            if (port == oldport &&
+                ((!addr && !sa->hostname) ||
+                 ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) {
                 new = *walk;
                 *walk = new->next;
                 new->next = ap_listeners;
@@ -271,10 +269,27 @@ static const char *alloc_listener(process_rec *process, char *addr, apr_port_t p
                       addr);
         return "Listen setup failed";
     }
-    if ((status = apr_socket_create(&new->sd,
-                                    new->bind_addr->family,
-                                    SOCK_STREAM, process->pool))
-        != APR_SUCCESS) {
+
+    while (new->bind_addr) {
+        status = apr_socket_create(&new->sd, new->bind_addr->family,
+                                    SOCK_STREAM, process->pool);
+#if APR_HAVE_IPV6
+        /* What could happen is that we got an IPv6 address, but this system
+         * doesn't actually support IPv6.  Try the next address.
+         */
+        if (status != APR_SUCCESS && !addr &&
+            new->bind_addr->family == APR_INET6) {
+            new->bind_addr = new->bind_addr->next;
+        }
+        else {
+            break;
+        }
+#else
+        break;
+#endif
+    }
+
+    if (status != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
                       "alloc_listener: failed to get a socket for %s", addr);
         return "Listen setup failed";