From 1bd657839e60f0274245b5a93e87f6aed65a1a0a Mon Sep 17 00:00:00 2001 From: henning <> Date: Tue, 6 Jul 2004 23:26:38 +0000 Subject: [PATCH] Implement the clock filter as descirbed by David Mills: form the last 8 replied received from a peer, find the one with the lowest delay. Use that as the peer's update taken into account for calculating the local clock's offset. Invalidate that reply and all ones received earlier than it so that they do not get used again. --- src/usr.sbin/ntpd/client.c | 13 +++++++---- src/usr.sbin/ntpd/ntp.c | 48 ++++++++++++++++++++++++++++++++++---- src/usr.sbin/ntpd/ntpd.h | 15 ++++++++---- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index 70560973..f877e1f9 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.10 2004/07/06 19:06:43 henning Exp $ */ +/* $OpenBSD: client.c,v 1.11 2004/07/06 23:26:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -138,16 +138,19 @@ client_dispatch(struct ntp_peer *p) T2 = lfp_to_d(msg.rectime); T3 = lfp_to_d(msg.xmttime); - p->offset[p->shift] = ((T2 - T1) + (T3 - T4)) / 2; - p->delay[p->shift] = (T2 - T1) - (T3 - T4); + p->reply[p->shift].offset = ((T2 - T1) + (T3 - T4)) / 2; + p->reply[p->shift].delay = (T4 - T1) - (T2 - T3); + p->reply[p->shift].error = (T2 - T1) - (T3 - T4); + p->reply[p->shift].rcvd = time(NULL); + p->reply[p->shift].good = 1; p->state = STATE_REPLY_RECEIVED; p->next = time(NULL) + INTERVAL_QUERY; p->deadline = 0; log_debug("reply received from %s: offset %f delay %f", - log_sockaddr((struct sockaddr *)&fsa), p->offset[p->shift], - p->delay[p->shift]); + log_sockaddr((struct sockaddr *)&fsa), p->reply[p->shift].offset, + p->reply[p->shift].delay); if (++p->shift >= OFFSET_ARRAY_SIZE) { p->shift = 0; diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 9f4a980a..05788e33 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.11 2004/07/05 22:12:53 henning Exp $ */ +/* $OpenBSD: ntp.c,v 1.12 2004/07/06 23:26:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -39,6 +39,7 @@ void ntp_sighdlr(int); int ntp_dispatch_imsg(void); int ntp_dispatch(int fd); void ntp_adjtime(struct ntpd_conf *); +int get_peer_update(struct ntp_peer *, double *); void ntp_sighdlr(int sig) @@ -283,16 +284,15 @@ void ntp_adjtime(struct ntpd_conf *conf) { struct ntp_peer *p; - double offset_median = 0; + double offset, offset_median = 0; int offset_cnt = 0; - u_int8_t idx; TAILQ_FOREACH(p, &conf->ntp_peers, entry) { if (!p->valid) continue; - for (idx = 0; idx < OFFSET_ARRAY_SIZE; idx++) { - offset_median += p->offset[idx]; + if (get_peer_update(p, &offset) == 0) { + offset_median += offset; offset_cnt++; } } @@ -303,3 +303,41 @@ ntp_adjtime(struct ntpd_conf *conf) imsg_compose(&ibuf_main, IMSG_ADJTIME, 0, &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) { + good++; + if (p->reply[i].delay < p->reply[best].delay) + best = i; + } + + /* XXX lower trust in the peer when too few good replies received */ + + if (good == 0) + 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 ea083392..795fd55f 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.12 2004/07/05 22:12:53 henning Exp $ */ +/* $OpenBSD: ntpd.h,v 1.13 2004/07/06 23:26:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -36,7 +36,7 @@ #define NTPD_OPT_VERBOSE 0x0001 #define NTPD_OPT_VERBOSE2 0x0002 -#define INTERVAL_ADJTIME 120 /* call adjtime every n seconds */ +#define INTERVAL_ADJTIME 240 /* call adjtime every n seconds */ #define INTERVAL_QUERY 30 /* sync with peers every n seconds */ #define QUERYTIME_MAX 15 /* single query might take n secs max */ #define OFFSET_ARRAY_SIZE 8 @@ -53,6 +53,14 @@ struct listen_addr { int fd; }; +struct ntp_offset { + u_int8_t good; + double offset; + double delay; + double error; + time_t rcvd; +}; + struct ntp_peer { TAILQ_ENTRY(ntp_peer) entry; struct sockaddr_storage ss; @@ -60,8 +68,7 @@ struct ntp_peer { enum client_state state; time_t next; time_t deadline; - double offset[OFFSET_ARRAY_SIZE]; - double delay[OFFSET_ARRAY_SIZE]; + struct ntp_offset reply[OFFSET_ARRAY_SIZE]; u_int8_t shift; u_int8_t valid; };