summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_ntp.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c
index 2954aa8..86709a1 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... */
300double 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
298void 374void
299setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ 375setup_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));