aboutsummaryrefslogtreecommitdiffstats
path: root/ntpd/ntp_proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_proto.c')
-rw-r--r--ntpd/ntp_proto.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c
index 33e97ef9d989..cde5a30852dd 100644
--- a/ntpd/ntp_proto.c
+++ b/ntpd/ntp_proto.c
@@ -1333,9 +1333,10 @@ receive(
* manycaster has already synchronized to us.
*/
if ( sys_leap == LEAP_NOTINSYNC
- || sys_stratum >= hisstratum
+ || sys_stratum > hisstratum + 1
|| (!sys_cohort && sys_stratum == hisstratum + 1)
|| rbufp->dstadr->addr_refid == pkt->refid) {
+ DPRINTF(2, ("receive: sys leap: %0x, sys_stratum %d > hisstratum+1 %d, !sys_cohort %d && sys_stratum == hisstratum+1, loop refid %#x == pkt refid %#x\n", sys_leap, sys_stratum, hisstratum + 1, !sys_cohort, rbufp->dstadr->addr_refid, pkt->refid));
DPRINTF(2, ("receive: AM_FXMIT drop: LEAP_NOTINSYNC || stratum || loop\n"));
sys_declined++;
return; /* no help */
@@ -1681,8 +1682,9 @@ receive(
* MODE_ACTIVE KoDs, which will time out eventually.
*/
if ( hisleap != LEAP_NOTINSYNC
- && (hisstratum < sys_floor || hisstratum >= sys_ceiling)) {
- DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n"));
+ && (hisstratum < sys_floor || hisstratum >= sys_ceiling)) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: Remote stratum (%d) out of range\n",
+ hisstratum));
sys_declined++;
return; /* no help */
}
@@ -2485,10 +2487,6 @@ process_packet(
double etemp, ftemp, td;
#endif /* ASSYM */
-#if 0
- sys_processed++;
- peer->processed++;
-#endif
p_del = FPTOD(NTOHS_FP(pkt->rootdelay));
p_offset = 0;
p_disp = FPTOD(NTOHS_FP(pkt->rootdisp));
@@ -2501,10 +2499,6 @@ process_packet(
pversion = PKT_VERSION(pkt->li_vn_mode);
pstratum = PKT_TO_STRATUM(pkt->stratum);
- /**/
-
- /**/
-
/*
* Verify the server is synchronized; that is, the leap bits,
* stratum and root distance are valid.
@@ -2524,19 +2518,15 @@ process_packet(
peer->seldisptoolarge++;
DPRINTF(1, ("packet: flash header %04x\n",
peer->flash));
-
- /* ppoll updated? */
- /* XXX: Fuzz the poll? */
- poll_update(peer, peer->hpoll, (peer->hmode == MODE_CLIENT));
+ /* [Bug 3592] do *not* update poll on bad packets! */
return;
}
- /**/
-
-#if 1
+ /*
+ * update stats, now that we really handle this packet:
+ */
sys_processed++;
peer->processed++;
-#endif
/*
* Capture the header values in the client/peer association..
@@ -2571,9 +2561,6 @@ process_packet(
if (peer->burst > 0)
peer->nextdate = current_time;
}
- poll_update(peer, peer->hpoll, (peer->hmode == MODE_CLIENT));
-
- /**/
/*
* If the peer was previously unreachable, raise a trap. In any
@@ -3455,11 +3442,13 @@ clock_select(void)
double d, e, f, g;
double high, low;
double speermet;
+ double lastresort_dist = MAXDISPERSE;
double orphmet = 2.0 * U_INT32_MAX; /* 2x is greater than */
struct endpoint endp;
struct peer *osys_peer;
struct peer *sys_prefer = NULL; /* prefer peer */
struct peer *typesystem = NULL;
+ struct peer *typelastresort = NULL;
struct peer *typeorphan = NULL;
#ifdef REFCLOCK
struct peer *typeacts = NULL;
@@ -3524,6 +3513,22 @@ clock_select(void)
}
/*
+ * If we have never been synchronised, look for any peer
+ * which has ever been synchronised and pick the one which
+ * has the lowest root distance. This can be used as a last
+ * resort if all else fails. Once we get an initial sync
+ * with this peer, sys_reftime gets set and so this
+ * function becomes disabled.
+ */
+ if (L_ISZERO(&sys_reftime)) {
+ d = root_distance(peer);
+ if (!L_ISZERO(&peer->reftime) && d < lastresort_dist) {
+ typelastresort = peer;
+ lastresort_dist = d;
+ }
+ }
+
+ /*
* If this peer is an orphan parent, elect the
* one with the lowest metric defined as the
* IPv4 address or the first 64 bits of the
@@ -3756,6 +3761,9 @@ clock_select(void)
if (typeorphan != NULL) {
peers[0].peer = typeorphan;
nlist = 1;
+ } else if (typelastresort != NULL) {
+ peers[0].peer = typelastresort;
+ nlist = 1;
}
}
@@ -3949,8 +3957,7 @@ clock_select(void)
*/
if (typesystem == NULL) {
if (osys_peer != NULL) {
- if (sys_orphwait > 0)
- orphwait = current_time + sys_orphwait;
+ orphwait = current_time + sys_orphwait;
report_event(EVNT_NOPEER, NULL, NULL);
}
sys_peer = NULL;
@@ -5344,7 +5351,7 @@ proto_config(
case PROTO_ORPHWAIT: /* orphan wait (orphwait) */
orphwait -= sys_orphwait;
- sys_orphwait = (int)dvalue;
+ sys_orphwait = (dvalue >= 1) ? (int)dvalue : NTP_ORPHWAIT;
orphwait += sys_orphwait;
break;