1 /* $OpenBSD: ntp.c,v 1.110 2009/01/26 11:51:50 henning Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/param.h> 21 #include <sys/time.h> 22 #include <sys/stat.h> 23 #include <errno.h> 24 #include <fcntl.h> 25 #include <paths.h> 26 #include <poll.h> 27 #include <pwd.h> 28 #include <signal.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <time.h> 32 #include <unistd.h> 33 34 #include "ntpd.h" 35 36 #define PFD_PIPE_MAIN 0 37 #define PFD_HOTPLUG 1 38 #define PFD_PIPE_DNS 2 39 #define PFD_MAX 3 40 41 volatile sig_atomic_t ntp_quit = 0; 42 volatile sig_atomic_t ntp_report = 0; 43 struct imsgbuf *ibuf_main; 44 struct imsgbuf *ibuf_dns; 45 struct ntpd_conf *conf; 46 u_int peer_cnt; 47 u_int sensors_cnt; 48 time_t lastreport; 49 50 void ntp_sighdlr(int); 51 int ntp_dispatch_imsg(void); 52 int ntp_dispatch_imsg_dns(void); 53 void peer_add(struct ntp_peer *); 54 void peer_remove(struct ntp_peer *); 55 void report_peers(int); 56 57 void 58 ntp_sighdlr(int sig) 59 { 60 switch (sig) { 61 case SIGINT: 62 case SIGTERM: 63 ntp_quit = 1; 64 break; 65 case SIGINFO: 66 ntp_report = 1; 67 break; 68 } 69 } 70 71 pid_t 72 ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf, struct passwd *pw) 73 { 74 int a, b, nfds, i, j, idx_peers, timeout; 75 int hotplugfd, nullfd, pipe_dns[2]; 76 u_int pfd_elms = 0, idx2peer_elms = 0; 77 u_int listener_cnt, new_cnt, sent_cnt, trial_cnt; 78 pid_t pid, dns_pid; 79 struct pollfd *pfd = NULL; 80 struct servent *se; 81 struct listen_addr *la; 82 struct ntp_peer *p; 83 struct ntp_peer **idx2peer = NULL; 84 struct ntp_sensor *s, *next_s; 85 struct timespec tp; 86 struct stat stb; 87 time_t nextaction, last_sensor_scan = 0; 88 void *newp; 89 90 switch (pid = fork()) { 91 case -1: 92 fatal("cannot fork"); 93 break; 94 case 0: 95 break; 96 default: 97 return (pid); 98 } 99 100 /* in this case the parent didn't init logging and didn't daemonize */ 101 if (nconf->settime && !nconf->debug) { 102 log_init(nconf->debug); 103 if (setsid() == -1) 104 fatal("setsid"); 105 } 106 if ((se = getservbyname("ntp", "udp")) == NULL) 107 fatal("getservbyname"); 108 109 if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1) 110 fatal(NULL); 111 hotplugfd = sensor_hotplugfd(); 112 113 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_dns) == -1) 114 fatal("socketpair"); 115 dns_pid = ntp_dns(pipe_dns, nconf, pw); 116 close(pipe_dns[1]); 117 118 if (stat(pw->pw_dir, &stb) == -1) 119 fatal("stat"); 120 if (stb.st_uid != 0 || (stb.st_mode & (S_IWGRP|S_IWOTH)) != 0) 121 fatalx("bad privsep dir permissions"); 122 if (chroot(pw->pw_dir) == -1) 123 fatal("chroot"); 124 if (chdir("/") == -1) 125 fatal("chdir(\"/\")"); 126 127 if (!nconf->debug) { 128 dup2(nullfd, STDIN_FILENO); 129 dup2(nullfd, STDOUT_FILENO); 130 dup2(nullfd, STDERR_FILENO); 131 } 132 close(nullfd); 133 134 setproctitle("ntp engine"); 135 136 conf = nconf; 137 setup_listeners(se, conf, &listener_cnt); 138 139 if (setgroups(1, &pw->pw_gid) || 140 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 141 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 142 fatal("can't drop privileges"); 143 144 endservent(); 145 146 signal(SIGTERM, ntp_sighdlr); 147 signal(SIGINT, ntp_sighdlr); 148 signal(SIGINFO, ntp_sighdlr); 149 signal(SIGPIPE, SIG_IGN); 150 signal(SIGHUP, SIG_IGN); 151 signal(SIGCHLD, SIG_DFL); 152 153 close(pipe_prnt[0]); 154 if ((ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL) 155 fatal(NULL); 156 imsg_init(ibuf_main, pipe_prnt[1]); 157 if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL) 158 fatal(NULL); 159 imsg_init(ibuf_dns, pipe_dns[0]); 160 161 TAILQ_FOREACH(p, &conf->ntp_peers, entry) 162 client_peer_init(p); 163 164 bzero(&conf->status, sizeof(conf->status)); 165 166 conf->freq.num = 0; 167 conf->freq.samples = 0; 168 conf->freq.x = 0.0; 169 conf->freq.xx = 0.0; 170 conf->freq.xy = 0.0; 171 conf->freq.y = 0.0; 172 conf->freq.overall_offset = 0.0; 173 174 conf->status.synced = 0; 175 clock_getres(CLOCK_REALTIME, &tp); 176 b = 1000000000 / tp.tv_nsec; /* convert to Hz */ 177 for (a = 0; b > 1; a--, b >>= 1) 178 ; 179 conf->status.precision = a; 180 conf->scale = 1; 181 182 sensor_init(); 183 184 log_info("ntp engine ready"); 185 186 peer_cnt = 0; 187 TAILQ_FOREACH(p, &conf->ntp_peers, entry) 188 peer_cnt++; 189 190 /* wait 5 min before reporting first status to let things settle down */ 191 lastreport = getmonotime() + (5 * 60) - REPORT_INTERVAL; 192 193 while (ntp_quit == 0) { 194 if (peer_cnt > idx2peer_elms) { 195 if ((newp = realloc(idx2peer, sizeof(void *) * 196 peer_cnt)) == NULL) { 197 /* panic for now */ 198 log_warn("could not resize idx2peer from %u -> " 199 "%u entries", idx2peer_elms, peer_cnt); 200 fatalx("exiting"); 201 } 202 idx2peer = newp; 203 idx2peer_elms = peer_cnt; 204 } 205 206 new_cnt = PFD_MAX + peer_cnt + listener_cnt; 207 if (new_cnt > pfd_elms) { 208 if ((newp = realloc(pfd, sizeof(struct pollfd) * 209 new_cnt)) == NULL) { 210 /* panic for now */ 211 log_warn("could not resize pfd from %u -> " 212 "%u entries", pfd_elms, new_cnt); 213 fatalx("exiting"); 214 } 215 pfd = newp; 216 pfd_elms = new_cnt; 217 } 218 219 bzero(pfd, sizeof(struct pollfd) * pfd_elms); 220 bzero(idx2peer, sizeof(void *) * idx2peer_elms); 221 nextaction = getmonotime() + 3600; 222 pfd[PFD_PIPE_MAIN].fd = ibuf_main->fd; 223 pfd[PFD_PIPE_MAIN].events = POLLIN; 224 pfd[PFD_HOTPLUG].fd = hotplugfd; 225 pfd[PFD_HOTPLUG].events = POLLIN; 226 pfd[PFD_PIPE_DNS].fd = ibuf_dns->fd; 227 pfd[PFD_PIPE_DNS].events = POLLIN; 228 229 i = PFD_MAX; 230 TAILQ_FOREACH(la, &conf->listen_addrs, entry) { 231 pfd[i].fd = la->fd; 232 pfd[i].events = POLLIN; 233 i++; 234 } 235 236 idx_peers = i; 237 sent_cnt = trial_cnt = 0; 238 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 239 if (p->next > 0 && p->next <= getmonotime()) { 240 if (p->state > STATE_DNS_INPROGRESS) 241 trial_cnt++; 242 if (client_query(p) == 0) 243 sent_cnt++; 244 } 245 if (p->deadline > 0 && p->deadline <= getmonotime()) { 246 timeout = 300; 247 log_debug("no reply from %s received in time, " 248 "next query %ds", log_sockaddr( 249 (struct sockaddr *)&p->addr->ss), timeout); 250 if (p->trustlevel >= TRUSTLEVEL_BADPEER && 251 (p->trustlevel /= 2) < TRUSTLEVEL_BADPEER) 252 log_info("peer %s now invalid", 253 log_sockaddr( 254 (struct sockaddr *)&p->addr->ss)); 255 client_nextaddr(p); 256 set_next(p, timeout); 257 } 258 if (p->senderrors > MAX_SEND_ERRORS) { 259 log_debug("failed to send query to %s, " 260 "next query %ds", log_sockaddr( 261 (struct sockaddr *)&p->addr->ss), 262 INTERVAL_QUERY_PATHETIC); 263 p->senderrors = 0; 264 client_nextaddr(p); 265 set_next(p, INTERVAL_QUERY_PATHETIC); 266 } 267 if (p->next > 0 && p->next < nextaction) 268 nextaction = p->next; 269 if (p->deadline > 0 && p->deadline < nextaction) 270 nextaction = p->deadline; 271 272 if (p->state == STATE_QUERY_SENT && 273 p->query->fd != -1) { 274 pfd[i].fd = p->query->fd; 275 pfd[i].events = POLLIN; 276 idx2peer[i - idx_peers] = p; 277 i++; 278 } 279 } 280 281 if (last_sensor_scan == 0 || 282 last_sensor_scan + SENSOR_SCAN_INTERVAL < getmonotime()) { 283 sensors_cnt = sensor_scan(); 284 last_sensor_scan = getmonotime(); 285 } 286 if (!TAILQ_EMPTY(&conf->ntp_conf_sensors) && sensors_cnt == 0 && 287 nextaction > last_sensor_scan + SENSOR_SCAN_INTERVAL) 288 nextaction = last_sensor_scan + SENSOR_SCAN_INTERVAL; 289 sensors_cnt = 0; 290 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 291 if (conf->settime && s->offsets[0].offset) 292 priv_settime(s->offsets[0].offset); 293 sensors_cnt++; 294 if (s->next > 0 && s->next < nextaction) 295 nextaction = s->next; 296 } 297 298 if (conf->settime && 299 ((trial_cnt > 0 && sent_cnt == 0) || 300 (peer_cnt == 0 && sensors_cnt == 0))) 301 priv_settime(0); /* no good peers, don't wait */ 302 303 if (ibuf_main->w.queued > 0) 304 pfd[PFD_PIPE_MAIN].events |= POLLOUT; 305 if (ibuf_dns->w.queued > 0) 306 pfd[PFD_PIPE_DNS].events |= POLLOUT; 307 308 timeout = nextaction - getmonotime(); 309 if (timeout < 0) 310 timeout = 0; 311 312 if ((nfds = poll(pfd, i, timeout * 1000)) == -1) 313 if (errno != EINTR) { 314 log_warn("poll error"); 315 ntp_quit = 1; 316 } 317 318 if (nfds > 0 && (pfd[PFD_PIPE_MAIN].revents & POLLOUT)) 319 if (msgbuf_write(&ibuf_main->w) < 0) { 320 log_warn("pipe write error (to parent)"); 321 ntp_quit = 1; 322 } 323 324 if (nfds > 0 && pfd[PFD_PIPE_MAIN].revents & (POLLIN|POLLERR)) { 325 nfds--; 326 if (ntp_dispatch_imsg() == -1) 327 ntp_quit = 1; 328 } 329 330 if (nfds > 0 && (pfd[PFD_PIPE_DNS].revents & POLLOUT)) 331 if (msgbuf_write(&ibuf_dns->w) < 0) { 332 log_warn("pipe write error (to dns engine)"); 333 ntp_quit = 1; 334 } 335 336 if (nfds > 0 && pfd[PFD_PIPE_DNS].revents & (POLLIN|POLLERR)) { 337 nfds--; 338 if (ntp_dispatch_imsg_dns() == -1) 339 ntp_quit = 1; 340 } 341 342 if (nfds > 0 && pfd[PFD_HOTPLUG].revents & (POLLIN|POLLERR)) { 343 nfds--; 344 sensor_hotplugevent(hotplugfd); 345 } 346 347 for (j = PFD_MAX; nfds > 0 && j < idx_peers; j++) 348 if (pfd[j].revents & (POLLIN|POLLERR)) { 349 nfds--; 350 if (server_dispatch(pfd[j].fd, conf) == -1) 351 ntp_quit = 1; 352 } 353 354 for (; nfds > 0 && j < i; j++) 355 if (pfd[j].revents & (POLLIN|POLLERR)) { 356 nfds--; 357 if (client_dispatch(idx2peer[j - idx_peers], 358 conf->settime) == -1) 359 ntp_quit = 1; 360 } 361 362 for (s = TAILQ_FIRST(&conf->ntp_sensors); s != NULL; 363 s = next_s) { 364 next_s = TAILQ_NEXT(s, entry); 365 if (s->next <= getmonotime()) 366 sensor_query(s); 367 } 368 report_peers(ntp_report); 369 ntp_report = 0; 370 } 371 372 msgbuf_write(&ibuf_main->w); 373 msgbuf_clear(&ibuf_main->w); 374 free(ibuf_main); 375 msgbuf_write(&ibuf_dns->w); 376 msgbuf_clear(&ibuf_dns->w); 377 free(ibuf_dns); 378 379 log_info("ntp engine exiting"); 380 _exit(0); 381 } 382 383 int 384 ntp_dispatch_imsg(void) 385 { 386 struct imsg imsg; 387 int n; 388 389 if ((n = imsg_read(ibuf_main)) == -1) 390 return (-1); 391 392 if (n == 0) { /* connection closed */ 393 log_warnx("ntp_dispatch_imsg in ntp engine: pipe closed"); 394 return (-1); 395 } 396 397 for (;;) { 398 if ((n = imsg_get(ibuf_main, &imsg)) == -1) 399 return (-1); 400 401 if (n == 0) 402 break; 403 404 switch (imsg.hdr.type) { 405 case IMSG_ADJTIME: 406 memcpy(&n, imsg.data, sizeof(n)); 407 if (n == 1 && !conf->status.synced) { 408 log_info("clock is now synced"); 409 conf->status.synced = 1; 410 } else if (n == 0 && conf->status.synced) { 411 log_info("clock is now unsynced"); 412 conf->status.synced = 0; 413 } 414 break; 415 default: 416 break; 417 } 418 imsg_free(&imsg); 419 } 420 return (0); 421 } 422 423 int 424 ntp_dispatch_imsg_dns(void) 425 { 426 struct imsg imsg; 427 struct ntp_peer *peer, *npeer; 428 u_int16_t dlen; 429 u_char *p; 430 struct ntp_addr *h; 431 int n; 432 433 if ((n = imsg_read(ibuf_dns)) == -1) 434 return (-1); 435 436 if (n == 0) { /* connection closed */ 437 log_warnx("ntp_dispatch_imsg_dns in ntp engine: pipe closed"); 438 return (-1); 439 } 440 441 for (;;) { 442 if ((n = imsg_get(ibuf_dns, &imsg)) == -1) 443 return (-1); 444 445 if (n == 0) 446 break; 447 448 switch (imsg.hdr.type) { 449 case IMSG_HOST_DNS: 450 TAILQ_FOREACH(peer, &conf->ntp_peers, entry) 451 if (peer->id == imsg.hdr.peerid) 452 break; 453 if (peer == NULL) { 454 log_warnx("IMSG_HOST_DNS with invalid peerID"); 455 break; 456 } 457 if (peer->addr != NULL) { 458 log_warnx("IMSG_HOST_DNS but addr != NULL!"); 459 break; 460 } 461 462 dlen = imsg.hdr.len - IMSG_HEADER_SIZE; 463 if (dlen == 0) { /* no data -> temp error */ 464 peer->state = STATE_DNS_TEMPFAIL; 465 break; 466 } 467 468 p = (u_char *)imsg.data; 469 while (dlen >= sizeof(struct sockaddr_storage)) { 470 if ((h = calloc(1, sizeof(struct ntp_addr))) == 471 NULL) 472 fatal(NULL); 473 memcpy(&h->ss, p, sizeof(h->ss)); 474 p += sizeof(h->ss); 475 dlen -= sizeof(h->ss); 476 if (peer->addr_head.pool) { 477 npeer = new_peer(); 478 npeer->weight = peer->weight; 479 h->next = NULL; 480 npeer->addr = h; 481 npeer->addr_head.a = h; 482 npeer->addr_head.name = 483 peer->addr_head.name; 484 npeer->addr_head.pool = 1; 485 client_peer_init(npeer); 486 npeer->state = STATE_DNS_DONE; 487 peer_add(npeer); 488 } else { 489 h->next = peer->addr; 490 peer->addr = h; 491 peer->addr_head.a = peer->addr; 492 peer->state = STATE_DNS_DONE; 493 } 494 } 495 if (dlen != 0) 496 fatalx("IMSG_HOST_DNS: dlen != 0"); 497 if (peer->addr_head.pool) 498 peer_remove(peer); 499 else 500 client_addr_init(peer); 501 break; 502 default: 503 break; 504 } 505 imsg_free(&imsg); 506 } 507 return (0); 508 } 509 510 void 511 peer_add(struct ntp_peer *p) 512 { 513 TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry); 514 peer_cnt++; 515 } 516 517 void 518 peer_remove(struct ntp_peer *p) 519 { 520 TAILQ_REMOVE(&conf->ntp_peers, p, entry); 521 free(p); 522 peer_cnt--; 523 } 524 525 static void 526 priv_adjfreq(double offset) 527 { 528 double curtime, freq; 529 530 if (!conf->status.synced) 531 return; 532 533 conf->freq.samples++; 534 535 if (conf->freq.samples <= 0) 536 return; 537 538 conf->freq.overall_offset += offset; 539 offset = conf->freq.overall_offset; 540 541 curtime = gettime_corrected(); 542 conf->freq.xy += offset * curtime; 543 conf->freq.x += curtime; 544 conf->freq.y += offset; 545 conf->freq.xx += curtime * curtime; 546 547 if (conf->freq.samples % FREQUENCY_SAMPLES != 0) 548 return; 549 550 freq = 551 (conf->freq.xy - conf->freq.x * conf->freq.y / conf->freq.samples) 552 / 553 (conf->freq.xx - conf->freq.x * conf->freq.x / conf->freq.samples); 554 555 if (freq > MAX_FREQUENCY_ADJUST) 556 freq = MAX_FREQUENCY_ADJUST; 557 else if (freq < -MAX_FREQUENCY_ADJUST) 558 freq = -MAX_FREQUENCY_ADJUST; 559 560 imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &freq, sizeof(freq)); 561 conf->freq.xy = 0.0; 562 conf->freq.x = 0.0; 563 conf->freq.y = 0.0; 564 conf->freq.xx = 0.0; 565 conf->freq.samples = 0; 566 conf->freq.overall_offset = 0.0; 567 conf->freq.num++; 568 } 569 570 int 571 priv_adjtime(void) 572 { 573 struct ntp_peer *p; 574 struct ntp_sensor *s; 575 int offset_cnt = 0, i = 0, j; 576 struct ntp_offset **offsets; 577 double offset_median; 578 579 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 580 if (p->trustlevel < TRUSTLEVEL_BADPEER) 581 continue; 582 if (!p->update.good) 583 return (1); 584 offset_cnt += p->weight; 585 } 586 587 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 588 if (!s->update.good) 589 continue; 590 offset_cnt += s->weight; 591 } 592 593 if (offset_cnt == 0) 594 return (1); 595 596 if ((offsets = calloc(offset_cnt, sizeof(struct ntp_offset *))) == NULL) 597 fatal("calloc priv_adjtime"); 598 599 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 600 if (p->trustlevel < TRUSTLEVEL_BADPEER) 601 continue; 602 for (j = 0; j < p->weight; j++) 603 offsets[i++] = &p->update; 604 } 605 606 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 607 if (!s->update.good) 608 continue; 609 for (j = 0; j < s->weight; j++) 610 offsets[i++] = &s->update; 611 } 612 613 qsort(offsets, offset_cnt, sizeof(struct ntp_offset *), offset_compare); 614 615 i = offset_cnt / 2; 616 if (offset_cnt % 2 == 0) { 617 offset_median = 618 (offsets[i - 1]->offset + offsets[i]->offset) / 2; 619 conf->status.rootdelay = 620 (offsets[i - 1]->delay + offsets[i]->delay) / 2; 621 conf->status.stratum = MAX( 622 offsets[i - 1]->status.stratum, offsets[i]->status.stratum); 623 } else { 624 offset_median = offsets[i]->offset; 625 conf->status.rootdelay = offsets[i]->delay; 626 conf->status.stratum = offsets[i]->status.stratum; 627 } 628 conf->status.leap = offsets[i]->status.leap; 629 630 imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, 631 &offset_median, sizeof(offset_median)); 632 633 priv_adjfreq(offset_median); 634 635 conf->status.reftime = gettime(); 636 conf->status.stratum++; /* one more than selected peer */ 637 update_scale(offset_median); 638 639 conf->status.refid = offsets[i]->status.send_refid; 640 641 free(offsets); 642 643 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 644 for (i = 0; i < OFFSET_ARRAY_SIZE; i++) 645 p->reply[i].offset -= offset_median; 646 p->update.good = 0; 647 } 648 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 649 for (i = 0; i < SENSOR_OFFSETS; i++) 650 s->offsets[i].offset -= offset_median; 651 s->update.offset -= offset_median; 652 } 653 654 return (0); 655 } 656 657 int 658 offset_compare(const void *aa, const void *bb) 659 { 660 const struct ntp_offset * const *a; 661 const struct ntp_offset * const *b; 662 663 a = aa; 664 b = bb; 665 666 if ((*a)->offset < (*b)->offset) 667 return (-1); 668 else if ((*a)->offset > (*b)->offset) 669 return (1); 670 else 671 return (0); 672 } 673 674 void 675 priv_settime(double offset) 676 { 677 imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &offset, sizeof(offset)); 678 conf->settime = 0; 679 } 680 681 void 682 priv_host_dns(char *name, u_int32_t peerid) 683 { 684 u_int16_t dlen; 685 686 dlen = strlen(name) + 1; 687 imsg_compose(ibuf_dns, IMSG_HOST_DNS, peerid, 0, name, dlen); 688 } 689 690 void 691 update_scale(double offset) 692 { 693 offset += getoffset(); 694 if (offset < 0) 695 offset = -offset; 696 697 if (offset > QSCALE_OFF_MAX || !conf->status.synced || 698 conf->freq.num < 3) 699 conf->scale = 1; 700 else if (offset < QSCALE_OFF_MIN) 701 conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN; 702 else 703 conf->scale = QSCALE_OFF_MAX / offset; 704 } 705 706 time_t 707 scale_interval(time_t requested) 708 { 709 time_t interval, r; 710 711 interval = requested * conf->scale; 712 r = arc4random_uniform(MAX(5, interval / 10)); 713 return (interval + r); 714 } 715 716 time_t 717 error_interval(void) 718 { 719 time_t interval, r; 720 721 interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN; 722 r = arc4random_uniform(interval / 10); 723 return (interval + r); 724 } 725 726 void 727 report_peers(int always) 728 { 729 time_t now; 730 u_int badpeers = 0; 731 u_int badsensors = 0; 732 struct ntp_peer *p; 733 struct ntp_sensor *s; 734 735 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 736 if (p->trustlevel < TRUSTLEVEL_BADPEER) 737 badpeers++; 738 } 739 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 740 if (!s->update.good) 741 badsensors++; 742 } 743 744 now = getmonotime(); 745 if (!always) { 746 if ((peer_cnt == 0 || badpeers == 0 || badpeers < peer_cnt / 2) 747 && (sensors_cnt == 0 || badsensors == 0 || 748 badsensors < sensors_cnt / 2)) 749 return; 750 751 if (lastreport + REPORT_INTERVAL > now) 752 return; 753 } 754 lastreport = now; 755 if (peer_cnt > 0) { 756 log_warnx("%u out of %u peers valid", peer_cnt - badpeers, 757 peer_cnt); 758 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 759 if (p->trustlevel < TRUSTLEVEL_BADPEER) { 760 const char *a = "not resolved"; 761 const char *pool = ""; 762 if (p->addr) 763 a = log_sockaddr( 764 (struct sockaddr *)&p->addr->ss); 765 if (p->addr_head.pool) 766 pool = "from pool "; 767 log_warnx("bad peer %s%s (%s)", pool, 768 p->addr_head.name, a); 769 } 770 } 771 } 772 if (sensors_cnt > 0) { 773 log_warnx("%u out of %u sensors valid", 774 sensors_cnt - badsensors, sensors_cnt); 775 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 776 if (!s->update.good) 777 log_warnx("bad sensor %s", s->device); 778 } 779 } 780 } 781