Browse Source

keep a "trustlevel" per peer. loose credit for loosing a packet, loose

a lot of credit for not having supplied us with enough data within an
adjtime run interval, and get a little credit each time we get a good
reply packet. if a peer is below 20%, only send a packet occasionally to
see wether it is back. send out queries much more often between 20 and 80%
to (re-)sync quickly, and above 80% usethe regular interval.
do not use peers < 60% for calculating teh local clock offset.
designed with theo at the pho, alexander ok
OPENBSD_3_6
henning 20 years ago
parent
commit
ccb62d3811
3 changed files with 60 additions and 24 deletions
  1. +20
    -7
      src/usr.sbin/ntpd/client.c
  2. +28
    -13
      src/usr.sbin/ntpd/ntp.c
  3. +12
    -4
      src/usr.sbin/ntpd/ntpd.h

+ 20
- 7
src/usr.sbin/ntpd/client.c View File

@ -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 <henning@openbsd.org>
@ -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);
}

+ 28
- 13
src/usr.sbin/ntpd/ntp.c View File

@ -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 <henning@openbsd.org>
@ -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++)


+ 12
- 4
src/usr.sbin/ntpd/ntpd.h View File

@ -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 <henning@openbsd.org>
@ -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 {


Loading…
Cancel
Save