---
+* [Bug 2855] Implement conditional leap smear feature.
* [Bug 2778] Implement "apeers" ntpq command to include associd.
* [Bug 2805] ntpd fails to join multicast group.
* [Bug 2824] Convert update-leap to perl. (also see 2769)
extern u_long timer_timereset;
extern u_long timer_overflows;
extern u_long timer_xmtcalls;
+extern int leap_sec_in_progress;
+#ifdef LEAP_SMEAR
extern struct leap_smear_info leap_smear;
extern int leap_smear_intv;
+#endif
#ifdef SYS_WINNT
HANDLE WaitableTimerHandle;
#endif
{ "io", T_Io, FOLLBY_TOKEN },
{ "includefile", T_Includefile, FOLLBY_STRING },
{ "leapfile", T_Leapfile, FOLLBY_STRING },
+#ifdef LEAP_SMEAR
{ "leapsmearinterval", T_Leapsmearinterval, FOLLBY_TOKEN },
+#endif
{ "logconfig", T_Logconfig, FOLLBY_STRINGS_TO_EOC },
{ "logfile", T_Logfile, FOLLBY_STRING },
{ "manycastclient", T_Manycastclient, FOLLBY_STRING },
stats_config(STATS_LEAP_FILE, curr_var->value.s);
break;
+#ifdef LEAP_SMEAR
case T_Leapsmearinterval:
leap_smear_intv = curr_var->value.i;
msyslog(LOG_INFO, "config: leap smear interval %i s", leap_smear_intv);
break;
+#endif
case T_Pidfile:
stats_config(STATS_PID_FILE, curr_var->value.s);
{ CS_TIMER_XMTS, RO, "timer_xmts" }, /* 87 */
{ CS_FUZZ, RO, "fuzz" }, /* 88 */
{ CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 89 */
+#ifdef LEAP_SMEAR
{ CS_LEAPSMEARINTV, RO, "leapsmearinterval" }, /* 90 */
{ CS_LEAPSMEAROFFS, RO, "leapsmearoffset" }, /* 91 */
+#endif /* LEAP_SMEAR */
#ifdef AUTOKEY
{ CS_FLAGS, RO, "flags" }, /* 1 + CS_MAX_NOAUTOKEY */
{ CS_HOST, RO, "host" }, /* 2 + CS_MAX_NOAUTOKEY */
break;
}
+#ifdef LEAP_SMEAR
case CS_LEAPSMEARINTV:
if (leap_smear_intv > 0)
ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
ctl_putdbl(sys_var[CS_LEAPSMEAROFFS].text,
leap_smear.doffset * 1e3);
break;
+#endif /* LEAP_SMEAR */
case CS_RATE:
ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
#define IPTOS_DSCP_EF 0xb8
#endif
int qos = IPTOS_DSCP_EF; /* QoS RFC3246 */
-int leap_smear_intv; //##+++++
+
+#ifdef LEAP_SMEAR
+/* TODO burnicki: This should be moved to ntp_timer.c, but if we do so
+ * we get a linker error. Since we're running out of time before the leap
+ * second occurs, we let it here where it just works.
+ */
+int leap_smear_intv;
+#endif
/*
* NIC rule entry
};
typedef struct leap_signature leap_signature_t;
+
+#ifdef LEAP_SMEAR
+
struct leap_smear_info {
int enabled; /* not 0 if smearing is generally enabled */
int in_progress; /* not 0 if smearing is in progress, i.e. the offset has been computed */
};
typedef struct leap_smear_info leap_smear_info_t;
+#endif /* LEAP_SMEAR */
+
#define LSPROX_NOWARN 0 /* clear radar screen */
#define LSPROX_SCHEDULE 1 /* less than 1 month to target*/
l_fp sys_reftime; /* last update time */
struct peer *sys_peer; /* current peer */
+#ifdef LEAP_SMEAR
struct leap_smear_info leap_smear;
+#endif
int leap_sec_in_progress;
/*
/* always send "not sync" */
xmt_leap = LEAP_NOTINSYNC;
}
+#ifdef LEAP_SMEAR
else {
/*
* If leap smear is enabled in general we must never send a leap second warning
if (leap_smear.enabled)
xmt_leap = LEAP_NOWARNING;
}
+#endif /* LEAP_SMEAR */
}
}
}
+#ifdef LEAP_SMEAR
+
static void
leap_smear_add_offs(l_fp *t, l_fp *t_recv) {
L_ADD(t, &leap_smear.offset);
}
+#endif /* LEAP_SMEAR */
/*
* This is a normal packet. Use the system variables.
*/
} else {
+#ifdef LEAP_SMEAR
/*
* Make copies of the variables which can be affected by smearing.
*/
+ l_fp this_ref_time;
l_fp this_recv_time;
+#endif
/*
* If we are inside the leap smear interval we add the current smear offset to
*/
xpkt.li_vn_mode = PKT_LI_VN_MODE(xmt_leap,
PKT_VERSION(rpkt->li_vn_mode), xmode);
+
xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll);
xpkt.precision = sys_precision;
xpkt.refid = sys_refid;
xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp));
- /* TODO: add smear offset to reftime? */
- HTONL_FP(&sys_reftime, &xpkt.reftime);
+
+
+#ifdef LEAP_SMEAR
+ this_ref_time = sys_reftime;
+ if (leap_smear.in_progress)
+ leap_smear_add_offs(&this_ref_time, NULL);
+ HTONL_FP(&this_ref_time, &xpkt.reftime);
+#else
+ HTONL_FP(&sys_ref_time, &xpkt.reftime);
+#endif
+
xpkt.org = rpkt->xmt;
+
+#ifdef LEAP_SMEAR
this_recv_time = rbufp->recv_time;
if (leap_smear.in_progress)
leap_smear_add_offs(&this_recv_time, NULL);
HTONL_FP(&this_recv_time, &xpkt.rec);
+#else
+ HTONL_FP(&rbufp->recv_time, &xpkt.rec);
+#endif
+
get_systime(&xmt_tx);
+#ifdef LEAP_SMEAR
if (leap_smear.in_progress)
leap_smear_add_offs(&xmt_tx, &this_recv_time);
+#endif
HTONL_FP(&xmt_tx, &xpkt.xmt);
}
#define TC_ERR (-1)
#endif
-extern struct leap_smear_info leap_smear;
-extern int leap_sec_in_progress;
static void check_leapsec(u_int32, const time_t*, int/*BOOL*/);
if (sys_orphan < STRATUM_UNSPEC && sys_peer == NULL &&
current_time > orphwait) {
if (sys_leap == LEAP_NOTINSYNC) {
- sys_leap = LEAP_NOWARNING;
+ set_sys_leap(LEAP_NOWARNING);
#ifdef AUTOKEY
if (crypto_flags)
crypto_update();
if (sys_leap != LEAP_NOTINSYNC) {
if (leapsec >= LSPROX_ANNOUNCE && leapdif) {
if (leapdif > 0)
- sys_leap = LEAP_ADDSECOND;
+ set_sys_leap(LEAP_ADDSECOND);
else
- sys_leap = LEAP_DELSECOND;
+ set_sys_leap(LEAP_DELSECOND);
} else {
- sys_leap = LEAP_NOWARNING;
+ set_sys_leap(LEAP_NOWARNING);
}
}
leapsec_electric(0);
# endif
#endif
+#ifdef LEAP_SMEAR
leap_smear.enabled = leap_smear_intv != 0;
-
+#endif
if (reset) {
lsprox = LSPROX_NOWARN;
leapsec_reset_frame();
DPRINTF(1, ("*** leapsec_query: fired %i, now %u (0x%08X), tai_diff %i, ddist %u\n",
fired, now, now, lsdata.tai_diff, lsdata.ddist));
+#ifdef LEAP_SMEAR
leap_smear.in_progress = 0;
+ leap_smear.doffset = 0.0;
if (leap_smear.enabled) {
if (lsdata.tai_diff) {
* TODO see if we're inside an inserted leap second, so we need to compute
* leap_smear.doffset = 1.0 - leap_smear.doffset
*/
- DTOLFP(leap_smear.doffset, &leap_smear.offset);
leap_smear.in_progress = 1;
- DPRINTF(1, ("*** leapsec_query: [%.0f:%.0f], now %u, smear offset %.6f\n",
- leap_smear.intv_start, leap_smear.intv_end, now, leap_smear.doffset));
-#if 1 //##++++++++++++++
- msyslog(LOG_NOTICE, "*** leapsec_query: [%.0f:%.0f] (%li), now %u (%.0f), smear offset %.6f\n",
+#if 0 && defined( DEBUG )
+ msyslog(LOG_NOTICE, "*** leapsec_query: [%.0f:%.0f] (%li), now %u (%.0f), smear offset %.6f ms\n",
leap_smear.intv_start, leap_smear.intv_end, leap_smear.interval,
now, leap_smear_time, leap_smear.doffset);
+#else
+ DPRINTF(1, ("*** leapsec_query: [%.0f:%.0f] (%li), now %u (%.0f), smear offset %.6f ms\n",
+ leap_smear.intv_start, leap_smear.intv_end, leap_smear.interval,
+ now, leap_smear_time, leap_smear.doffset));
#endif
}
else
leap_smear.interval = 0;
+ /*
+ * Update the current leap smear offset, eventually 0.0 if outside smear interval.
+ */
+ DTOLFP(leap_smear.doffset, &leap_smear.offset);
+
+#endif /* LEAP_SMEAR */
+
if (fired) {
/* Full hit. Eventually step the clock, but always
* announce the leap event has happened.