Browse Source

scale query interval based on local clock offset. tested by many

not as efficient as I want it to be yet, but more is coming
OPENBSD_3_6
henning 20 years ago
parent
commit
d2decbe40d
3 changed files with 87 additions and 66 deletions
  1. +70
    -9
      src/usr.sbin/ntpd/client.c
  2. +11
    -55
      src/usr.sbin/ntpd/ntp.c
  3. +6
    -2
      src/usr.sbin/ntpd/ntpd.h

+ 70
- 9
src/usr.sbin/ntpd/client.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: client.c,v 1.19 2004/07/09 15:02:15 henning Exp $ */
/* $OpenBSD: client.c,v 1.20 2004/07/10 18:42:51 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -26,6 +26,8 @@
#include "ntpd.h"
int client_update(struct ntp_peer *);
int
client_peer_init(struct ntp_peer *p)
{
@ -126,6 +128,8 @@ client_dispatch(struct ntp_peer *p)
ssize_t size;
struct ntp_msg msg;
double T1, T2, T3, T4;
double abs_offset;
time_t interval;
fsa_len = sizeof(fsa);
if ((size = recvfrom(p->query->fd, &buf, sizeof(buf), 0,
@ -166,12 +170,26 @@ client_dispatch(struct ntp_peer *p)
p->reply[p->shift].good = 1;
if (p->trustlevel < TRUSTLEVEL_PATHETIC)
p->next = time(NULL) + INTERVAL_QUERY_PATHETIC;
interval = INTERVAL_QUERY_PATHETIC;
else if (p->trustlevel < TRUSTLEVEL_AGRESSIVE)
p->next = time(NULL) + INTERVAL_QUERY_AGRESSIVE;
else
p->next = time(NULL) + INTERVAL_QUERY_NORMAL;
interval = INTERVAL_QUERY_AGRESSIVE;
else {
if (p->update.offset < 0)
abs_offset = p->update.offset * -1;
else
abs_offset = p->update.offset;
log_debug("offset %f, abs_offset %f", p->update.offset, abs_offset);
if (!p->update.good)
interval = INTERVAL_QUERY_NORMAL;
else if (abs_offset > QSCALE_OFF_MAX)
interval = INTERVAL_QUERY_NORMAL;
else if (abs_offset < QSCALE_OFF_MIN)
interval = INTERVAL_QUERY_NORMAL * (1 / QSCALE_OFF_MIN);
else
interval = INTERVAL_QUERY_NORMAL * (1 / abs_offset);
}
p->next = time(NULL) + interval;
p->deadline = 0;
p->state = STATE_REPLY_RECEIVED;
@ -184,12 +202,55 @@ client_dispatch(struct ntp_peer *p)
p->trustlevel++;
}
log_debug("received reply from %s: offset %f delay %f",
log_sockaddr((struct sockaddr *)&fsa), p->reply[p->shift].offset,
p->reply[p->shift].delay);
log_debug("reply from %s: offset %f delay %f, "
"next query %ds", log_sockaddr((struct sockaddr *)&fsa),
p->reply[p->shift].offset, p->reply[p->shift].delay, interval);
if (++p->shift >= OFFSET_ARRAY_SIZE)
if (++p->shift >= OFFSET_ARRAY_SIZE) {
p->shift = 0;
client_update(p);
}
return (0);
}
int
client_update(struct ntp_peer *p)
{
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 &&
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;
}
if (good == 0)
return (-1);
memcpy(&p->update, &p->reply[best], sizeof(p->update));
for (i = 0; i < OFFSET_ARRAY_SIZE; i++)
if (p->reply[i].rcvd <= p->reply[best].rcvd)
p->reply[i].good = 0;
return (0);
}

+ 11
- 55
src/usr.sbin/ntpd/ntp.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntp.c,v 1.21 2004/07/09 15:00:43 henning Exp $ */
/* $OpenBSD: ntp.c,v 1.22 2004/07/10 18:42:51 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -38,7 +38,6 @@ struct l_fixedpt ref_ts;
void ntp_sighdlr(int);
int ntp_dispatch_imsg(void);
void ntp_adjtime(struct ntpd_conf *);
int get_peer_update(struct ntp_peer *, double *);
void
ntp_sighdlr(int sig)
@ -175,7 +174,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *conf)
log_sockaddr(
(struct sockaddr *)&p->addr->ss));
if (p->trustlevel >= TRUSTLEVEL_BADPEER &&
--p->trustlevel < TRUSTLEVEL_BADPEER)
(p->trustlevel /= 2) < TRUSTLEVEL_BADPEER)
log_info("peer %s now invalid",
log_sockaddr(
(struct sockaddr *)&p->addr->ss));
@ -278,13 +277,18 @@ void
ntp_adjtime(struct ntpd_conf *conf)
{
struct ntp_peer *p;
double offset, offset_median = 0;
double offset_median = 0;
int offset_cnt = 0;
TAILQ_FOREACH(p, &conf->ntp_peers, entry)
if (get_peer_update(p, &offset) == 0) {
offset_median += offset;
offset_cnt++;
if (p->update.good) {
if (p->update.rcvd + REPLY_MAXAGE < time(NULL))
p->update.good = 0;
else
if (p->trustlevel >= TRUSTLEVEL_BADPEER) {
offset_median += p->update.offset;
offset_cnt++;
}
}
if (offset_cnt > 0) {
@ -293,51 +297,3 @@ ntp_adjtime(struct ntpd_conf *conf)
&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 &&
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;
}
/* 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->addr->ss));
p->trustlevel /= 2;
}
if (good == 0 || p->trustlevel < TRUSTLEVEL_BADPEER)
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);
}

+ 6
- 2
src/usr.sbin/ntpd/ntpd.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntpd.h,v 1.20 2004/07/09 19:44:18 deraadt Exp $ */
/* $OpenBSD: ntpd.h,v 1.21 2004/07/10 18:42:51 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -46,8 +46,11 @@
#define TRUSTLEVEL_PATHETIC 2
#define TRUSTLEVEL_AGRESSIVE 8
#define QSCALE_OFF_MIN 0.05
#define QSCALE_OFF_MAX 1
#define QUERYTIME_MAX 15 /* single query might take n secs max */
#define REPLY_MAXAGE 300
#define REPLY_MAXAGE 720
#define OFFSET_ARRAY_SIZE 8
enum client_state {
@ -84,6 +87,7 @@ struct ntp_peer {
time_t next;
time_t deadline;
struct ntp_offset reply[OFFSET_ARRAY_SIZE];
struct ntp_offset update;
u_int8_t shift;
u_int8_t trustlevel;
};


Loading…
Cancel
Save