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; };