Browse Source

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.
OPENBSD_3_6
henning 20 years ago
parent
commit
1bd657839e
3 changed files with 62 additions and 14 deletions
  1. +8
    -5
      src/usr.sbin/ntpd/client.c
  2. +43
    -5
      src/usr.sbin/ntpd/ntp.c
  3. +11
    -4
      src/usr.sbin/ntpd/ntpd.h

+ 8
- 5
src/usr.sbin/ntpd/client.c View File

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


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

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

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

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


Loading…
Cancel
Save