1 /* $OpenBSD: ntp.c,v 1.116 2011/06/17 18:12:05 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 close(pipe_prnt[0]); 114 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_dns) == -1) 115 fatal("socketpair"); 116 dns_pid = ntp_dns(pipe_dns, nconf, pw); 117 close(pipe_dns[1]); 118 119 if (stat(pw->pw_dir, &stb) == -1) 120 fatal("stat"); 121 if (stb.st_uid != 0 || (stb.st_mode & (S_IWGRP|S_IWOTH)) != 0) 122 fatalx("bad privsep dir permissions"); 123 if (chroot(pw->pw_dir) == -1) 124 fatal("chroot"); 125 if (chdir("/") == -1) 126 fatal("chdir(\"/\")"); 127 128 if (!nconf->debug) { 129 dup2(nullfd, STDIN_FILENO); 130 dup2(nullfd, STDOUT_FILENO); 131 dup2(nullfd, STDERR_FILENO); 132 } 133 close(nullfd); 134 135 setproctitle("ntp engine"); 136 137 conf = nconf; 138 setup_listeners(se, conf, &listener_cnt); 139 140 if (setgroups(1, &pw->pw_gid) || 141 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 142 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 143 fatal("can't drop privileges"); 144 145 endservent(); 146 147 signal(SIGTERM, ntp_sighdlr); 148 signal(SIGINT, ntp_sighdlr); 149 signal(SIGINFO, ntp_sighdlr); 150 signal(SIGPIPE, SIG_IGN); 151 signal(SIGHUP, SIG_IGN); 152 signal(SIGCHLD, SIG_DFL); 153 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 conf->freq.samples = 0; 532 return; 533 } 534 535 conf->freq.samples++; 536 537 if (conf->freq.samples <= 0) 538 return; 539 540 conf->freq.overall_offset += offset; 541 offset = conf->freq.overall_offset; 542 543 curtime = gettime_corrected(); 544 conf->freq.xy += offset * curtime; 545 conf->freq.x += curtime; 546 conf->freq.y += offset; 547 conf->freq.xx += curtime * curtime; 548 549 if (conf->freq.samples % FREQUENCY_SAMPLES != 0) 550 return; 551 552 freq = 553 (conf->freq.xy - conf->freq.x * conf->freq.y / conf->freq.samples) 554 / 555 (conf->freq.xx - conf->freq.x * conf->freq.x / conf->freq.samples); 556 557 if (freq > MAX_FREQUENCY_ADJUST) 558 freq = MAX_FREQUENCY_ADJUST; 559 else if (freq < -MAX_FREQUENCY_ADJUST) 560 freq = -MAX_FREQUENCY_ADJUST; 561 562 imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, -1, &freq, sizeof(freq)); 563 conf->filters |= FILTER_ADJFREQ; 564 conf->freq.xy = 0.0; 565 conf->freq.x = 0.0; 566 conf->freq.y = 0.0; 567 conf->freq.xx = 0.0; 568 conf->freq.samples = 0; 569 conf->freq.overall_offset = 0.0; 570 conf->freq.num++; 571 } 572 573 int 574 priv_adjtime(void) 575 { 576 struct ntp_peer *p; 577 struct ntp_sensor *s; 578 int offset_cnt = 0, i = 0, j; 579 struct ntp_offset **offsets; 580 double offset_median; 581 582 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 583 if (p->trustlevel < TRUSTLEVEL_BADPEER) 584 continue; 585 if (!p->update.good) 586 return (1); 587 offset_cnt += p->weight; 588 } 589 590 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 591 if (!s->update.good) 592 continue; 593 offset_cnt += s->weight; 594 } 595 596 if (offset_cnt == 0) 597 return (1); 598 599 if ((offsets = calloc(offset_cnt, sizeof(struct ntp_offset *))) == NULL) 600 fatal("calloc priv_adjtime"); 601 602 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 603 if (p->trustlevel < TRUSTLEVEL_BADPEER) 604 continue; 605 for (j = 0; j < p->weight; j++) 606 offsets[i++] = &p->update; 607 } 608 609 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 610 if (!s->update.good) 611 continue; 612 for (j = 0; j < s->weight; j++) 613 offsets[i++] = &s->update; 614 } 615 616 qsort(offsets, offset_cnt, sizeof(struct ntp_offset *), offset_compare); 617 618 i = offset_cnt / 2; 619 if (offset_cnt % 2 == 0) { 620 offset_median = 621 (offsets[i - 1]->offset + offsets[i]->offset) / 2; 622 conf->status.rootdelay = 623 (offsets[i - 1]->delay + offsets[i]->delay) / 2; 624 conf->status.stratum = MAX( 625 offsets[i - 1]->status.stratum, offsets[i]->status.stratum); 626 } else { 627 offset_median = offsets[i]->offset; 628 conf->status.rootdelay = offsets[i]->delay; 629 conf->status.stratum = offsets[i]->status.stratum; 630 } 631 conf->status.leap = offsets[i]->status.leap; 632 633 imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, -1, 634 &offset_median, sizeof(offset_median)); 635 636 priv_adjfreq(offset_median); 637 638 conf->status.reftime = gettime(); 639 conf->status.stratum++; /* one more than selected peer */ 640 if (conf->status.stratum > NTP_MAXSTRATUM) 641 conf->status.stratum = NTP_MAXSTRATUM; 642 update_scale(offset_median); 643 644 conf->status.refid = offsets[i]->status.send_refid; 645 646 free(offsets); 647 648 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 649 for (i = 0; i < OFFSET_ARRAY_SIZE; i++) 650 p->reply[i].offset -= offset_median; 651 p->update.good = 0; 652 } 653 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 654 for (i = 0; i < SENSOR_OFFSETS; i++) 655 s->offsets[i].offset -= offset_median; 656 s->update.offset -= offset_median; 657 } 658 659 return (0); 660 } 661 662 int 663 offset_compare(const void *aa, const void *bb) 664 { 665 const struct ntp_offset * const *a; 666 const struct ntp_offset * const *b; 667 668 a = aa; 669 b = bb; 670 671 if ((*a)->offset < (*b)->offset) 672 return (-1); 673 else if ((*a)->offset > (*b)->offset) 674 return (1); 675 else 676 return (0); 677 } 678 679 void 680 priv_settime(double offset) 681 { 682 imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, -1, 683 &offset, sizeof(offset)); 684 conf->settime = 0; 685 } 686 687 void 688 priv_host_dns(char *name, u_int32_t peerid) 689 { 690 u_int16_t dlen; 691 692 dlen = strlen(name) + 1; 693 imsg_compose(ibuf_dns, IMSG_HOST_DNS, peerid, 0, -1, name, dlen); 694 } 695 696 void 697 update_scale(double offset) 698 { 699 offset += getoffset(); 700 if (offset < 0) 701 offset = -offset; 702 703 if (offset > QSCALE_OFF_MAX || !conf->status.synced || 704 conf->freq.num < 3) 705 conf->scale = 1; 706 else if (offset < QSCALE_OFF_MIN) 707 conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN; 708 else 709 conf->scale = QSCALE_OFF_MAX / offset; 710 } 711 712 time_t 713 scale_interval(time_t requested) 714 { 715 time_t interval, r; 716 717 interval = requested * conf->scale; 718 r = arc4random_uniform(MAX(5, interval / 10)); 719 return (interval + r); 720 } 721 722 time_t 723 error_interval(void) 724 { 725 time_t interval, r; 726 727 interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN; 728 r = arc4random_uniform(interval / 10); 729 return (interval + r); 730 } 731 732 void 733 report_peers(int always) 734 { 735 time_t now; 736 u_int badpeers = 0; 737 u_int badsensors = 0; 738 struct ntp_peer *p; 739 struct ntp_sensor *s; 740 741 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 742 if (p->trustlevel < TRUSTLEVEL_BADPEER) 743 badpeers++; 744 } 745 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 746 if (!s->update.good) 747 badsensors++; 748 } 749 750 now = getmonotime(); 751 if (!always) { 752 if ((peer_cnt == 0 || badpeers == 0 || badpeers < peer_cnt / 2) 753 && (sensors_cnt == 0 || badsensors == 0 || 754 badsensors < sensors_cnt / 2)) 755 return; 756 757 if (lastreport + REPORT_INTERVAL > now) 758 return; 759 } 760 lastreport = now; 761 if (peer_cnt > 0) { 762 log_warnx("%u out of %u peers valid", peer_cnt - badpeers, 763 peer_cnt); 764 TAILQ_FOREACH(p, &conf->ntp_peers, entry) { 765 if (p->trustlevel < TRUSTLEVEL_BADPEER) { 766 const char *a = "not resolved"; 767 const char *pool = ""; 768 if (p->addr) 769 a = log_sockaddr( 770 (struct sockaddr *)&p->addr->ss); 771 if (p->addr_head.pool) 772 pool = "from pool "; 773 log_warnx("bad peer %s%s (%s)", pool, 774 p->addr_head.name, a); 775 } 776 } 777 } 778 if (sensors_cnt > 0) { 779 log_warnx("%u out of %u sensors valid", 780 sensors_cnt - badsensors, sensors_cnt); 781 TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { 782 if (!s->update.good) 783 log_warnx("bad sensor %s", s->device); 784 } 785 } 786 } 787