Browse Source

do not take the average offset from all peers when calculating the total

offset to correct the local clock, but use the median.
given a reasonable sized set of servers this makes us nearly immune against
outliers or flasetickers, without the need for a horribly complicated outliers
detection which does not yield to better results anyway.
test & ok otto
OPENBSD_3_7
henning 20 years ago
parent
commit
addeddaa0e
1 changed files with 43 additions and 8 deletions
  1. +43
    -8
      src/usr.sbin/ntpd/ntp.c

+ 43
- 8
src/usr.sbin/ntpd/ntp.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntp.c,v 1.33 2004/09/18 20:01:38 henning Exp $ */
/* $OpenBSD: ntp.c,v 1.34 2004/10/04 11:12:58 henning Exp $ */
/* /*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -43,6 +43,7 @@ void ntp_sighdlr(int);
int ntp_dispatch_imsg(void); int ntp_dispatch_imsg(void);
void peer_add(struct ntp_peer *); void peer_add(struct ntp_peer *);
void peer_remove(struct ntp_peer *); void peer_remove(struct ntp_peer *);
int offset_compare(const void *, const void *);
void void
ntp_sighdlr(int sig) ntp_sighdlr(int sig)
@ -345,23 +346,38 @@ peer_remove(struct ntp_peer *p)
void void
ntp_adjtime(void) ntp_adjtime(void)
{ {
struct ntp_peer *p;
double offset_median = 0;
int offset_cnt = 0;
struct ntp_peer *p;
int offset_cnt = 0, i = 0;
struct ntp_peer **peers;
double offset_median;
TAILQ_FOREACH(p, &conf->ntp_peers, entry) { TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
if (p->trustlevel < TRUSTLEVEL_BADPEER) if (p->trustlevel < TRUSTLEVEL_BADPEER)
continue; continue;
if (!p->update.good) if (!p->update.good)
return; return;
offset_median += p->update.offset;
offset_cnt++; offset_cnt++;
} }
if ((peers = calloc(offset_cnt, sizeof(struct ntp_peer *))) == NULL)
fatal("calloc ntp_adjtime");
TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
if (p->trustlevel < TRUSTLEVEL_BADPEER)
continue;
peers[i++] = p;
}
qsort(peers, offset_cnt, sizeof(struct ntp_peer *), offset_compare);
if (offset_cnt > 0) { if (offset_cnt > 0) {
offset_median /= offset_cnt;
if (offset_cnt > 1 && offset_cnt % 2 == 0)
offset_median =
(peers[offset_cnt / 2 - 1]->update.offset +
peers[offset_cnt / 2]->update.offset) / 2;
else
offset_median = peers[offset_cnt / 2]->update.offset;
imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0,
&offset_median, sizeof(offset_median)); &offset_median, sizeof(offset_median));
@ -369,10 +385,29 @@ ntp_adjtime(void)
conf->status.leap = LI_NOWARNING; /* XXX */ conf->status.leap = LI_NOWARNING; /* XXX */
} }
free(peers);
TAILQ_FOREACH(p, &conf->ntp_peers, entry) TAILQ_FOREACH(p, &conf->ntp_peers, entry)
p->update.good = 0; p->update.good = 0;
} }
int
offset_compare(const void *aa, const void *bb)
{
const struct ntp_peer * const *a;
const struct ntp_peer * const *b;
a = aa;
b = bb;
if ((*a)->update.offset < (*b)->update.offset)
return (-1);
else if ((*a)->update.offset > (*b)->update.offset)
return (1);
else
return (0);
}
void void
ntp_settime(double offset) ntp_settime(double offset)
{ {


Loading…
Cancel
Save