]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Don't require all listeners to be created equal ...
authorNick Kew <niq@apache.org>
Wed, 19 Aug 2009 23:55:14 +0000 (23:55 +0000)
committerNick Kew <niq@apache.org>
Wed, 19 Aug 2009 23:55:14 +0000 (23:55 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@806010 13f79535-47bb-0310-9956-ffa450edef68

include/ap_listen.h
server/listen.c

index b623495ba1c4af4fbaac4210f2690676caa8365f..3c73043698b4e7255ad87f67b2b41d0940958ea9 100644 (file)
@@ -34,6 +34,7 @@
 extern "C" {
 #endif
 
+typedef struct ap_slave_t ap_slave_t;
 typedef struct ap_listen_rec ap_listen_rec;
 typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans);
 
@@ -68,6 +69,8 @@ struct ap_listen_rec {
      * The default protocol for this listening socket.
      */
     const char* protocol;
+
+    ap_slave_t *slave;
 };
 
 /**
@@ -92,6 +95,7 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s);
  * Loop through the global ap_listen_rec list and close each of the sockets.
  */
 AP_DECLARE_NONSTD(void) ap_close_listeners(void);
+AP_DECLARE_NONSTD(int) ap_close_listeners_selected(ap_slave_t*);
 
 /* Although these functions are exported from libmain, they are not really
  * public functions.  These functions are actually called while parsing the
index 8361fb3c35d132f5443886c0bb3746f31b77d0e6..4a237150656ff8f7dd5bf664f3d3321a6d133bb1 100644 (file)
@@ -234,7 +234,8 @@ static apr_status_t close_listeners_on_exec(void *v)
 }
 
 static const char *alloc_listener(process_rec *process, char *addr,
-                                  apr_port_t port, const char* proto)
+                                  apr_port_t port, const char* proto,
+                                  void *dummy)
 {
     ap_listen_rec **walk, *last;
     apr_status_t status;
@@ -269,6 +270,9 @@ static const char *alloc_listener(process_rec *process, char *addr,
     }
 
     if (found_listener) {
+        if (ap_listeners->slave != dummy) {
+            return "Cannot define a slave on the same IP:port as a Listener";
+        }
         return NULL;
     }
 
@@ -326,6 +330,7 @@ static const char *alloc_listener(process_rec *process, char *addr,
             last->next = new;
             last = new;
         }
+        new->slave = dummy;
     }
 
     return NULL;
@@ -581,6 +586,22 @@ AP_DECLARE_NONSTD(void) ap_close_listeners(void)
         lr->active = 0;
     }
 }
+AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave)
+{
+    ap_listen_rec *lr;
+    int n = 0;
+
+    for (lr = ap_listeners; lr; lr = lr->next) {
+        if (lr->slave != slave) {
+            apr_socket_close(lr->sd);
+            lr->active = 0;
+        }
+        else {
+            ++n;
+        }
+    }
+    return n;
+}
 
 AP_DECLARE(void) ap_listen_pre_config(void)
 {
@@ -589,7 +610,10 @@ AP_DECLARE(void) ap_listen_pre_config(void)
     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
 }
 
-
+/* Hack: populate an extra field
+ * When this gets called from a Listen directive, dummy is null.
+ * So we can use non-null dummy to pass a data pointer without conflict
+ */
 AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
                                                 int argc, char *const argv[])
 {
@@ -636,7 +660,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
         ap_str_tolower(proto);
     }
 
-    return alloc_listener(cmd->server->process, host, port, proto);
+    return alloc_listener(cmd->server->process, host, port, proto, dummy);
 }
 
 AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,