From: Martin Burnicki Date: Mon, 22 Jun 2015 15:31:28 +0000 (+0200) Subject: [Bug 2855] Implement conditional leap smear feature. X-Git-Tag: NTP_4_2_8P3_RC2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d676990eeb0066eca05eb4608844599c5691e76;p=thirdparty%2Fntp.git [Bug 2855] Implement conditional leap smear feature. bk: 55882a50y_edrkRBbvER7rUd8WIXvw --- diff --git a/ChangeLog b/ChangeLog index 6035eda17..44ef79657 100644 --- 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) diff --git a/include/ntpd.h b/include/ntpd.h index c30b80624..be3cd3e76 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -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 diff --git a/ntpd/keyword-gen.c b/ntpd/keyword-gen.c index 42e94973f..ef1c6b018 100644 --- a/ntpd/keyword-gen.c +++ b/ntpd/keyword-gen.c @@ -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 }, diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index c760e6a59..300773240 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -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); diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 72a365792..9adee7471 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -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); diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index bfe8405b7..a93733f82 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -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 diff --git a/ntpd/ntp_leapsec.h b/ntpd/ntp_leapsec.h index affe627e0..120b75fcb 100644 --- a/ntpd/ntp_leapsec.h +++ b/ntpd/ntp_leapsec.h @@ -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*/ diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 107573cc9..c3ae034d3 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -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); } diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index e211f224f..5cbb892e3 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -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.