xref: /openbsd/usr.sbin/ntpd/ntp.c (revision a6445c1d)
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