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