extern int sys_ceiling; /* cluster stratum ceiling */
extern u_char sys_ttl[]; /* ttl mapping vector */
extern int sys_ttlmax; /* max ttl mapping vector index */
-extern int leap_next; /* leap consensus */
/*
* Statistics counters
u_long sys_clocktime; /* last system clock update */
u_long pps_control; /* last pps update */
u_int sys_tai; /* TAI offset from UTC (s) */
-u_long sys_leapin; /* seconds at next leap (s) */
static void rstclock (int, u_long, double); /* transition function */
#ifdef KERNEL_PLL
if (ext_enable) {
ntv.modes = MOD_STATUS;
} else {
- struct tm *tm = NULL;
- time_t tstamp;
-
#ifdef STA_NANO
ntv.modes = MOD_BITS | MOD_NANO;
#else /* STA_NANO */
sys_rootdispersion) * 1e6);
ntv.status = STA_PLL;
- /*
- * Set the leap bits in the status word, but
- * only on the last day of June or December.
- */
- tstamp = peer->rec.l_ui - JAN_1970;
- tm = gmtime(&tstamp);
- if (tm != NULL) {
- if ((tm->tm_mon + 1 == 6 &&
- tm->tm_mday == 30) || (tm->tm_mon +
- 1 == 12 && tm->tm_mday == 31)) {
- if (leap_next & LEAP_ADDSECOND)
- ntv.status |= STA_INS;
- else if (leap_next &
- LEAP_DELSECOND)
- ntv.status |= STA_DEL;
- }
- }
-
/*
* If the PPS signal is up and enabled, light
* the frequency bit. If the PPS driver is
ntv.status &= ~(STA_PPSFREQ |
STA_PPSTIME);
}
+
+ /*
+ * If less than 23 hours remain before a leap,
+ * set the kernel leap bits.
+ */
+ if (leap_sec > 0 && leap_sec < 23 * 3600) {
+ if (sys_leap == LEAP_ADDSECOND)
+ ntv.status |= STA_INS;
+ else if (sys_leap == LEAP_DELSECOND)
+ ntv.status |= STA_DEL;
+ }
}
/*
clock_codec = freq;
break;
- case LOOP_LEAP: /* arm leap insert */
+ case LOOP_LEAP: /* set kernel TAI offset */
#if defined(STA_NANO) && NTP_API == 4
if (pll_control && kern_enable) {
- memset(&ntv, 0, sizeof(ntv));
ntv.modes = MOD_TAI;
- ntv.constant = sys_tai - 1;
+ ntv.constant = sys_tai;
ntp_adjtime(&ntv);
}
#endif /* STA_NANO */
double sys_jitter; /* system jitter (s) */
static int sys_hopper; /* anticlockhop counter */
static int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */
-int leap_next; /* leap consensus */
-u_long leap_ins; /* seconds ar next leap */
+u_long leap_ins; /* seconds at next leap */
u_long leap_sec; /* leap countdown */
+static int leap_next; /* leap consensus */
+static int leap_sw; /* leap is from file */
keyid_t sys_private; /* private value for session seed */
int sys_manycastserver; /* respond to manycast client pkts */
int peer_ntpdate; /* active peers in ntpdate mode */
* at the last offset measurement.
*/
case 1:
-
sys_stratum = min(sys_peer->stratum + 1,
STRATUM_UNSPEC);
sys_reftime = sys_peer->rec;
- get_systime(&now);
/*
- * If no leap is scheduled and the number of upstream
- * leap bits is at least the sanity threshold, schedule
- * a leap for the end of the current month. If from the
- * leapseconds file schedule a leap for the last entry
- * in the file, but only if it is in the future.
+ * 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.
*/
+ get_systime(&now);
if (leap_sec == 0) {
- if (leap_next >= sys_minsane) {
- leap_sec = leap_month(now.l_ui);
- } else if (leap_ins != 0) {
- if (now.l_ui < leap_ins) {
- leap_sec = leap_ins - now.l_ui;
+ if (leap_ins > now.l_ui) {
+ if (leap_sw == 0) {
+ leap_sw++;
sys_tai--;
+ loop_config(LOOP_LEAP, sys_tai);
}
+ 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);
}
+ 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.
+ */
+ } else if (!leap_sw && leap_next < sys_minsane) {
+ leap_sec = 0;
}
+printf("xxx %d %d %d %d %d %lu\n", sys_leap, sys_tai, leap_sw, sys_minsane, leap_next, leap_sec);
+
+ /*
+ * If this is the first time the clock is set,
+ * reset the leap bits.
+ */
+ if (sys_leap == LEAP_NOTINSYNC)
+ sys_leap = LEAP_NOWARNING;
+
/*
* In orphan mode the stratum defaults to the orphan
* stratum. The root delay is set to a random value
if (peer->pkey != NULL)
EVP_PKEY_free(peer->pkey);
peer->pkey = NULL;
-
- peer->digest = NULL; /* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */
-
+ peer->digest = NULL; /* digest * is a constant */
if (peer->subject != NULL)
free(peer->subject);
peer->subject = NULL;
*/
sys_leap = LEAP_NOTINSYNC;
sys_stratum = STRATUM_UNSPEC;
+ sys_peer = NULL;
+ sys_rootdelay = 0;
+ sys_rootdispersion = 0;
memcpy(&sys_refid, "INIT", 4);
sys_precision = (s_char)default_get_precision();
sys_jitter = LOGTOD(sys_precision);
- sys_rootdelay = 0;
sys_orphandelay = (double)(ntp_random() & 0xffff) / 65536. *
sys_maxdist;
- sys_rootdispersion = 0;
L_CLR(&sys_reftime);
sys_peer = NULL;
sys_survivors = 0;
volatile u_long alarm_overflow;
#define MINUTE 60
-#define HOUR (60*60)
+#define HOUR (60 * 60)
-u_long current_time;
+u_long current_time; /* seconds since startup */
+static int tai_sw; /* kernel TAI switch */
/*
* Stats. Number of overflows and number of calls to transmit().
* Leapseconds.
*/
if (leap_sec > 0) {
- if (leap_sec < 86400 * 28)
- sys_leap = LEAP_ADDSECOND;
- if (leap_sec < 86400)
- loop_config(LOOP_LEAP, sys_tai);
+ sys_leap = LEAP_ADDSECOND;
leap_sec--;
- } else {
- sys_leap = LEAP_NOWARNING;
+ if (leap_sec == 0) {
+ sys_leap = LEAP_NOWARNING;
+ if (sys_tai > 0) {
+ sys_tai++;
+ msyslog(LOG_NOTICE, "TAI offset %d s",
+ sys_tai);
+ }
+ }
}
/*
# include <descrip.h>
#endif /* VMS */
-#define MAX_LEAP 100 /* max TAI offset (s) */
-
/*
- * This contains odds and ends. Right now the only thing you'll find
- * in here is the hourly stats printer and some code to support
- * rereading the keys file, but I may eventually put other things in
- * here such as code to do something with the leap bits.
+ * Defines used by the leapseconds stuff
*/
+#define MAX_TAI 100 /* max TAI offset (s) */
+#define L_DAY 86400UL /* seconds per day */
+#define L_YEAR (L_DAY * 365) /* days per year */
+#define L_LYEAR (L_YEAR + L_DAY) /* days per leap year */
+#define L_4YEAR (L_LYEAR + 3 * L_YEAR) /* days per leap cycle */
+#define L_CENT (L_4YEAR * 25) /* days per century */
+
/*
- * Name of the keys file
+ * This contains odds and ends, including the hourly stats, various
+ * configuration items, leapseconds stuff, etc.
*/
-static char *key_file_name;
-
/*
- * The name of the drift_comp file and the temporary.
+ * File names
*/
-static char *stats_drift_file;
-static char *stats_temp_file;
-int stats_write_period = 3600; /* # of seconds between writes. */
-static double prev_drift_comp;
+static char *key_file_name; /* keys file name */
+static char *stats_drift_file; /* frequency file name */
+static char *stats_temp_file; /* temp frequency file name */
+int stats_write_period = 3600; /* seconds between writes. */
/*
* Statistics file stuff
# define MAXPATHLEN 256
#endif
-static char statsdir[MAXPATHLEN] = NTP_VAR;
-
-static FILEGEN peerstats;
-static FILEGEN loopstats;
-static FILEGEN clockstats;
-static FILEGEN rawstats;
-static FILEGEN sysstats;
#ifdef DEBUG_TIMING
static FILEGEN timingstats;
#endif
static FILEGEN cryptostats;
#endif /* OPENSSL */
+static char statsdir[MAXPATHLEN] = NTP_VAR;
+static FILEGEN peerstats;
+static FILEGEN loopstats;
+static FILEGEN clockstats;
+static FILEGEN rawstats;
+static FILEGEN sysstats;
+
/*
* This controls whether stats are written to the fileset. Provided
* so that ntpdc can turn off stats when the file system fills up.
/*
* Initial frequency offset later passed to the loopfilter.
*/
-double old_drift;
+double old_drift; /* current frequency */
+static double prev_drift_comp; /* last frequency update */
+/*
+ * Static prototypes
+ */
static void leap_file(char *);
/*
#ifdef DEBUG_TIMING
filegen_register(&statsdir[0], "timingstats", &timingstats);
#endif
+
+leap_file("/etc/leapseconds"); /***** temp for debug *****/
+
}
* insertion.
*/
i = TAI_1972;
- while (i < MAX_LEAP) {
+ while (i < MAX_TAI) {
dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
if (dp == NULL)
break;
}
fclose(str);
if (dp != NULL) {
- msyslog(LOG_INFO, "Leapseconds format error in %s", cp);
+ msyslog(LOG_INFO, "leapseconds format error from %s",
+ cp);
} else {
sys_tai = offset;
leap_ins = leapsec;
}
}
+
/*
- * leap_month - returns the number of seconds until the end of the month
+ * leap_month - returns seconds until the end of the month.
*/
-#define L_DAY 86400 /* seconds per day */
-#define L_YEAR L_DAY * 365 /* days per year */
-#define L_LYEAR L_YEAR + 1 /* days per leap year */
-#define L_4YEAR L_LYEAR + 3 * L_YEAR /* days per leap cycle */
-#define L_CENT (u_long)L_4YEAR * 25 /* days per century */
-
u_long
leap_month(
u_long sec /* current NTP second */
31};
/*
- * Find current leap cycle
+ * Find current leap cycle.
*/
ltemp = sec;
- while (ltemp > L_CENT)
+ while (ltemp >= L_CENT)
ltemp -= L_CENT;
- while (ltemp > L_4YEAR)
+ while (ltemp >= L_4YEAR)
ltemp -= L_4YEAR;
/*
- * If in leap year, use leap table
+ * We are within four years of the target. If in leap year, use
+ * leap year month table; otherwise, use year month table.
*/
if (ltemp < L_LYEAR) {
ptr = lyear;
} else {
ptr = year;
ltemp -= L_LYEAR;
- while (ltemp > L_YEAR)
+ while (ltemp >= L_YEAR)
ltemp -= L_YEAR;
}
- while (ltemp > *ptr)
- ltemp -= *ptr++;
- /* The result is the number of seconds until the end of the
+ /*
+ * We are within one year of the target. Find the month of the
+ * leap.
+ */
+ while (ltemp >= *ptr * L_DAY)
+ ltemp -= *ptr++ * L_DAY;
+
+ /*
+ * The result is the number of seconds until the end of the
* month when the leap is to occur.
*/
- return (ltemp);
+ return (*ptr * L_DAY - ltemp - L_DAY);
}