# [ntp:questions] Poul-Henning Kamp and re-write of NTP

David Woolley david at ex.djwhome.demon.invalid
Mon Dec 8 09:46:19 UTC 2014

```On 08/12/14 04:08, Paul wrote:
> I asked before but I'll try again since "tsc" has come up.
>
> Mills says (Mitigation Rules and the prefer Keyword):
> "The clock combine algorithm uses the survivor list to produce a weighted
> average of both offset and jitter. Absent other considerations discussed
> later, the *combined offset* is used to discipline the system clock"
>
> phk says (20141107 - Probably Noon):
> "In classical NTPD we always pick one server at a time, and steer our clock
> only with the measurements from that server."
>
> So which of these is correct?  Or does "classical NTPD" refer to an 18th
> century version?  I know other people make the same assertion but I fail to
> understand what they mean.
>

The last time I looked at a moderately recent version of the source
code, it used a weighted average.

There is a lot of confusion in the community about this because of the
concept of a system peer, and simplistic explanations of what this
means.  Many people assume that that must be the only source of time,
whereas, in the default case at least, it is only the source of the
performance statistics like stratum and root distance.

I am pretty certain this has been the case for over a decade (i.e. both
version 3 and 4), with only, possibly, the choice of weights changing.

The clock combine code is really quite small, so this is it from
4.2.7p333 (ntp_proto.c):

static void
clock_combine(
peer_select *	peers,	/* survivor list */
int		npeers,	/* number of survivors */
int		syspeer	/* index of sys.peer */
)
{
int	i;
double	x, y, z, w;

y = z = w = 0;
for (i = 0; i < npeers; i++) {
x = 1. / peers[i].synch;
y += x;
z += x * peers[i].peer->offset;
w += x * DIFF(peers[i].peer->offset,
peers[syspeer].peer->offset);
}
sys_offset = z / y;
sys_jitter = SQRT(w / y + SQUARE(peers[syspeer].seljit));
}

It is basically weighting the offsets by the reciprocal of the error
bound for the source.  The exception is that, specifying a prefer peer
(and you are only supposed to specify one such) will disable this and
use only one peer as the time source:

if (sys_prefer == NULL) {
typesystem->new_status = CTL_PST_SEL_SYSPEER;
clock_combine(peers, sys_survivors, speer);
} else {

I didn't follow the code back far enough to find out which source is
used if the prefer peer is unreachable.

[Note: your news client failed to add a References header.]

```