From: Graham Leggett Date: Mon, 21 Jun 2021 17:03:35 +0000 (+0000) Subject: *) back port: Add CPING to health check logic. X-Git-Tag: candidate-2.4.49~3^2~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=044b45e0da8db6332383aa1fc9301848d1c81ab8;p=thirdparty%2Fapache%2Fhttpd.git *) back port: Add CPING to health check logic. Trunk version of patch: https://svn.apache.org/r1887415 Backport version for 2.4.x of patch: Trunk version of patch works svn merge -c 1887415 ^/httpd/httpd/trunk . +1: jfclere, jim, minfrin git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1890947 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 40d0a93b0c2..3920c6a4c3f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.49 + *) Add CPING to health check logic. [Jean-Frederic Clere] + *) core: Split ap_create_request() from ap_read_request(). [Graham Leggett] *) core, h2: common ap_parse_request_line() and ap_check_request_header() diff --git a/STATUS b/STATUS index f9a5ddb882a..31a364a38c1 100644 --- a/STATUS +++ b/STATUS @@ -142,13 +142,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) back port: Add CPING to health check logic. - Trunk version of patch: - https://svn.apache.org/r1887415 - Backport version for 2.4.x of patch: - Trunk version of patch works - svn merge -c 1887415 ^/httpd/httpd/trunk . - +1: jfclere, jim, minfrin PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/include/ap_mmn.h b/include/ap_mmn.h index a2bf24527a7..239273762f0 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -562,6 +562,7 @@ * 20120211.106 (2.4.49-dev) Add ap_create_request(). * 20120211.107 (2.4.49-dev) Add ap_parse_request_line() and * ap_check_request_header() + * 20120211.108 (2.4.49-dev) Add ajp_handle_cping_cpong */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -569,7 +570,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 107 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 108 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 56461707cd2..c1c61068bcf 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -1310,6 +1310,15 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel); APR_DECLARE_OPTIONAL_FN(int, ap_proxy_clear_connection, (request_rec *r, apr_table_t *headers)); +/** + * Do a AJP CPING and wait for CPONG on the socket + * + */ +APR_DECLARE_OPTIONAL_FN(apr_status_t, ajp_handle_cping_cpong, + (apr_socket_t *sock, request_rec *r, + apr_interval_time_t timeout)); + + /** * @param socket socket to test * @return TRUE if socket is connected/active diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index dc669164895..e2992fcb49c 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -832,6 +832,7 @@ static void ap_proxy_http_register_hook(apr_pool_t *p) { proxy_hook_scheme_handler(proxy_ajp_handler, NULL, NULL, APR_HOOK_FIRST); proxy_hook_canon_handler(proxy_ajp_canon, NULL, NULL, APR_HOOK_FIRST); + APR_REGISTER_OPTIONAL_FN(ajp_handle_cping_cpong); } AP_DECLARE_MODULE(proxy_ajp) = { diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 0d56d1b3de7..ece8498b6d9 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -1089,6 +1089,8 @@ static void push2table(const char *input, apr_table_t *params, } ap_unescape_url(key); ap_unescape_url(val); + /* hcuri, worker name, balancer name, at least are escaped when building the form, so twice */ + ap_unescape_url(val); if (allowed == NULL) { /* allow all */ apr_table_set(params, key, val); } @@ -1329,7 +1331,7 @@ static int balancer_handler(request_rec *r) *wsel->s->hcexpr = '\0'; } /* If the health check method doesn't support an expr, then null it */ - if (wsel->s->method == NONE || wsel->s->method == TCP) { + if (wsel->s->method == NONE || wsel->s->method == TCP || wsel->s->method == CPING) { *wsel->s->hcexpr = '\0'; } /* if enabling, we need to reset all lb params */ diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c index 6f9902ea339..9986f1a9bd7 100644 --- a/modules/proxy/mod_proxy_hcheck.c +++ b/modules/proxy/mod_proxy_hcheck.c @@ -75,6 +75,8 @@ typedef struct { apr_time_t *now; } baton_t; +static APR_OPTIONAL_FN_TYPE(ajp_handle_cping_cpong) *ajp_handle_cping_cpong = NULL; + static void *hc_create_config(apr_pool_t *p, server_rec *s) { sctx_t *ctx = apr_pcalloc(p, sizeof(sctx_t)); @@ -613,6 +615,39 @@ static int hc_get_backend(const char *proxy_function, proxy_conn_rec **backend, return hc_determine_connection(ctx, hc, &(*backend)->addr, ptemp); } +static apr_status_t hc_check_cping(baton_t *baton) +{ + int status; + sctx_t *ctx = baton->ctx; + proxy_worker *hc = baton->hc; + proxy_conn_rec *backend = NULL; + apr_pool_t *ptemp = baton->ptemp; + request_rec *r; + apr_interval_time_t timeout; + + if (!ajp_handle_cping_cpong) { + return APR_ENOTIMPL; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING starting"); + if ((status = hc_get_backend("HCCPING", &backend, hc, ctx, baton->ptemp)) != OK) { + return backend_cleanup("HCCPING", backend, ctx->s, status); + } + if ((status = ap_proxy_connect_backend("HCCPING", backend, hc, ctx->s)) != OK) { + return backend_cleanup("HCCPING", backend, ctx->s, status); + } + r = create_request_rec(ptemp, ctx->s, baton->balancer, "CPING"); + if ((status = ap_proxy_connection_create_ex("HCCPING", backend, r)) != OK) { + return backend_cleanup("HCCPING", backend, ctx->s, status); + } + set_request_connection(r, backend->connection); + + timeout = apr_time_from_sec(10); /* 10 seconds */ + status = ajp_handle_cping_cpong(backend->sock, r, timeout); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING done %d", status); + return backend_cleanup("HCCPING", backend, ctx->s, status); +} + static apr_status_t hc_check_tcp(baton_t *baton) { int status; @@ -848,6 +883,9 @@ static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b) if (hc->s->method == TCP) { rv = hc_check_tcp(baton); } + else if (hc->s->method == CPING) { + rv = hc_check_cping(baton); + } else { rv = hc_check_http(baton); } @@ -1075,6 +1113,18 @@ static int hc_post_config(apr_pool_t *p, apr_pool_t *plog, "watchdog callback registered (%s for %s)", HCHECK_WATHCHDOG_NAME, s->server_hostname); s = s->next; } + + ajp_handle_cping_cpong = APR_RETRIEVE_OPTIONAL_FN(ajp_handle_cping_cpong); + if (ajp_handle_cping_cpong) { + proxy_hcmethods_t *method = proxy_hcmethods; + for (; method->name; method++) { + if (method->method == CPING) { + method->implemented = 1; + break; + } + } + } + return OK; }