Module: monitoring-plugins
    Branch: master
    Commit: db2983da7e8175ca3928998d4547acdf75d55dc0
    Author: Lorenz Kästle <[email protected]>
 Committer: GitHub <[email protected]>
      Date: Fri Nov 28 12:21:08 2025 +0100
       URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=db2983da

Fix/check curl sticky redir (#2188)

* check_curl: avoid freeing memory when we don't know where it came from

* check_curl: when using -f sticky conserve IPv6 addresses properly

When running the check on an ipv6 address with a sticky onredirect
policy like in this example:

  check_curl -6 -H example.com -I ::1 -f sticky

It results in a getaddrinfo error:

  HTTP CRITICAL - Unable to lookup IP address for '[::1]': getaddrinfo returned 
-3 - Temporary failure in name resolution

This happens because in check_http() if the content of server_addr is an
ipv6 address enclosing brackets are added and on redirection a
subsequent call to check_http() will pass this now bracketed value to
getaddrinfo resulting in the error.

To work around this, strip the brackets from the address prior to the
lookup_host() call.

* add Michael Jeanson to thanks

---

 THANKS.in                                 |  1 +
 plugins/check_curl.c                      | 10 +++-------
 plugins/check_curl.d/check_curl_helpers.c | 14 +++++++++++++-
 plugins/check_curl.d/check_curl_helpers.h |  4 ++++
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/THANKS.in b/THANKS.in
index 66397ad1..5dbb1b39 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -426,3 +426,4 @@ Eunice Remoquillo
 Louis Sautier
 Sven Hartge
 Alvar Penning
+Michael Jeanson
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index ba856a11..e3e514ff 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -68,10 +68,6 @@ const char *email = "[email protected]";
 
 #include <netdb.h>
 
-enum {
-       MAX_IPV4_HOSTLENGTH = 255,
-};
-
 enum {
        REGS = 2,
 };
@@ -789,21 +785,21 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, 
const check_curl_config
        /* set new values for redirected request */
 
        if (!(config.followsticky & STICKY_HOST)) {
-               free(working_state.server_address);
+               // free(working_state.server_address);
                working_state.server_address = strndup(new_host, 
MAX_IPV4_HOSTLENGTH);
        }
        if (!(config.followsticky & STICKY_PORT)) {
                working_state.serverPort = (unsigned short)new_port;
        }
 
-       free(working_state.host_name);
+       // free(working_state.host_name);
        working_state.host_name = strndup(new_host, MAX_IPV4_HOSTLENGTH);
 
        /* reset virtual port */
        working_state.virtualPort = working_state.serverPort;
 
        free(new_host);
-       free(working_state.server_url);
+       // free(working_state.server_url);
        working_state.server_url = new_url;
 
        uriFreeUriMembersA(&uri);
diff --git a/plugins/check_curl.d/check_curl_helpers.c 
b/plugins/check_curl.d/check_curl_helpers.c
index d49d8f07..e4e7bef6 100644
--- a/plugins/check_curl.d/check_curl_helpers.c
+++ b/plugins/check_curl.d/check_curl_helpers.c
@@ -128,8 +128,20 @@ check_curl_configure_curl(const 
check_curl_static_curl_config config,
        char dnscache[DEFAULT_BUFFER_SIZE];
        char addrstr[DEFAULT_BUFFER_SIZE / 2];
        if (working_state.use_ssl && working_state.host_name != NULL) {
+               char *tmp_mod_address;
+
+               /* lookup_host() requires an IPv6 address without the brackets. 
*/
+               if ((strnlen(working_state.server_address, MAX_IPV4_HOSTLENGTH) 
> 2) &&
+                       (working_state.server_address[0] == '[')) {
+                       // Duplicate and strip the leading '['
+                       tmp_mod_address =
+                               strndup(working_state.server_address + 1, 
strlen(working_state.server_address) - 2);
+               } else {
+                       tmp_mod_address = working_state.server_address;
+               }
+
                int res;
-               if ((res = lookup_host(working_state.server_address, addrstr, 
DEFAULT_BUFFER_SIZE / 2,
+               if ((res = lookup_host(tmp_mod_address, addrstr, 
DEFAULT_BUFFER_SIZE / 2,
                                                           config.sin_family)) 
!= 0) {
                        die(STATE_CRITICAL,
                                _("Unable to lookup IP address for '%s': 
getaddrinfo returned %d - %s"),
diff --git a/plugins/check_curl.d/check_curl_helpers.h 
b/plugins/check_curl.d/check_curl_helpers.h
index 87e45a9d..e7b80f7e 100644
--- a/plugins/check_curl.d/check_curl_helpers.h
+++ b/plugins/check_curl.d/check_curl_helpers.h
@@ -7,6 +7,10 @@
 #      include <openssl/opensslv.h>
 #endif
 
+enum {
+       MAX_IPV4_HOSTLENGTH = 255,
+};
+
 /* for buffers for header and body */
 typedef struct {
        size_t buflen;

Reply via email to