Fix a serious bug in the NTPD loopfilter. Basically what happens is that
authorMatthew Dillon <dillon@dragonflybsd.org>
Mon, 26 Jan 2004 20:58:11 +0000 (20:58 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Mon, 26 Jan 2004 20:58:11 +0000 (20:58 +0000)
commit07de9e16af8e520334766cd1b62346a24623d40e
treebc5f2962e454d16813db7eeaa58573287568dd85
parenta1e33b0fbfac2bb407b674f01f0e784822be1870
Fix a serious bug in the NTPD loopfilter.  Basically what happens is that
when the frequency error is low (e.g. like 15ppm), but an offset correction
must be made (e.g. like 3 seconds), the rstclock() call loopfilter makes
in the S_NSET state, after adjusting the system time, will reload a
clock_offset value PRIOR to the system time adjustment actually having taken
place, because rstclock() uses offset information prior to the time step, not
after, and because the kernel may slew the time step over several seconds.

The result is that clock_offset will wind up being very high (e.g. like 3
seconds) as the loopfilter enters into the S_FREQ state.  This will cause
the loopfilter to make a wildly incorrect clock_frequency calculation and
in my tests it can take ntpd and the kernel upwards of one to two DAYS to
correct for the bad calculation.

The fix is to introduce an offset settling state, S_PFREQ, which resets
the offset calculations CLOCK_MINSEC seconds after the correction was made
in order to give the next state, S_FREQ, a good basis for calculating the
frequency drift.  clock_offset will be far more reasonable when the S_FREQ
state is entered, a good clock_frequency calculation will be made, and
ntpd will lock onto the frequency is less then half an hour (instead of
24+ hours).
contrib/ntp/ntpd/ntp_loopfilter.c