diff options
author | Andreas Baumann <202930+andreasbaumann@users.noreply.github.com> | 2023-03-08 15:36:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-08 15:36:49 (GMT) |
commit | 4e7f81fddb9d76491ad3443569d1ecbd844d38f6 (patch) | |
tree | fe341fa478450a1d16170ead116e57ddff475832 | |
parent | 03f86b5d0809967855fbaafb4d600dc5b82081fa (diff) | |
parent | fc927e98db73850e760f490117ed36f2de20270c (diff) | |
download | monitoring-plugins-4e7f81fddb9d76491ad3443569d1ecbd844d38f6.tar.gz |
Merge pull request #1846 from bazzisoft/curlfix1845-v2
check_curl.c: Include all IPs from getaddrinfo() in curl DNS cache
-rw-r--r-- | plugins/check_curl.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index e1bc98d..cc17ef5 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -384,9 +384,12 @@ int | |||
384 | lookup_host (const char *host, char *buf, size_t buflen) | 384 | lookup_host (const char *host, char *buf, size_t buflen) |
385 | { | 385 | { |
386 | struct addrinfo hints, *res, *result; | 386 | struct addrinfo hints, *res, *result; |
387 | char addrstr[100]; | ||
388 | size_t addrstr_len; | ||
387 | int errcode; | 389 | int errcode; |
388 | void *ptr; | 390 | void *ptr; |
389 | int s; | 391 | int s; |
392 | size_t buflen_remaining = buflen - 1; | ||
390 | 393 | ||
391 | memset (&hints, 0, sizeof (hints)); | 394 | memset (&hints, 0, sizeof (hints)); |
392 | hints.ai_family = address_family; | 395 | hints.ai_family = address_family; |
@@ -396,33 +399,40 @@ lookup_host (const char *host, char *buf, size_t buflen) | |||
396 | errcode = getaddrinfo (host, NULL, &hints, &result); | 399 | errcode = getaddrinfo (host, NULL, &hints, &result); |
397 | if (errcode != 0) | 400 | if (errcode != 0) |
398 | return errcode; | 401 | return errcode; |
399 | 402 | ||
403 | strcpy(buf, ""); | ||
400 | res = result; | 404 | res = result; |
401 | 405 | ||
402 | while (res) { | 406 | while (res) { |
403 | inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); | ||
404 | switch (res->ai_family) { | 407 | switch (res->ai_family) { |
405 | case AF_INET: | 408 | case AF_INET: |
406 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; | 409 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; |
407 | break; | 410 | break; |
408 | case AF_INET6: | 411 | case AF_INET6: |
409 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; | 412 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; |
410 | break; | 413 | break; |
411 | } | 414 | } |
412 | 415 | ||
413 | inet_ntop (res->ai_family, ptr, buf, buflen); | 416 | inet_ntop (res->ai_family, ptr, addrstr, 100); |
414 | if (verbose >= 1) | 417 | if (verbose >= 1) { |
415 | printf ("* getaddrinfo IPv%d address: %s\n", | 418 | printf ("* getaddrinfo IPv%d address: %s\n", |
416 | res->ai_family == PF_INET6 ? 6 : 4, buf); | 419 | res->ai_family == PF_INET6 ? 6 : 4, addrstr); |
420 | } | ||
417 | 421 | ||
418 | if (s = socket (res->ai_family, res->ai_socktype, res->ai_protocol) == -1) | 422 | // Append all IPs to buf as a comma-separated string |
419 | continue; | 423 | addrstr_len = strlen(addrstr); |
420 | if (bind (s, res->ai_addr, res->ai_addrlen == 0) ) | 424 | if (buflen_remaining > addrstr_len + 1) { |
421 | break; | 425 | if (buf[0] != '\0') { |
426 | strncat(buf, ",", buflen_remaining); | ||
427 | buflen_remaining -= 1; | ||
428 | } | ||
429 | strncat(buf, addrstr, buflen_remaining); | ||
430 | buflen_remaining -= addrstr_len; | ||
431 | } | ||
422 | 432 | ||
423 | res = res->ai_next; | 433 | res = res->ai_next; |
424 | } | 434 | } |
425 | 435 | ||
426 | freeaddrinfo(result); | 436 | freeaddrinfo(result); |
427 | 437 | ||
428 | return 0; | 438 | return 0; |
@@ -453,7 +463,7 @@ check_http (void) | |||
453 | int i; | 463 | int i; |
454 | char *force_host_header = NULL; | 464 | char *force_host_header = NULL; |
455 | struct curl_slist *host = NULL; | 465 | struct curl_slist *host = NULL; |
456 | char addrstr[100]; | 466 | char addrstr[DEFAULT_BUFFER_SIZE/2]; |
457 | char dnscache[DEFAULT_BUFFER_SIZE]; | 467 | char dnscache[DEFAULT_BUFFER_SIZE]; |
458 | 468 | ||
459 | /* initialize curl */ | 469 | /* initialize curl */ |
@@ -505,7 +515,7 @@ check_http (void) | |||
505 | 515 | ||
506 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy | 516 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy |
507 | if(use_ssl && host_name != NULL) { | 517 | if(use_ssl && host_name != NULL) { |
508 | if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { | 518 | if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) { |
509 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), | 519 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), |
510 | server_address, res, gai_strerror (res)); | 520 | server_address, res, gai_strerror (res)); |
511 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 521 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
@@ -800,6 +810,9 @@ check_http (void) | |||
800 | /* free header and server IP resolve lists, we don't need it anymore */ | 810 | /* free header and server IP resolve lists, we don't need it anymore */ |
801 | curl_slist_free_all (header_list); header_list = NULL; | 811 | curl_slist_free_all (header_list); header_list = NULL; |
802 | curl_slist_free_all (server_ips); server_ips = NULL; | 812 | curl_slist_free_all (server_ips); server_ips = NULL; |
813 | if (host) { | ||
814 | curl_slist_free_all (host); host = NULL; | ||
815 | } | ||
803 | 816 | ||
804 | /* Curl errors, result in critical Nagios state */ | 817 | /* Curl errors, result in critical Nagios state */ |
805 | if (res != CURLE_OK) { | 818 | if (res != CURLE_OK) { |