aboutsummaryrefslogtreecommitdiff
path: root/ntpd/ntp_proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_proto.c')
-rw-r--r--ntpd/ntp_proto.c145
1 files changed, 91 insertions, 54 deletions
diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c
index fb8a837db5c2..73ada6b442ba 100644
--- a/ntpd/ntp_proto.c
+++ b/ntpd/ntp_proto.c
@@ -33,7 +33,7 @@
/*
* This macro defines the authentication state. If x is 1 authentication
- * is required; othewise it is optional.
+ * is required; otherwise it is optional.
*/
#define AUTH(x, y) ((x) ? (y) == AUTH_OK \
: (y) == AUTH_OK || (y) == AUTH_NONE)
@@ -272,7 +272,7 @@ kiss_code_check(
}
-/*
+/*
* Check that NAK is valid
*/
nak_code
@@ -315,7 +315,7 @@ valid_NAK(
return INVALIDNAK;
}
- /*
+ /*
* Make sure that the extra field in the packet is all zeros
*/
rpkt = &rbufp->recv_pkt;
@@ -324,10 +324,13 @@ valid_NAK(
return INVALIDNAK;
}
- /*
- * Only valid if peer uses a key
+ /*
+ * During the first few packets of the autokey dance there will
+ * not (yet) be a keyid, but in this case FLAG_SKEY is set.
+ * So the NAK is invalid if either there's no peer, or
+ * if the keyid is 0 and FLAG_SKEY is not set.
*/
- if (!peer || !peer->keyid || !(peer->flags & FLAG_SKEY)) {
+ if (!peer || (!peer->keyid && !(peer->flags & FLAG_SKEY))) {
return INVALIDNAK;
}
@@ -372,6 +375,13 @@ transmit(
hpoll = peer->hpoll;
/*
+ * If we haven't received anything (even if unsync) since last
+ * send, reset ppoll.
+ */
+ if (peer->outdate > peer->timelastrec && !peer->reach)
+ peer->ppoll = peer->maxpoll;
+
+ /*
* In broadcast mode the poll interval is never changed from
* minpoll.
*/
@@ -645,7 +655,7 @@ receive(
hisleap = PKT_LEAP(pkt->li_vn_mode);
hismode = (int)PKT_MODE(pkt->li_vn_mode);
hisstratum = PKT_TO_STRATUM(pkt->stratum);
- DPRINTF(2, ("receive: at %ld %s<-%s ippeerlimit %d mode %d iflags %s restrict %s org %#010x.%08x xmt %#010x.%08x\n",
+ DPRINTF(1, ("receive: at %ld %s<-%s ippeerlimit %d mode %d iflags %s restrict %s org %#010x.%08x xmt %#010x.%08x\n",
current_time, stoa(&rbufp->dstadr->sin),
stoa(&rbufp->recv_srcadr), r4a.ippeerlimit, hismode,
build_iflags(rbufp->dstadr->flags),
@@ -737,7 +747,7 @@ receive(
} else {
DPRINTF(2, ("receive: drop: MODE_UNSPEC\n"));
sys_badlength++;
- return; /* invalid mode */
+ return; /* invalid mode */
}
}
@@ -841,7 +851,7 @@ receive(
/*
** Packet Data Verification Layer
**
- ** This layer verifies the packet data content. If
+ ** This layer verifies the packet data content. If
** authentication is required, a MAC must be present.
** If a MAC is present, it must validate.
** Crypto-NAK? Look - a shiny thing!
@@ -949,7 +959,7 @@ receive(
if (0 != peer) {
peer->badNAK++;
}
- msyslog(LOG_ERR, "Invalid-NAK error at %ld %s<-%s",
+ msyslog(LOG_ERR, "Invalid-NAK error at %ld %s<-%s",
current_time, stoa(dstadr_sin), stoa(&rbufp->recv_srcadr));
return;
}
@@ -957,7 +967,7 @@ receive(
if (has_mac == 0) {
restrict_mask &= ~RES_MSSNTP;
is_authentic = AUTH_NONE; /* not required */
- DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n",
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n",
current_time, stoa(dstadr_sin),
stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
authlen,
@@ -966,7 +976,7 @@ receive(
} else if (crypto_nak_test == VALIDNAK) {
restrict_mask &= ~RES_MSSNTP;
is_authentic = AUTH_CRYPTO; /* crypto-NAK */
- DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC4\n",
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x CRYPTONAK\n",
current_time, stoa(dstadr_sin),
stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
skeyid, authlen + has_mac, is_authentic,
@@ -989,13 +999,19 @@ receive(
&& (memcmp(zero_key, (char *)pkt + authlen + 4,
MAX_MD5_LEN - 4) == 0)) {
is_authentic = AUTH_NONE;
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x SIGND\n",
+ current_time, stoa(dstadr_sin),
+ stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
+ authlen,
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
#endif /* HAVE_NTP_SIGND */
} else {
/*
* has_mac is not 0
* Not a VALID_NAK
- * Not an MS-SNTP SIGND packet
+ * Not an MS-SNTP SIGND packet
*
* So there is a MAC here.
*/
@@ -1054,7 +1070,7 @@ receive(
ANY_INTERFACE_CHOOSE(&rbufp->recv_srcadr)) {
DPRINTF(2, ("receive: drop: BCAST from wildcard\n"));
sys_restricted++;
- return; /* no wildcard */
+ return; /* no wildcard */
}
pkeyid = 0;
if (!SOCK_UNSPEC(&rbufp->dstadr->bcast))
@@ -1106,7 +1122,7 @@ receive(
if (crypto_flags && skeyid > NTP_MAXKEY)
authtrust(skeyid, 0);
#endif /* AUTOKEY */
- DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x\n",
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC\n",
current_time, stoa(dstadr_sin),
stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
skeyid, authlen + has_mac, is_authentic,
@@ -1198,6 +1214,8 @@ receive(
* client association; a symmetric active packet mobilizes a
* symmetric passive association.
*/
+ DPRINTF(1, ("receive: MATCH_ASSOC dispatch: mode %d/%s:%s \n",
+ hismode, hm_str, am_str));
switch (retcode) {
/*
@@ -1373,7 +1391,7 @@ receive(
if (NULL == peer) {
DPRINTF(2, ("receive: AM_MANYCAST drop: duplicate\n"));
sys_declined++;
- return; /* ignore duplicate */
+ return; /* ignore duplicate */
}
/*
@@ -1511,10 +1529,10 @@ receive(
* is fixed at this value.
*/
peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep,
- r4a.ippeerlimit, MODE_CLIENT, hisversion,
- pkt->ppoll, pkt->ppoll,
- FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT,
- 0, skeyid, sys_ident);
+ r4a.ippeerlimit, MODE_CLIENT, hisversion,
+ pkt->ppoll, pkt->ppoll,
+ FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT,
+ 0, skeyid, sys_ident);
if (NULL == peer) {
DPRINTF(2, ("receive: AM_NEWBCL drop: empty newpeer() failed\n"));
sys_restricted++;
@@ -1529,15 +1547,19 @@ receive(
return; /* hooray */
/*
- * This is the first packet received from a symmetric active
- * peer. If the packet is authentic, the first he sent, and
- * RES_NOEPEER is not enabled, mobilize a passive association
- * If not, kiss the frog.
+ * This is the first packet received from a potential ephemeral
+ * symmetric active peer. First, deal with broken Windows clients.
+ * Then, if NOEPEER is enabled, drop it. If the packet meets our
+ * authenticty requirements and is the first he sent, mobilize
+ * a passive association.
+ * Otherwise, kiss the frog.
*
* There are cases here where we do not call record_raw_stats().
*/
case AM_NEWPASS:
+ DEBUG_REQUIRE(MODE_ACTIVE == hismode);
+
#ifdef AUTOKEY
/*
* Do not respond if not the same group.
@@ -1551,27 +1573,33 @@ receive(
if (!AUTH(sys_authenticate | (restrict_mask &
(RES_NOPEER | RES_DONTTRUST)), is_authentic)
) {
- if (0 == (restrict_mask & RES_NOEPEER)) {
- /*
- * If authenticated but cannot mobilize an
- * association, send a symmetric passive
- * response without mobilizing an association.
- * This is for drat broken Windows clients. See
- * Microsoft KB 875424 for preferred workaround.
- */
- if (AUTH(restrict_mask & RES_DONTTRUST,
- is_authentic)) {
- fast_xmit(rbufp, MODE_PASSIVE, skeyid,
- restrict_mask);
- return; /* hooray */
- }
- if (is_authentic == AUTH_ERROR) {
- fast_xmit(rbufp, MODE_ACTIVE, 0,
- restrict_mask);
- sys_restricted++;
- return;
- }
+ /*
+ * If authenticated but cannot mobilize an
+ * association, send a symmetric passive
+ * response without mobilizing an association.
+ * This is for drat broken Windows clients. See
+ * Microsoft KB 875424 for preferred workaround.
+ */
+ if (AUTH(restrict_mask & RES_DONTTRUST,
+ is_authentic)) {
+ fast_xmit(rbufp, MODE_PASSIVE, skeyid,
+ restrict_mask);
+ return; /* hooray */
}
+ /* HMS: Why is this next set of lines a feature? */
+ if (is_authentic == AUTH_ERROR) {
+ fast_xmit(rbufp, MODE_PASSIVE, 0,
+ restrict_mask);
+ sys_restricted++;
+ return;
+ }
+
+ if (restrict_mask & RES_NOEPEER) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n"));
+ sys_declined++;
+ return;
+ }
+
/* [Bug 2941]
* If we got here, the packet isn't part of an
* existing association, either isn't correctly
@@ -1593,6 +1621,12 @@ receive(
return;
}
+ if (restrict_mask & RES_NOEPEER) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n"));
+ sys_declined++;
+ return;
+ }
+
/*
* Do not respond if synchronized and if stratum is
* below the floor or at or above the ceiling. Note,
@@ -1670,8 +1704,8 @@ receive(
}
/* This is error-worthy */
- if (pkt->ppoll < peer->minpoll ||
- pkt->ppoll > peer->maxpoll ) {
+ if ( pkt->ppoll < peer->minpoll
+ || pkt->ppoll > peer->maxpoll) {
msyslog(LOG_INFO, "receive: broadcast poll of %u from %s is out-of-range (%d to %d)!",
pkt->ppoll, stoa(&rbufp->recv_srcadr),
peer->minpoll, peer->maxpoll);
@@ -1719,7 +1753,7 @@ receive(
* network is trustable, so we take our accepted
* broadcast packets as we receive them. But
* some folks might want to take additional poll
- * delays before believing a backward step.
+ * delays before believing a backward step.
*/
if (sys_bcpollbstep) {
/* pkt->ppoll or peer->ppoll ? */
@@ -1735,8 +1769,8 @@ receive(
tdiff = p_xmt;
L_SUB(&tdiff, &peer->bxmt);
}
- if (tdiff.l_i < 0 &&
- (current_time - peer->timereceived) < deadband)
+ if ( tdiff.l_i < 0
+ && (current_time - peer->timereceived) < deadband)
{
msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x",
stoa(&rbufp->recv_srcadr),
@@ -2431,6 +2465,7 @@ process_packet(
peer->seldisptoolarge++;
DPRINTF(1, ("packet: flash header %04x\n",
peer->flash));
+ poll_update(peer, peer->hpoll); /* ppoll updated? */
return;
}
@@ -2586,7 +2621,7 @@ process_packet(
* between the unicast timestamp and the broadcast
* timestamp. This works for both basic and interleaved
* modes.
- * [Bug 3031] Don't keep this peer when the delay
+ * [Bug 3031] Don't keep this peer when the delay
* calculation gives reason to suspect clock steps.
* This is assumed for delays > 50ms.
*/
@@ -2977,8 +3012,6 @@ poll_update(
} else {
if (peer->retry > 0)
hpoll = peer->minpoll;
- else if (!(peer->reach))
- hpoll = peer->hpoll;
else
hpoll = min(peer->ppoll, peer->hpoll);
#ifdef REFCLOCK
@@ -3072,6 +3105,10 @@ peer_clear(
peer->stratum = STRATUM_UNSPEC;
memcpy(&peer->refid, ident, 4);
#ifdef REFCLOCK
+ } else {
+ /* Clear refclock sample filter */
+ peer->procptr->codeproc = 0;
+ peer->procptr->coderecv = 0;
}
#endif
@@ -3987,7 +4024,7 @@ peer_xmit(
DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d len %zu xmt %#010x.%08x\n",
current_time,
peer->dstadr ? stoa(&peer->dstadr->sin) : "-",
- stoa(&peer->srcadr), peer->hmode, sendlen,
+ stoa(&peer->srcadr), peer->hmode, sendlen,
xmt_tx.l_ui, xmt_tx.l_uf));
return;
}
@@ -4330,7 +4367,7 @@ leap_smear_add_offs(
return;
}
-#endif /* LEAP_SMEAR */
+#endif /* LEAP_SMEAR */
/*