summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-07-10 18:42:52 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-07-10 18:42:52 +0000
commit29bfa60d32391eaf14ba5095185838af5eb545f9 (patch)
tree973db6691812611e964fa3947ee4d80cbfbf7e71
parent0c408f89fe5b2a2747113e0036b164aa1d117011 (diff)
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
-rw-r--r--usr.sbin/ntpd/client.c79
-rw-r--r--usr.sbin/ntpd/ntp.c66
-rw-r--r--usr.sbin/ntpd/ntpd.h8
3 files changed, 87 insertions, 66 deletions
diff --git a/usr.sbin/ntpd/client.c b/usr.sbin/ntpd/client.c
index 7c2503e1359..a2ededf65ae 100644
--- a/usr.sbin/ntpd/client.c
+++ b/usr.sbin/ntpd/client.c
@@ -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);
}
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c
index fe3ef683729..0a382d726bb 100644
--- a/usr.sbin/ntpd/ntp.c
+++ b/usr.sbin/ntpd/ntp.c
@@ -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);
-}
diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h
index beca1d238d1..43b5327ff8b 100644
--- a/usr.sbin/ntpd/ntpd.h
+++ b/usr.sbin/ntpd/ntpd.h
@@ -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;
};