Some code in ntpd applies a dither using ntp_random. However, ntp_random (which is also used elsewhere, e.g. in getting an initial association ID) generates only positive integers, resulting in a one-sided offset bias. The following patch compensates for this bias by offsetting the return value from ntp_random to produce approximately zero mean dither in both positive and negative offset directions in the functions which use ntp_random for dither.
*** libntp/systime.c.orig Wed Dec 9 02:36:35 2009 --- libntp/systime.c Sat Nov 19 09:10:31 2011 *************** *** 62,67 **** --- 62,68 ---- ) { double dtemp; + long correction = (1L << 30) + 1L; /* compensate for ntp_random bias */ #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETCLOCK) struct timespec ts; /* seconds and nanoseconds */ *************** *** 78,86 **** now->l_i = (int32)ts.tv_sec + JAN_1970; 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.; --- 79,87 ---- now->l_i = (int32)ts.tv_sec + JAN_1970; dtemp = 0; if (sys_tick > FUZZ) ! dtemp = (ntp_random() - correction) * 2. / FRAC * sys_tick * 1e9; else if (sys_tick > 0) ! dtemp = (ntp_random() - correction) * 2. / FRAC; dtemp = (ts.tv_nsec + dtemp) * 1e-9 + sys_residual; if (dtemp >= 1.) { dtemp -= 1.; *************** *** 102,110 **** now->l_i = tv.tv_sec + JAN_1970; 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.; --- 103,111 ---- now->l_i = tv.tv_sec + JAN_1970; dtemp = 0; if (sys_tick > FUZZ) ! dtemp = (ntp_random() - correction) * 2. / FRAC * sys_tick * 1e6; else if (sys_tick > 0) ! dtemp = (ntp_random() - correction) * 2. / FRAC; dtemp = (tv.tv_usec + dtemp) * 1e-6 + sys_residual; if (dtemp >= 1.) { dtemp -= 1.; *** ntpd/ntp_io.c.orig Sat Dec 25 04:40:36 2010 --- ntpd/ntp_io.c Sat Oct 29 08:12:06 2011 *************** *** 3344,3350 **** tvp->tv_sec, tvp->tv_usec)); nts.l_i = tvp->tv_sec + JAN_1970; dtemp = (tvp->tv_usec ! + (ntp_random() * 2. / FRAC)) / 1e6; nts.l_uf = (u_int32)(dtemp * FRAC); #ifdef DEBUG_TIMING { --- 3344,3350 ---- tvp->tv_sec, tvp->tv_usec)); nts.l_i = tvp->tv_sec + JAN_1970; dtemp = (tvp->tv_usec ! + ((ntp_random() - (1L << 30) - 1) * 2. / FRAC)) / 1e6; nts.l_uf = (u_int32)(dtemp * FRAC); #ifdef DEBUG_TIMING { _______________________________________________ questions mailing list questions@lists.ntp.org http://lists.ntp.org/listinfo/questions