diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index f877e1f9..81d7eb86 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.11 2004/07/06 23:26:38 henning Exp $ */ +/* $OpenBSD: client.c,v 1.12 2004/07/07 01:01:27 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -58,7 +58,7 @@ client_peer_init(struct ntp_peer *p) p->state = STATE_NONE; p->next = time(NULL); p->shift = 0; - p->valid = 0; + p->trustlevel = TRUSTLEVEL_PATHETIC; return (0); } @@ -144,18 +144,31 @@ client_dispatch(struct ntp_peer *p) p->reply[p->shift].rcvd = time(NULL); p->reply[p->shift].good = 1; - p->state = STATE_REPLY_RECEIVED; - p->next = time(NULL) + INTERVAL_QUERY; + if (p->trustlevel < TRUSTLEVEL_PATHETIC) + p->next = time(NULL) + INTERVAL_QUERY_PATHETIC; + else if (p->trustlevel < TRUSTLEVEL_AGRESSIVE) + p->next = time(NULL) + INTERVAL_QUERY_AGRESSIVE; + else + p->next = time(NULL) + INTERVAL_QUERY_NORMAL; + p->deadline = 0; + p->state = STATE_REPLY_RECEIVED; log_debug("reply received from %s: offset %f delay %f", log_sockaddr((struct sockaddr *)&fsa), p->reply[p->shift].offset, p->reply[p->shift].delay); - if (++p->shift >= OFFSET_ARRAY_SIZE) { - p->shift = 0; - p->valid = 1; + /* every received reply which we do not discard increases trust */ + if (p->trustlevel < 10) { + if (p->trustlevel < TRUSTLEVEL_BADPEER && + p->trustlevel + 1 >= TRUSTLEVEL_BADPEER) + log_info("peer %s now valid", + log_sockaddr((struct sockaddr *)&fsa)); + p->trustlevel++; } + if (++p->shift >= OFFSET_ARRAY_SIZE) + p->shift = 0; + return (0); } diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 05788e33..d9a66db0 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.12 2004/07/06 23:26:38 henning Exp $ */ +/* $OpenBSD: ntp.c,v 1.13 2004/07/07 01:01:27 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -165,9 +165,18 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *conf) TAILQ_FOREACH(p, &conf->ntp_peers, entry) { if (p->next > 0 && p->next < nextaction) nextaction = p->next; - if ((p->next > 0 && p->next <= time(NULL)) || - (p->deadline > 0 && p->deadline <= time(NULL))) + + if (p->next > 0 && p->next <= time(NULL)) + client_query(p); + + if (p->deadline > 0 && p->deadline <= time(NULL)) { + if (p->trustlevel >= TRUSTLEVEL_BADPEER && + --p->trustlevel < TRUSTLEVEL_BADPEER) + log_info("peer %s now invalid", + log_sockaddr( + (struct sockaddr *)&p->ss)); client_query(p); + } if (p->state == STATE_QUERY_SENT) { pfd[i].fd = p->query->fd; @@ -287,15 +296,11 @@ ntp_adjtime(struct ntpd_conf *conf) double offset, offset_median = 0; int offset_cnt = 0; - TAILQ_FOREACH(p, &conf->ntp_peers, entry) { - if (!p->valid) - continue; - + TAILQ_FOREACH(p, &conf->ntp_peers, entry) if (get_peer_update(p, &offset) == 0) { offset_median += offset; offset_cnt++; } - } offset_median /= offset_cnt; @@ -322,16 +327,26 @@ get_peer_update(struct ntp_peer *p, double *offset) best = i; } - for (; i < OFFSET_ARRAY_SIZE; i++) - if (p->reply[i].good) { + 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; - } + } - /* XXX lower trust in the peer when too few good replies received */ + /* 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->ss)); + p->trustlevel /= 2; + } - if (good == 0) + if (good == 0 || p->trustlevel < TRUSTLEVEL_BADPEER) return (-1); for (i = 0; i < OFFSET_ARRAY_SIZE; i++) diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index 795fd55f..48b6be87 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.13 2004/07/06 23:26:38 henning Exp $ */ +/* $OpenBSD: ntpd.h,v 1.14 2004/07/07 01:01:27 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -36,9 +36,17 @@ #define NTPD_OPT_VERBOSE 0x0001 #define NTPD_OPT_VERBOSE2 0x0002 -#define INTERVAL_ADJTIME 240 /* call adjtime every n seconds */ -#define INTERVAL_QUERY 30 /* sync with peers every n seconds */ +#define INTERVAL_ADJTIME 240 /* call adjtime every n secs */ +#define INTERVAL_QUERY_NORMAL 30 /* sync to peers every n secs */ +#define INTERVAL_QUERY_PATHETIC 60 +#define INTERVAL_QUERY_AGRESSIVE 5 + +#define TRUSTLEVEL_BADPEER 6 +#define TRUSTLEVEL_PATHETIC 2 +#define TRUSTLEVEL_AGRESSIVE 8 + #define QUERYTIME_MAX 15 /* single query might take n secs max */ +#define REPLY_MAXAGE 300 #define OFFSET_ARRAY_SIZE 8 enum client_state { @@ -70,7 +78,7 @@ struct ntp_peer { time_t deadline; struct ntp_offset reply[OFFSET_ARRAY_SIZE]; u_int8_t shift; - u_int8_t valid; + u_int8_t trustlevel; }; struct ntpd_conf {