# include <utmpx.h>
#endif /* HAVE_UTMPX_H */
+
+#define FUZZ 500e-6 /* fuzz pivot */
+
/*
* These routines (get_systime, step_systime, adj_systime) implement an
* interface between the system independent NTP clock and the Unix
* with an unbiased random fuzz.
*
* The sys_tick variable secifies the system clock tick interval in
- * seconds and fraction. For systems that can interpolate between timer
- * interrupts, the assumed tick interval and resolution is 1 us
- * consistent with the timeval format used by the Unix getimeofday() abd
- * adjtime() routines. With routines that use the timespec format, the
- * resolution is 1 ns. For systems that cannot interpolate, such as
- * Reliant and SCO, the resolution is as specified by the sys_tick
- * variable, which defaults to 10 ms. The default can be changed by the
- * tick configuration command.
+ * seconds. For systems that can interpolate between timer interrupts,
+ * the resolution is presumed much less than the time to read the system
+ * clock, which is the value of sys_tick after the precision has been
+ * determined. For those systems that cannot interpolate between timer
+ * interrupts, sys_tick will be much larger in the order of 10 ms, so the
+ * fuzz should be that value. For Sunses the tick is not interpolated, but
+ * the system clock is derived from a 2-MHz oscillator, so the resolution
+ * is 500 ns and sys_tick is 500 ns.
*/
-#if defined RELIANTUNIX_CLOCK || defined SCO5_CLOCK
-double sys_tick = .01; /* 10 ms resolution */
-#else
-double sys_tick = 1e-6; /* 1 us resolution */
-#endif
+double sys_tick = 0; /* precision (time to read the clock) */
double sys_residual = 0; /* adjustment residue (s) */
#ifndef SIM
getclock(TIMEOFDAY, &ts);
# endif
now->l_i = (int32)ts.tv_sec + JAN_1970;
- dtemp = ts.tv_nsec + (ntp_random() * 2. / FRAC) * sys_tick *
- 1e6;
- dtemp = dtemp / 1e9 + sys_residual;
+ dtemp = 0;
+ if (sys_tick > FUZZ)
+ dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e9;
+ else if (sys_tick > 0)
+ dtemp = ntp_random() * 2. / FRAC;
+ dtemp = (ts.tv_nsec + dtemp) * 1e-9 + sys_residual;
if (dtemp >= 1.) {
dtemp -= 1.;
now->l_i++;
*/
GETTIMEOFDAY(&tv, NULL);
now->l_i = tv.tv_sec + JAN_1970;
- dtemp = tv.tv_usec + (ntp_random() * 2. / FRAC) * sys_tick *
- 1e6;
- dtemp = dtemp / 1e6 + sys_residual;
+ dtemp = 0;
+ if (sys_tick > FUZZ)
+ dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e6;
+ else if (sys_tick > 0)
+ dtemp = ntp_random() * 2. / FRAC;
+ dtemp = (tv.tv_usec + dtemp) * 1e-6 + sys_residual;
if (dtemp >= 1.) {
dtemp -= 1.;
now->l_i++;
#include "ntp_refclock.h"
#endif
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <sys/sysctl.h>
-#endif
-
/*
* This macro defines the authentication state. If x is 1 authentication
* is required; othewise it is optional.
int sys_authenticate; /* requre authentication for config */
l_fp sys_authdelay; /* authentication delay */
double sys_offset; /* current local clock offset */
-double sys_mindisp = MINDISPERSE; /* min disp increment (s) */
+double sys_mindisp = MINDISPERSE; /* minimum distance (s) */
double sys_maxdist = MAXDISTANCE; /* selection threshold */
double sys_jitter; /* system jitter */
u_long sys_epoch; /* last clock update time */
return; /* not enabled */
}
if ((peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr,
- MODE_CLIENT, hisversion, NTP_MINDPOLL,
- NTP_MAXDPOLL, FLAG_IBURST | FLAG_PREEMPT,
- MDF_UCAST | MDF_ACLNT, 0, skeyid)) == NULL) {
+ MODE_CLIENT, hisversion, NTP_MINDPOLL, NTP_MAXDPOLL,
+ FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT, 0, skeyid)) ==
+ NULL) {
sys_declined++;
return; /* ignore duplicate */
}
/*
* We don't need these, but it warms the billboards.
*/
- peer->ttl = peer2->ttl;
+ if (peer2->flags & FLAG_IBURST)
+ peer->flags |= FLAG_IBURST;
+ peer->minpoll = peer2->minpoll;
+ peer->maxpoll = peer2->maxpoll;
break;
/*
/*
* If authenticated but cannot mobilize an
- * association, send a summetric passive
+ * association, send a symmetric passive
* response without mobilizing an association.
* This is for drat broken Windows clients. See
* Microsoft KB 875424 for preferred workaround.
sys_refid = addr2refid(&peer->srcadr);
dtemp = sys_jitter + fabs(sys_offset) + peer->disp + clock_phi *
(current_time - peer->update);
-#ifdef REFCLOCK
- if (!(peer->flags & FLAG_REFCLOCK) && sys_rootdisp <
- sys_mindisp)
- dtemp = sys_mindisp;
-#else
- if (sys_rootdisp < sys_mindisp)
- dtemp = sys_mindisp;
-#endif /* REFCLOCK */
sys_rootdisp = dtemp + peer->rootdisp;
sys_rootdelay = peer->delay + peer->rootdelay;
sys_reftime = peer->dst;
break;
/*
- * 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.
+ * Clock was slewed. Handle the leapsecond stuff.
*/
case 1:
* least one kitten in the litter.
*/
if (nlist > 0 && nlist >= sys_minsane) {
- if (synch[j] < synch[0] + sys_mindisp +
- ULOGTOD(sys_poll) * sys_maxhop * clock_phi)
+ if (synch[j] < synch[0] + ULOGTOD(sys_poll) *
+ sys_maxhop * clock_phi)
typesystem = peer_list[j];
else
typesystem = peer_list[0];
struct peer *peer /* peer structure pointer */
)
{
+ double dtemp;
/*
* Careful squeak here. The value returned must be greater than
* cannot exceed the sys_maxdist, as this is the cutoff by the
* selection algorithm.
*/
- return ((peer->delay + peer->rootdelay) / 2 + peer->disp +
+ dtemp = (peer->delay + peer->rootdelay) / 2 + peer->disp +
peer->rootdisp + clock_phi * (current_time - peer->update) +
- peer->jitter);
+ peer->jitter;
+ if (dtemp < sys_mindisp)
+ dtemp = sys_mindisp;
+ return (dtemp);
}
if (++i >= MINLOOPS)
break;
}
+ sys_tick = tick;
/*
* Find the nearest power of two.
*/
- msyslog(LOG_NOTICE, "proto: precision = %.3f usec", tick * 1e6);
+ msyslog(LOG_NOTICE, "proto: precision = %.3f usec", tick * 1e6);
for (i = 0; tick <= 1; i++)
tick *= 2;
- if (tick - 1. > 1. - tick / 2)
+ if (tick - 1 > 1 - tick / 2)
i--;
return (-i);
}
sys_minclock = (int)dvalue;
break;
- case PROTO_MINDISP: /* distance increment (mindist) */
+ case PROTO_MINDISP: /* minimum distance (mindist) */
sys_mindisp = dvalue;
break;