diff options
| -rw-r--r-- | plugins/check_ntp_peer.c | 2 | ||||
| -rw-r--r-- | plugins/check_ntp_time.c | 81 | ||||
| -rw-r--r-- | plugins/t/check_ntp.t | 2 |
3 files changed, 61 insertions, 24 deletions
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index f7cad630..26f74286 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c | |||
| @@ -625,7 +625,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { | |||
| 625 | mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range); | 625 | mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range); |
| 626 | } break; | 626 | } break; |
| 627 | case 'H': | 627 | case 'H': |
| 628 | if (!is_host(optarg)) { | 628 | if (!is_host(optarg) && (optarg[0] != '/')) { |
| 629 | usage2(_("Invalid hostname/address"), optarg); | 629 | usage2(_("Invalid hostname/address"), optarg); |
| 630 | } | 630 | } |
| 631 | result.config.server_address = strdup(optarg); | 631 | result.config.server_address = strdup(optarg); |
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index 602b6010..1300faea 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | #include "states.h" | 42 | #include "states.h" |
| 43 | #include "thresholds.h" | 43 | #include "thresholds.h" |
| 44 | #include "check_ntp_time.d/config.h" | 44 | #include "check_ntp_time.d/config.h" |
| 45 | #include <netinet/in.h> | ||
| 46 | #include <sys/socket.h> | ||
| 45 | 47 | ||
| 46 | static int verbose = 0; | 48 | static int verbose = 0; |
| 47 | 49 | ||
| @@ -336,17 +338,26 @@ static offset_request_wrapper offset_request(const char *host, const char *port, | |||
| 336 | hints.ai_protocol = IPPROTO_UDP; | 338 | hints.ai_protocol = IPPROTO_UDP; |
| 337 | hints.ai_socktype = SOCK_DGRAM; | 339 | hints.ai_socktype = SOCK_DGRAM; |
| 338 | 340 | ||
| 339 | /* fill in ai with the list of hosts resolved by the host name */ | 341 | bool is_socket; |
| 340 | struct addrinfo *addresses = NULL; | 342 | struct addrinfo *addresses = NULL; |
| 341 | int ga_result = getaddrinfo(host, port, &hints, &addresses); | ||
| 342 | if (ga_result != 0) { | ||
| 343 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* count the number of returned hosts, and allocate stuff accordingly */ | ||
| 347 | size_t num_hosts = 0; | 343 | size_t num_hosts = 0; |
| 348 | for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { | 344 | if (host[0] == '/') { |
| 349 | num_hosts++; | 345 | num_hosts = 1; |
| 346 | is_socket = true; | ||
| 347 | } else { | ||
| 348 | is_socket = false; | ||
| 349 | |||
| 350 | /* fill in ai with the list of hosts resolved by the host name */ | ||
| 351 | struct addrinfo *addresses = NULL; | ||
| 352 | int ga_result = getaddrinfo(host, port, &hints, &addresses); | ||
| 353 | if (ga_result != 0) { | ||
| 354 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); | ||
| 355 | } | ||
| 356 | |||
| 357 | /* count the number of returned hosts, and allocate stuff accordingly */ | ||
| 358 | for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { | ||
| 359 | num_hosts++; | ||
| 360 | } | ||
| 350 | } | 361 | } |
| 351 | 362 | ||
| 352 | ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); | 363 | ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); |
| @@ -374,25 +385,51 @@ static offset_request_wrapper offset_request(const char *host, const char *port, | |||
| 374 | DBG(printf("Found %zu peers to check\n", num_hosts)); | 385 | DBG(printf("Found %zu peers to check\n", num_hosts)); |
| 375 | 386 | ||
| 376 | /* setup each socket for writing, and the corresponding struct pollfd */ | 387 | /* setup each socket for writing, and the corresponding struct pollfd */ |
| 377 | struct addrinfo *ai_tmp = addresses; | 388 | if (is_socket) { |
| 378 | for (int i = 0; ai_tmp; i++) { | 389 | socklist[0] = socket(AF_UNIX, SOCK_STREAM, 0); |
| 379 | socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | 390 | if (socklist[0] == -1) { |
| 380 | if (socklist[i] == -1) { | 391 | DBG(printf("can't create socket: %s\n", strerror(errno))); |
| 381 | perror(NULL); | 392 | die(STATE_UNKNOWN, "can not create new socket\n"); |
| 382 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 383 | } | 393 | } |
| 384 | if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { | 394 | |
| 395 | struct sockaddr_un unix_socket = { | ||
| 396 | .sun_family = AF_UNIX, | ||
| 397 | }; | ||
| 398 | |||
| 399 | strncpy(unix_socket.sun_path, host, strlen(host)); | ||
| 400 | |||
| 401 | if (connect(socklist[0], &unix_socket, sizeof(unix_socket))) { | ||
| 385 | /* don't die here, because it is enough if there is one server | 402 | /* don't die here, because it is enough if there is one server |
| 386 | answering in time. This also would break for dual ipv4/6 stacked | 403 | answering in time. This also would break for dual ipv4/6 stacked |
| 387 | ntp servers when the client only supports on of them. | 404 | ntp servers when the client only supports on of them. |
| 388 | */ | 405 | */ |
| 389 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | 406 | DBG(printf("can't create socket connection on peer %i: %s\n", 0, strerror(errno))); |
| 390 | } else { | 407 | } else { |
| 391 | ufds[i].fd = socklist[i]; | 408 | ufds[0].fd = socklist[0]; |
| 392 | ufds[i].events = POLLIN; | 409 | ufds[0].events = POLLIN; |
| 393 | ufds[i].revents = 0; | 410 | ufds[0].revents = 0; |
| 411 | } | ||
| 412 | } else { | ||
| 413 | struct addrinfo *ai_tmp = addresses; | ||
| 414 | for (int i = 0; ai_tmp; i++) { | ||
| 415 | socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | ||
| 416 | if (socklist[i] == -1) { | ||
| 417 | perror(NULL); | ||
| 418 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 419 | } | ||
| 420 | if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { | ||
| 421 | /* don't die here, because it is enough if there is one server | ||
| 422 | answering in time. This also would break for dual ipv4/6 stacked | ||
| 423 | ntp servers when the client only supports on of them. | ||
| 424 | */ | ||
| 425 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | ||
| 426 | } else { | ||
| 427 | ufds[i].fd = socklist[i]; | ||
| 428 | ufds[i].events = POLLIN; | ||
| 429 | ufds[i].revents = 0; | ||
| 430 | } | ||
| 431 | ai_tmp = ai_tmp->ai_next; | ||
| 394 | } | 432 | } |
| 395 | ai_tmp = ai_tmp->ai_next; | ||
| 396 | } | 433 | } |
| 397 | 434 | ||
| 398 | /* now do AVG_NUM checks to each host. We stop before timeout/2 seconds | 435 | /* now do AVG_NUM checks to each host. We stop before timeout/2 seconds |
| @@ -586,7 +623,7 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | |||
| 586 | mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range); | 623 | mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range); |
| 587 | } break; | 624 | } break; |
| 588 | case 'H': | 625 | case 'H': |
| 589 | if (!is_host(optarg)) { | 626 | if (!is_host(optarg) && (optarg[0] != '/')) { |
| 590 | usage2(_("Invalid hostname/address"), optarg); | 627 | usage2(_("Invalid hostname/address"), optarg); |
| 591 | } | 628 | } |
| 592 | result.config.server_address = strdup(optarg); | 629 | result.config.server_address = strdup(optarg); |
diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index a8ac7bb8..7703bc3b 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t | |||
| @@ -8,7 +8,7 @@ use strict; | |||
| 8 | use Test::More; | 8 | use Test::More; |
| 9 | use NPTest; | 9 | use NPTest; |
| 10 | 10 | ||
| 11 | my @PLUGINS1 = ('check_ntp', 'check_ntp_peer', 'check_ntp_time'); | 11 | my @PLUGINS1 = ('check_ntp_peer', 'check_ntp_time'); |
| 12 | my @PLUGINS2 = ('check_ntp_peer'); | 12 | my @PLUGINS2 = ('check_ntp_peer'); |
| 13 | 13 | ||
| 14 | plan tests => (12 * scalar(@PLUGINS1)) + (6 * scalar(@PLUGINS2)); | 14 | plan tests => (12 * scalar(@PLUGINS1)) + (6 * scalar(@PLUGINS2)); |
