diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_ntp.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c index 2954aa88..86709a1f 100644 --- a/plugins/check_ntp.c +++ b/plugins/check_ntp.c | |||
| @@ -295,6 +295,82 @@ double offset_request(const char *host){ | |||
| 295 | return avg_offset; | 295 | return avg_offset; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | |||
| 299 | /* this should behave more like ntpdate, but needs optomisations... */ | ||
| 300 | double offset_request_ntpdate(const char *host){ | ||
| 301 | int i=0, j=0, ga_result=0, num_hosts=0, *socklist=NULL; | ||
| 302 | ntp_message req; | ||
| 303 | double offset=0., avg_offset=0.; | ||
| 304 | struct timeval recv_time; | ||
| 305 | struct addrinfo *ai=NULL, *ai_tmp=NULL, hints; | ||
| 306 | |||
| 307 | /* setup hints to only return results from getaddrinfo that we'd like */ | ||
| 308 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
| 309 | hints.ai_family = address_family; | ||
| 310 | hints.ai_protocol = IPPROTO_UDP; | ||
| 311 | hints.ai_socktype = SOCK_DGRAM; | ||
| 312 | |||
| 313 | /* XXX better error handling here... */ | ||
| 314 | ga_result = getaddrinfo(host, "123", &hints, &ai); | ||
| 315 | if(ga_result!=0){ | ||
| 316 | fprintf(stderr, "error getting address for %s: %s\n", | ||
| 317 | host, gai_strerror(ga_result)); | ||
| 318 | return -1.0; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* count te number of returned hosts, and allocate an array of sockets */ | ||
| 322 | ai_tmp=ai; | ||
| 323 | while(ai_tmp){ | ||
| 324 | ai_tmp = ai_tmp->ai_next; | ||
| 325 | num_hosts++; | ||
| 326 | } | ||
| 327 | socklist=(int*)malloc(sizeof(int)*num_hosts); | ||
| 328 | if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); | ||
| 329 | |||
| 330 | /* setup each socket for writing */ | ||
| 331 | ai_tmp=ai; | ||
| 332 | for(i=0;ai_tmp;i++){ | ||
| 333 | socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | ||
| 334 | if(socklist[i] == -1) { | ||
| 335 | perror(NULL); | ||
| 336 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 337 | } | ||
| 338 | if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){ | ||
| 339 | die(STATE_UNKNOWN, "can't create socket connection"); | ||
| 340 | } | ||
| 341 | ai_tmp = ai_tmp->ai_next; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* now do AVG_NUM checks to each host. this needs to be optimized | ||
| 345 | * two ways: | ||
| 346 | * - use some parellization w/poll for much faster results. currently | ||
| 347 | * we do send/recv, send/recv, etc, whereas we could use poll(), to | ||
| 348 | * determine when to read and just do a bunch of writing when we | ||
| 349 | * have free time. | ||
| 350 | * - behave like ntpdate and only take the 5 best responses. | ||
| 351 | */ | ||
| 352 | for(i=0; i<AVG_NUM; i++){ | ||
| 353 | if(verbose) printf("offset calculation run %d/%d\n", i+1, AVG_NUM); | ||
| 354 | for(j=0; j<num_hosts; j++){ | ||
| 355 | if(verbose) printf("peer %d: ", j); | ||
| 356 | setup_request(&req); | ||
| 357 | write(socklist[j], &req, sizeof(ntp_message)); | ||
| 358 | read(socklist[j], &req, sizeof(ntp_message)); | ||
| 359 | gettimeofday(&recv_time, NULL); | ||
| 360 | offset=calc_offset(&req, &recv_time); | ||
| 361 | if(verbose) printf("offset: %g\n", offset); | ||
| 362 | avg_offset+=offset; | ||
| 363 | } | ||
| 364 | avg_offset/=num_hosts; | ||
| 365 | } | ||
| 366 | avg_offset/=AVG_NUM; | ||
| 367 | if(verbose) printf("overall average offset: %g\n", avg_offset); | ||
| 368 | |||
| 369 | for(j=0; j<num_hosts; j++){ close(socklist[j]); } | ||
| 370 | freeaddrinfo(ai); | ||
| 371 | return avg_offset; | ||
| 372 | } | ||
| 373 | |||
| 298 | void | 374 | void |
| 299 | setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ | 375 | setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ |
| 300 | memset(p, 0, sizeof(ntp_control_message)); | 376 | memset(p, 0, sizeof(ntp_control_message)); |
