]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
More leapsecond table file fixes from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Wed, 27 Jun 2007 06:15:24 +0000 (02:15 -0400)
committerHarlan Stenn <stenn@ntp.org>
Wed, 27 Jun 2007 06:15:24 +0000 (02:15 -0400)
bk: 4682007cjtpYRIAInWDmt2ShnkYLJQ

ChangeLog
include/ntpd.h
ntpd/ntp_crypto.c
ntpd/ntp_proto.c
ntpd/ntp_util.c

index c2703fae805121a01c1156d153a5ca0960e1a5b0..3043d11b2269064a407b505883fb45959a52a50b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,9 @@
+* more leap second infrastructure fixes from Dave Mills.
 * [Bug 858] recent leapfile changes broke non-OpenSSL builds.
 * Use emalloc() instead of malloc() in refclock_datum.c (Calysto).
 * Start using 'design by contract' assertions.
 * [Bug 767] Fast sync to refclocks wanted.
 * Allow null driftfile.
-* leap second infrastructure fixes from Dave Mills.
 * Use YYERROR_VERBOSE for the new parser, and fix related BUILT_SOURCES.
 * [Bug 629] changes to ensure broadcast works including on wildcard addresses
 * [Bug 853] get_node() must return a pointer to maximally-aligned memory.
index 579f75b93122b5198e91628e996d4347f33efbb1..1a76d92ba42fdccf4a45accb95f985902a40c1e4 100644 (file)
@@ -183,6 +183,7 @@ extern      void    process_packet  (struct peer *, struct pkt *);
 extern void    clock_select    (void);
 extern void    kod_proto       (void);
 extern u_long  leap_ins;
+extern u_long  leap_expire;
 extern u_long  leap_sec;
 
 /*
index ef7d73fede0a204f74a9d1f958347a905377b1dc..1627d65280531ee18b5433327112175a9445c960 100644 (file)
@@ -3746,6 +3746,7 @@ crypto_tai(
        FILE    *str;           /* file handle */
        char    buf[NTP_MAXSTRLEN];     /* file line buffer */
        u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */
+       u_long  expire;         /* NTP time when file expires */
        int     offset;         /* offset at leap (s) */
        char    filename[MAXFILENAME]; /* name of leapseconds file */
        char    linkname[MAXFILENAME]; /* file link (for filestamp) */
@@ -3796,7 +3797,8 @@ crypto_tai(
         * must equal the initial insertion of ten seconds on 1 January
         * 1972 plus one second for each succeeding insertion.
         */
-       i = 0;
+       i = TAI_1972;
+       expire = 0;
        while (i < MAX_LEAP) {
                dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
                if (dp == NULL)
@@ -3805,13 +3807,19 @@ crypto_tai(
                if (strlen(buf) < 1)
                        continue;
 
-               if (*buf == '#')
-                       continue;
+               if (buf[0] == '#') {
+                       if (buf[1] == '@') {
+                               if (sscanf(&buf[2], "%lu", &expire) !=
+                                   1)
+                                       break;
+                       }
+               }
+               continue;
 
                if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2)
                        continue;
 
-               if (i != offset - TAI_1972
+               if (i != offset) 
                        break;
 
                i++;
@@ -3834,9 +3842,13 @@ crypto_tai(
        tai_leap.ptr = (u_char *)ptr;
        for (j = 0; j < i; j++)
                *ptr++ = htonl(leapsec[j]);
+       sys_tai = offset;
+       leap_ins = leapsec[--j];
+       leap_expire = expire;
        crypto_flags |= CRYPTO_FLAG_TAI;
-       sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp,
-          leapsec[--j], len);
+       sprintf(statstr,
+            "%s fs %u leap %lu tai %d expire %lu len %u", cp,
+           fstamp, leap_ins, sys_tai, leap_expire, len);
        record_crypto_stats(NULL, statstr);
 #ifdef DEBUG
        if (debug)
index a1b5f8ab083675832aeeb423e2fc54b15cd9b0f2..da17e3b1ce2f2dcd936744f5ecb541fdc65aa785 100644 (file)
@@ -67,6 +67,7 @@ double        sys_jitter;             /* system jitter (s) */
 static int sys_hopper;         /* anticlockhop counter */
 static int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */
 u_long leap_ins;               /* seconds at next leap */
+u_long leap_expire;            /* seconds leapfile expires */
 u_long leap_sec;               /* leap countdown */
 static int leap_next;          /* leap consensus */
 static int leap_sw;            /* leap is from file */
@@ -1314,9 +1315,7 @@ clock_update(void)
         * Clock was slewed. Update the system stratum, leap bits, root
         * delay, root dispersion, reference ID and reference time.
         * Except for reference clocks, the minimum dispersion increment
-        * is not less than sys_mindisp. If a leap is anticipated, read
-        * the system clock because the time now might not be the time
-        * at the last offset measurement.
+        * is not less than sys_mindisp.
         */
        case 1:
                sys_stratum = min(sys_peer->stratum + 1,
@@ -1324,49 +1323,54 @@ clock_update(void)
                sys_reftime = sys_peer->rec;
 
                /*
-                * If no leap is scheduled and the leap is triggered
-                * from the leapseconds file, schedule a leap for the
-                * last entry in the file, but only if it is in the
-                * future. If triggered by upstream server leap bits and
-                * the number of bits is at least the sanity threshold,
-                * schedule a leap for the end of the current month.
-                *
-                * If the kernel code is available and enabled, pass the
-                * current TAI offset to the kernel. Note, if the leap
-                * hasn't been taken yet, decrement the offset.
+                * If a leapseconds file is not present or expired and
+                * the number of upstream server leap bits is at least
+                * the sanity threshold, schedule a leap for the end of
+                * the current month.
                 */
                get_systime(&now);
-               if (leap_sec == 0) {
-                       if (leap_ins > now.l_ui) {
-                               if (leap_sw == 0) {
+               if (now.l_ui > leap_expire) {
+                       if (leap_next >= sys_minsane) {
+                               if (!leap_sw) {
                                        leap_sw++;
-                                       sys_tai--;
+                                       leap_sec = leap_month(now.l_ui);
                                        msyslog(LOG_NOTICE,
-                                           "TAI offset %d s", sys_tai);
-#ifdef KERNEL_PLL
-                                       if (pll_control && kern_enable)
-                                               loop_config(LOOP_LEAP,
-                                                   0);
-#endif /* KERNEL_PLL */
+                                           "leap second armed %lu s",
+                                           leap_sec);
                                }
-                               if (leap_ins - now.l_ui < 28 * 86400)
-                                       leap_sec = leap_ins - now.l_ui;
-                       } else if (leap_next >= sys_minsane) {
-                               leap_sec = leap_month(now.l_ui);
+                       } else {
+                               leap_sw = 0;
+                               leap_sec = 0;
                        }
-                       if (leap_sec > 0)
-                               msyslog(LOG_NOTICE,
-                                   "leap second armed %lu s",
-                                   leap_sec);
-                               
 
                /*
-                * If the leap was not triggered from the leapsecond
-                * file, cancel the leap if the server leap bits grow
-                * dim.
+                * If a leapseconds file is present and not expired and
+                * a future leap is scheduled, decrement the TAI offset.
+                * If the kernel code is available and enabled, pass the
+                * TAI offset to the kernel. If less than 28 days remain
+                * to the leap, schedule a leap when the leapseconds
+                * counter expires.
                 */
-               } else if (!leap_sw && leap_next < sys_minsane) {
-                       leap_sec = 0;
+               } else if (leap_sec == 0) {
+                       if (leap_ins > now.l_ui) {
+                               if (leap_ins - now.l_ui < 28 * 86400) {
+                                       leap_sec = leap_ins - now.l_ui;
+                                       msyslog(LOG_NOTICE,
+                                           "leap second armed %lu s",
+                                           leap_sec);
+                               }
+                               if (!leap_sw)
+                                       sys_tai--;
+                       }
+                       if (!leap_sw) {
+                               leap_sw++;
+                               msyslog(LOG_NOTICE,
+                                   "TAI offset %d s", sys_tai);
+#ifdef KERNEL_PLL
+                               if (pll_control && kern_enable)
+                                       loop_config(LOOP_LEAP, 0);
+#endif /* KERNEL_PLL */
+                       }
                }
 
                /*
index 397bbe2aae016441ec8e8fec36fc75664dcc7185..40d52fe26b8c8549654e7dadb191e24ed89f5187 100644 (file)
@@ -757,12 +757,14 @@ leap_file(
        FILE    *str;           /* file handle */
        char    buf[NTP_MAXSTRLEN];     /* file line buffer */
        u_long  leapsec;        /* NTP time at leap */
+       u_long  expire;         /* NTP time when file expires */
        int     offset;         /* TAI offset at leap (s) */
        char    filename[MAXFILENAME]; /* name of leapseconds file */
        char    *dp;
        int     i;
 
        NTP_REQUIRE(cp != NULL);
+
        /*
         * Open the file and discard comment lines. If the first
         * character of the file name is not '/', prepend the keys
@@ -786,6 +788,7 @@ leap_file(
         * insertion.
         */
        i = TAI_1972;
+       expire = 0;
        while (i < MAX_TAI) {
                dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
                if (dp == NULL)
@@ -794,8 +797,14 @@ leap_file(
                if (strlen(buf) < 1)
                        continue;
 
-               if (*buf == '#')
-                       continue;
+               if (buf[0] == '#') {
+                       if (buf[1] == '@') {
+                               if (sscanf(&buf[2], "%lu", &expire) !=
+                                   1)
+                                       break;
+                       }
+               }
+               continue;
 
                if (sscanf(buf, "%lu %d", &leapsec, &offset) != 2)
                        continue;
@@ -806,13 +815,14 @@ leap_file(
        }
        fclose(str);
        if (dp != NULL) {
-               msyslog(LOG_INFO, "leapseconds format error from %s",
-                   cp);
+               msyslog(LOG_INFO, "leapseconds %s error",  cp);
        } else {
                sys_tai = offset;
                leap_ins = leapsec;
-               msyslog(LOG_INFO, "TAI offset %d s at %lu from %s",
-                   sys_tai, leap_ins, cp);
+               leap_expire = expire;
+               msyslog(LOG_INFO,
+                   "TAI offset %d s at %lu file %s expire %lu",
+                   sys_tai, leap_ins, cp, leap_expire);
        }
 }