Hi,
While hunting a bug in ntpd offset handling, I found some things
that could be improved.
Call the index of the offset loops "shift" consistently.
Merge the two offset loops in client_update() into one.
Assign the best value instead of memcpy.
Use the same mechanism everywhere to avoid an invalid best value.
ok?
bluhm
Index: client.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/client.c,v
retrieving revision 1.115
diff -u -p -r1.115 client.c
--- client.c 18 Mar 2021 11:06:41 -0000 1.115
+++ client.c 18 Mar 2021 11:20:49 -0000
@@ -473,7 +473,7 @@ client_dispatch(struct ntp_peer *p, u_in
int
client_update(struct ntp_peer *p)
{
- int i, best = 0, good = 0;
+ int shift, best = -1, good = 0;
/*
* clock filter
@@ -482,27 +482,22 @@ client_update(struct ntp_peer *p)
* invalidate it and all older ones
*/
- for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++)
- if (p->reply[i].good) {
+ for (shift = 0; shift < OFFSET_ARRAY_SIZE; shift++)
+ if (p->reply[shift].good) {
good++;
- best = i;
+ if (best == -1 ||
+ p->reply[shift].delay < p->reply[best].delay)
+ best = shift;
}
- for (; i < OFFSET_ARRAY_SIZE; i++)
- if (p->reply[i].good) {
- good++;
- if (p->reply[i].delay < p->reply[best].delay)
- best = i;
- }
-
- if (good < 8)
+ if (best == -1 || good < 8)
return (-1);
- memcpy(&p->update, &p->reply[best], sizeof(p->update));
+ p->update = p->reply[best];
if (priv_adjtime() == 0) {
- for (i = 0; i < OFFSET_ARRAY_SIZE; i++)
- if (p->reply[i].rcvd <= p->reply[best].rcvd)
- p->reply[i].good = 0;
+ for (shift = 0; shift < OFFSET_ARRAY_SIZE; shift++)
+ if (p->reply[shift].rcvd <= p->reply[best].rcvd)
+ p->reply[shift].good = 0;
}
return (0);
}
Index: control.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/control.c,v
retrieving revision 1.18
diff -u -p -r1.18 control.c
--- control.c 12 Feb 2020 19:14:56 -0000 1.18
+++ control.c 18 Mar 2021 11:20:53 -0000
@@ -341,7 +341,7 @@ build_show_peer(struct ctl_show_peer *cp
const char *a = "not resolved";
const char *pool = "", *addr_head_name = "";
const char *auth = "";
- u_int8_t shift, best, validdelaycnt, jittercnt;
+ int shift, best = -1, validdelaycnt = 0, jittercnt = 0;
time_t now;
now = getmonotime();
@@ -360,14 +360,14 @@ build_show_peer(struct ctl_show_peer *cp
snprintf(cp->peer_desc, sizeof(cp->peer_desc),
"%s %s%s%s", a, pool, addr_head_name, auth);
- validdelaycnt = best = 0;
cp->offset = cp->delay = 0.0;
for (shift = 0; shift < OFFSET_ARRAY_SIZE; shift++) {
if (p->reply[shift].delay > 0.0) {
cp->offset += p->reply[shift].offset;
cp->delay += p->reply[shift].delay;
- if (p->reply[shift].delay < p->reply[best].delay)
+ if (best == -1 ||
+ p->reply[shift].delay < p->reply[best].delay)
best = shift;
validdelaycnt++;
@@ -379,18 +379,19 @@ build_show_peer(struct ctl_show_peer *cp
cp->delay /= validdelaycnt;
}
- jittercnt = 0;
cp->jitter = 0.0;
- for (shift = 0; shift < OFFSET_ARRAY_SIZE; shift++) {
- if (p->reply[shift].delay > 0.0 && shift != best) {
- cp->jitter += square(p->reply[shift].delay -
- p->reply[best].delay);
- jittercnt++;
+ if (best != -1) {
+ for (shift = 0; shift < OFFSET_ARRAY_SIZE; shift++) {
+ if (p->reply[shift].delay > 0.0 && shift != best) {
+ cp->jitter += square(p->reply[shift].delay -
+ p->reply[best].delay);
+ jittercnt++;
+ }
}
+ if (jittercnt > 1)
+ cp->jitter /= jittercnt;
+ cp->jitter = sqrt(cp->jitter);
}
- if (jittercnt > 1)
- cp->jitter /= jittercnt;
- cp->jitter = sqrt(cp->jitter);
if (p->shift == 0)
shift = OFFSET_ARRAY_SIZE - 1;