]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2855] Implement conditional leap smear feature.
authorMartin Burnicki <burnicki@ntp.org>
Mon, 22 Jun 2015 15:31:28 +0000 (17:31 +0200)
committerMartin Burnicki <burnicki@ntp.org>
Mon, 22 Jun 2015 15:31:28 +0000 (17:31 +0200)
bk: 55882a50y_edrkRBbvER7rUd8WIXvw

ChangeLog
include/ntpd.h
ntpd/keyword-gen.c
ntpd/ntp_config.c
ntpd/ntp_control.c
ntpd/ntp_io.c
ntpd/ntp_leapsec.h
ntpd/ntp_proto.c
ntpd/ntp_timer.c

index 6035eda17629fab7fcedd08da77b3810b6f9e8a3..44ef7965748c744a091be724182e0682ef05f401 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 ---
 
+* [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)
index c30b806247646229bc33fead959b483feaf24a4a..be3cd3e7619b0f71ad891675a280ee4b893d4b0e 100644 (file)
@@ -534,8 +534,11 @@ extern u_long      current_time;           /* seconds since startup */
 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
index 42e94973f81eecd1da724ce0d1852385d131f907..ef1c6b018fab51d015142d10df63e402ca6b1170 100644 (file)
@@ -54,7 +54,9 @@ struct key_tok ntp_keywords[] = {
 { "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 },
index c760e6a59d11871f7e2b0835e8c7bcb5513e6020..300773240c74be5cd745296af094f72e4e318e97 100644 (file)
@@ -3511,10 +3511,12 @@ config_vars(
                        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);
index 72a365792a6a0eeaa95e5b6ed5f324a923ef2c6a..9adee7471d962ce097d00d4780bb39c8ca77f6bd 100644 (file)
@@ -419,8 +419,10 @@ static const struct ctl_var sys_var[] = {
        { 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 */
@@ -1978,6 +1980,7 @@ ctl_putsys(
                break;
        }
 
+#ifdef LEAP_SMEAR
        case CS_LEAPSMEARINTV:
                if (leap_smear_intv > 0)
                        ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
@@ -1988,6 +1991,7 @@ ctl_putsys(
                        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);
index bfe8405b78b85124f14469cf51f7f5831657acee..a93733f824a26944dd69a8e016fb036da118db9d 100644 (file)
@@ -77,7 +77,14 @@ extern int listen_to_virtual_ips;
 #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
index affe627e0cb1403c561c7cadaf1a359a533342cd..120b75fcbb3f144331ee881abc25070d1fa7896a 100644 (file)
@@ -119,6 +119,9 @@ struct leap_signature {
 };
 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 */
@@ -132,6 +135,8 @@ struct leap_smear_info {
 };
 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*/
index 107573cc97b2d2f0ba77882a3e6314abe807e965..c3ae034d378293533cc9fe6ab221e633f54d9af3 100644 (file)
@@ -71,7 +71,9 @@ u_int32 sys_refid;            /* reference id (network byte order) */
 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;
 
 /*
@@ -169,6 +171,7 @@ set_sys_leap(u_char new_sys_leap) {
                        /* 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
@@ -177,6 +180,7 @@ set_sys_leap(u_char new_sys_leap) {
                        if (leap_smear.enabled)
                                xmt_leap = LEAP_NOWARNING;
                }
+#endif /* LEAP_SMEAR */
        }
 }
 
@@ -3436,11 +3440,14 @@ peer_xmit(
 }
 
 
+#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 */
 
 
 /*
@@ -3504,10 +3511,13 @@ fast_xmit(
         * 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
@@ -3516,22 +3526,40 @@ fast_xmit(
                 */
                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);
        }
 
index e211f224fa0aeee2b3a266b8b8d5e8b100f3c7ad..5cbb892e3ddd2a3e638f4caa710272a1f7e5cd66 100644 (file)
@@ -41,8 +41,6 @@
 #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*/);
 
@@ -344,7 +342,7 @@ timer(void)
        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();
@@ -373,11 +371,11 @@ timer(void)
         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);
                 }
        }
 
@@ -542,8 +540,9 @@ check_leapsec(
        leapsec_electric(0);
 # endif
 #endif
+#ifdef LEAP_SMEAR
        leap_smear.enabled = leap_smear_intv != 0;
-
+#endif
        if (reset)      {
                lsprox = LSPROX_NOWARN;
                leapsec_reset_frame();
@@ -554,7 +553,9 @@ check_leapsec(
          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) {
@@ -590,14 +591,15 @@ check_leapsec(
                                 * 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
 
                        }
@@ -606,6 +608,13 @@ check_leapsec(
          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.