From d2decbe40d68a0a0d3ffa86843637bab48941659 Mon Sep 17 00:00:00 2001 From: henning <> Date: Sat, 10 Jul 2004 18:42:51 +0000 Subject: [PATCH] scale query interval based on local clock offset. tested by many not as efficient as I want it to be yet, but more is coming --- src/usr.sbin/ntpd/client.c | 79 +++++++++++++++++++++++++++++++++----- src/usr.sbin/ntpd/ntp.c | 66 ++++++------------------------- src/usr.sbin/ntpd/ntpd.h | 8 +++- 3 files changed, 87 insertions(+), 66 deletions(-) diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index 7c2503e1..a2ededf6 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.19 2004/07/09 15:02:15 henning Exp $ */ +/* $OpenBSD: client.c,v 1.20 2004/07/10 18:42:51 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -26,6 +26,8 @@ #include "ntpd.h" +int client_update(struct ntp_peer *); + int client_peer_init(struct ntp_peer *p) { @@ -126,6 +128,8 @@ client_dispatch(struct ntp_peer *p) ssize_t size; struct ntp_msg msg; double T1, T2, T3, T4; + double abs_offset; + time_t interval; fsa_len = sizeof(fsa); if ((size = recvfrom(p->query->fd, &buf, sizeof(buf), 0, @@ -166,12 +170,26 @@ client_dispatch(struct ntp_peer *p) p->reply[p->shift].good = 1; if (p->trustlevel < TRUSTLEVEL_PATHETIC) - p->next = time(NULL) + INTERVAL_QUERY_PATHETIC; + interval = INTERVAL_QUERY_PATHETIC; else if (p->trustlevel < TRUSTLEVEL_AGRESSIVE) - p->next = time(NULL) + INTERVAL_QUERY_AGRESSIVE; - else - p->next = time(NULL) + INTERVAL_QUERY_NORMAL; + interval = INTERVAL_QUERY_AGRESSIVE; + else { + if (p->update.offset < 0) + abs_offset = p->update.offset * -1; + else + abs_offset = p->update.offset; +log_debug("offset %f, abs_offset %f", p->update.offset, abs_offset); + if (!p->update.good) + interval = INTERVAL_QUERY_NORMAL; + else if (abs_offset > QSCALE_OFF_MAX) + interval = INTERVAL_QUERY_NORMAL; + else if (abs_offset < QSCALE_OFF_MIN) + interval = INTERVAL_QUERY_NORMAL * (1 / QSCALE_OFF_MIN); + else + interval = INTERVAL_QUERY_NORMAL * (1 / abs_offset); + } + p->next = time(NULL) + interval; p->deadline = 0; p->state = STATE_REPLY_RECEIVED; @@ -184,12 +202,55 @@ client_dispatch(struct ntp_peer *p) p->trustlevel++; } - log_debug("received reply from %s: offset %f delay %f", - log_sockaddr((struct sockaddr *)&fsa), p->reply[p->shift].offset, - p->reply[p->shift].delay); + log_debug("reply from %s: offset %f delay %f, " + "next query %ds", log_sockaddr((struct sockaddr *)&fsa), + p->reply[p->shift].offset, p->reply[p->shift].delay, interval); - if (++p->shift >= OFFSET_ARRAY_SIZE) + if (++p->shift >= OFFSET_ARRAY_SIZE) { p->shift = 0; + client_update(p); + } + + return (0); +} + +int +client_update(struct ntp_peer *p) +{ + int i, best = 0, good = 0; + + /* + * clock filter + * find the offset which arrived with the lowest delay + * use that as the peer update + * invalidate it and all older ones + */ + + for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++) + if (p->reply[i].good) { + good++; + best = i; + } + + for (; i < OFFSET_ARRAY_SIZE; i++) { + if (p->reply[i].good && + p->reply[i].rcvd + REPLY_MAXAGE < time(NULL)) + p->reply[i].good = 0; + + if (p->reply[i].good) + good++; + if (p->reply[i].delay < p->reply[best].delay) + best = i; + } + + if (good == 0) + return (-1); + + memcpy(&p->update, &p->reply[best], sizeof(p->update)); + + for (i = 0; i < OFFSET_ARRAY_SIZE; i++) + if (p->reply[i].rcvd <= p->reply[best].rcvd) + p->reply[i].good = 0; return (0); } diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index fe3ef683..0a382d72 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.21 2004/07/09 15:00:43 henning Exp $ */ +/* $OpenBSD: ntp.c,v 1.22 2004/07/10 18:42:51 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -38,7 +38,6 @@ struct l_fixedpt ref_ts; void ntp_sighdlr(int); int ntp_dispatch_imsg(void); void ntp_adjtime(struct ntpd_conf *); -int get_peer_update(struct ntp_peer *, double *); void ntp_sighdlr(int sig) @@ -175,7 +174,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *conf) log_sockaddr( (struct sockaddr *)&p->addr->ss)); if (p->trustlevel >= TRUSTLEVEL_BADPEER && - --p->trustlevel < TRUSTLEVEL_BADPEER) + (p->trustlevel /= 2) < TRUSTLEVEL_BADPEER) log_info("peer %s now invalid", log_sockaddr( (struct sockaddr *)&p->addr->ss)); @@ -278,13 +277,18 @@ void ntp_adjtime(struct ntpd_conf *conf) { struct ntp_peer *p; - double offset, offset_median = 0; + double offset_median = 0; int offset_cnt = 0; TAILQ_FOREACH(p, &conf->ntp_peers, entry) - if (get_peer_update(p, &offset) == 0) { - offset_median += offset; - offset_cnt++; + if (p->update.good) { + if (p->update.rcvd + REPLY_MAXAGE < time(NULL)) + p->update.good = 0; + else + if (p->trustlevel >= TRUSTLEVEL_BADPEER) { + offset_median += p->update.offset; + offset_cnt++; + } } if (offset_cnt > 0) { @@ -293,51 +297,3 @@ ntp_adjtime(struct ntpd_conf *conf) &offset_median, sizeof(offset_median)); } } - -int -get_peer_update(struct ntp_peer *p, double *offset) -{ - int i, best = 0, good = 0; - - /* - * clock filter - * find the offset which arrived with the lowest delay - * use that as the peer update - * invalidate it and all older ones - */ - - for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++) - if (p->reply[i].good) { - good++; - best = i; - } - - for (; i < OFFSET_ARRAY_SIZE; i++) { - if (p->reply[i].good && - p->reply[i].rcvd + REPLY_MAXAGE < time(NULL)) - p->reply[i].good = 0; - - if (p->reply[i].good) - good++; - if (p->reply[i].delay < p->reply[best].delay) - best = i; - } - - /* lower trust in the peer when too few good replies received */ - if (good < 8 && p->trustlevel > 0) { - if (p->trustlevel >= TRUSTLEVEL_BADPEER) - log_info("peer %s now invalid", - log_sockaddr((struct sockaddr *)&p->addr->ss)); - p->trustlevel /= 2; - } - - if (good == 0 || p->trustlevel < TRUSTLEVEL_BADPEER) - return (-1); - - for (i = 0; i < OFFSET_ARRAY_SIZE; i++) - if (p->reply[i].rcvd <= p->reply[best].rcvd) - p->reply[i].good = 0; - - *offset = p->reply[best].offset; - return (0); -} diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index beca1d23..43b5327f 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.20 2004/07/09 19:44:18 deraadt Exp $ */ +/* $OpenBSD: ntpd.h,v 1.21 2004/07/10 18:42:51 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -46,8 +46,11 @@ #define TRUSTLEVEL_PATHETIC 2 #define TRUSTLEVEL_AGRESSIVE 8 +#define QSCALE_OFF_MIN 0.05 +#define QSCALE_OFF_MAX 1 + #define QUERYTIME_MAX 15 /* single query might take n secs max */ -#define REPLY_MAXAGE 300 +#define REPLY_MAXAGE 720 #define OFFSET_ARRAY_SIZE 8 enum client_state { @@ -84,6 +87,7 @@ struct ntp_peer { time_t next; time_t deadline; struct ntp_offset reply[OFFSET_ARRAY_SIZE]; + struct ntp_offset update; u_int8_t shift; u_int8_t trustlevel; };