]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport support for ping/pong.
authorMladen Turk <mturk@apache.org>
Mon, 27 Nov 2006 15:00:56 +0000 (15:00 +0000)
committerMladen Turk <mturk@apache.org>
Mon, 27 Nov 2006 15:00:56 +0000 (15:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@479647 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/proxy/NWGNUproxyajp
modules/proxy/ajp.h
modules/proxy/ajp_utils.c [new file with mode: 0644]
modules/proxy/config.m4
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_ajp.c
modules/proxy/mod_proxy_ajp.dsp

diff --git a/CHANGES b/CHANGES
index 93961a8ac93766628186a2a6419a24dba08088d9..ce036380d586a8c43d986a10079946b223d4b63c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,12 @@ Changes with Apache 2.2.4
      parameter in the URL correctly. PR 40400.
      [Ruediger Pluem, Tomokazu Harada <harada sysrdc.ns-sol.co.jp>]
 
+  *) mod_proxy_ajp: Added cping/cpong support for the AJP protocol.
+     A new worker directive ping=timeout will cause CPING packet
+     to be send expecting CPONG packet within defined timeout.  
+     In case the backend is too busy this will fail instead
+     sending the full header.  [Mladen Turk]
+
   *) mod_disk_cache: Make sure that only positive integers are accepted
      for the CacheMaxFileSize and CacheMinFileSize parameters in the
      config file. PR39380 [Niklas Edmundsson <nikke acc.umu.se>]
diff --git a/STATUS b/STATUS
index 20a9b43f7aa4841ebf8e30ff69d56d49d99afc98..4a64359aa6eef68544f6232735045a5ac780a3a6 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -156,18 +156,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
         deflate output filter.
       +1: rpluem, niq
 
-    * mod_proxy: Add in support for ping/pong (heartbeat test) for
-      the Proxy. Implement cping/cpong for AJP.
-      Trunk version of patch:
-        http://svn.apache.org/viewvc?view=rev&revision=425454
-      2.2.x version of patch:
-        http://people.apache.org/~jim/patches/pingpong2.txt
-        http://svn.apache.org/viewvc?view=rev&revision=425559
-        http://svn.apache.org/viewvc?view=rev&revision=425690
-        http://svn.apache.org/viewvc?view=rev&revision=452549
-        (Note: your patch should auto-createmodules/proxy/ajp_utils.c)
-      +1: jim, rpluem, mturk
-
     * Allow htcacheclean and httxt2dbm to link apr/apr-util statically
       like the older support programs.
       Trunk version of patch:
index 3d65d706c43a36bf1fd35f0ab7a88f68ab37d81d..6750891413dff5a176a15e6bb6232b91e6269f8e 100644 (file)
@@ -171,6 +171,7 @@ FILES_nlm_objs = \
        $(OBJDIR)/ajp_header.o \
        $(OBJDIR)/ajp_msg.o \
        $(OBJDIR)/ajp_link.o \
+       $(OBJDIR)/ajp_utils.o \
        $(OBJDIR)/libprews.o \
        $(EOLIST)
 
index d10f3976271c17f5b62ac18d10f92598b8bd5721..171fb9213031341ed9b39bdfa0e50d62d4efcd37 100644 (file)
@@ -471,6 +471,17 @@ apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf,
 apr_status_t  ajp_parse_data(request_rec  *r, ajp_msg_t *msg,
                              apr_uint16_t *len, char **ptr);
 
+
+/** 
+ * Handle the CPING/CPONG messages
+ * @param sock      backend socket
+ * @param r         current request
+ * @param timeout   time window for receiving cpong reply
+ * @return          APR_SUCCESS or error
+ */
+apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock,
+                                    request_rec *r,
+                                    apr_interval_time_t timeout);
 /** @} */
 
 #endif /* AJP_H */
diff --git a/modules/proxy/ajp_utils.c b/modules/proxy/ajp_utils.c
new file mode 100644 (file)
index 0000000..17e25bf
--- /dev/null
@@ -0,0 +1,105 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ajp.h"
+
+/*
+ * Handle the CPING/CPONG
+ */
+apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock,
+                                    request_rec *r,
+                                    apr_interval_time_t timeout)
+{
+    ajp_msg_t *msg;
+    apr_status_t rc, rv;
+    apr_interval_time_t org;
+    apr_byte_t result;
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                         "Into ajp_handle_cping_cpong");
+
+    rc = ajp_msg_create(r->pool, &msg);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: ajp_msg_create failed");
+        return rc;
+    }
+
+    rc = ajp_msg_serialize_cping(msg);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: ajp_marshal_into_msgb failed");
+        return rc;
+    }
+
+    rc = ajp_ilink_send(sock, msg);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: ajp_ilink_send failed");
+        return rc;
+    }
+
+    rc = apr_socket_timeout_get(sock, &org);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: apr_socket_timeout_get failed");
+        return rc;
+    }
+
+    /* Set CPING/CPONG response timeout */
+    rc = apr_socket_timeout_set(sock, timeout);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: apr_socket_timeout_set failed");
+        return rc;
+    }
+    ajp_msg_reuse(msg);
+
+    /* Read CPONG reply */
+    rv = ajp_ilink_receive(sock, msg);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: ajp_ilink_receive failed");
+        goto cleanup;
+    }
+
+    rv = ajp_msg_get_uint8(msg, &result);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: invalid CPONG message");
+        goto cleanup;
+    }
+    if (result != CMD_AJP13_CPONG) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: awaited CPONG, received %d ",
+               result);
+        rv = APR_EGENERAL;
+        goto cleanup;
+    }
+
+cleanup:
+    /* Restore original socket timeout */
+    rc = apr_socket_timeout_set(sock, org);
+    if (rc != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+               "ajp_handle_cping_cpong: apr_socket_timeout_set failed");
+        return rc;
+    }
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                         "ajp_handle_cping_cpong: Done");
+    return rv;
+}
index f131ee661111115a2f1c048653d0f60cf87eca02..da0a0b31485568fb572ce0e54fd32ef1c547db17 100644 (file)
@@ -16,7 +16,7 @@ APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , $proxy_mods_enable)
 proxy_connect_objs="mod_proxy_connect.lo"
 proxy_ftp_objs="mod_proxy_ftp.lo"
 proxy_http_objs="mod_proxy_http.lo"
-proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo"
+proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo ajp_utils.lo"
 proxy_balancer_objs="mod_proxy_balancer.lo"
 
 case "$host" in
index f972ab198492caf5c04c4974d004fd853eefb145..9e78853df5af637f9bf61428f2de6f08a6a90c60 100644 (file)
@@ -250,6 +250,15 @@ static const char *set_worker_param(apr_pool_t *p,
             return "lbset must be between 0 and 99";
         worker->lbset = ival;
     }
+    else if (!strcasecmp(key, "ping")) {
+        /* Ping/Pong timeout in seconds.
+         */
+        ival = atoi(val);
+        if (ival < 1)
+            return "Ping/Pong timeout must be at least one second";
+        worker->ping_timeout = apr_time_from_sec(ival);
+        worker->ping_timeout_set = 1;
+    }
     else {
         return "unknown Worker parameter";
     }
index d3a6cc7ead8f7a8cae4296fc099953295aaffef0..12659e7defe4f2fae82f5a4f537b50d2dae682c4 100644 (file)
@@ -325,6 +325,8 @@ struct proxy_worker {
     } flush_packets;           /* control AJP flushing */
     int             flush_wait;  /* poll wait time in microseconds if flush_auto */
     int             lbset;      /* load balancer cluster set */
+    apr_interval_time_t ping_timeout;
+    char ping_timeout_set;
 };
 
 /*
index c0dfbfa84df9a8c1dd495c49639e7d66114e8c4c..75ea68befc85754e3ba79c494f400fed317da14e 100644 (file)
@@ -532,6 +532,20 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker,
         goto cleanup;
     }
 
+    /* Handle CPING/CPONG */
+    if (worker->ping_timeout_set) {
+        status = ajp_handle_cping_cpong(backend->sock, r,
+                                        worker->ping_timeout);
+        if (status != APR_SUCCESS) {
+            backend->close++;
+            ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+                         "proxy: AJP: cping/cpong failed to %pI (%s)",
+                         worker->cp->addr,
+                         worker->hostname);
+            status = HTTP_SERVICE_UNAVAILABLE;
+            goto cleanup;
+        }
+    }
     /* Step Three: Process the Request */
     status = ap_proxy_ajp_request(p, r, backend, origin, dconf, uri, url,
                                   server_portstr);
index 989a702028a2786d6b90dc5dda14aef2afdc3663..0a0873b92faac173f19b1dbb7edfd2059cf735e0 100644 (file)
@@ -126,6 +126,10 @@ SOURCE=.\ajp_link.c
 
 SOURCE=.\ajp_msg.c
 # End Source File
+# Begin Source File
+
+SOURCE=.\ajp_utils.c
+# End Source File
 # End Group
 # Begin Source File