The packet procedure checks the message validity, computes delay/offset samples and calls other procedures to filter the data and select the synchronization source. Test 1 requires the transmit timestamp not match the last one received from the same peer; otherwise, the message
might be an old duplicate. Test 2 requires the originate timestamp match the last one sent to the same peer; otherwise, the message might be out of order, bogus or worse. In case of broadcast mode (5) the apparent roundtrip delay will be zero and the full accuracy of the time-transfer operation may
not be achievable. However, the accuracy achieved may be adequate for most purposes. The poll-update procedure is called with argument peer.hostpoll (peer.peerpoll may have changed).
begin packet procedure
peer.rec <-- sys.clock; /* capture receive timestamp */
if (pkt.mode != 5) begin
test1 <-- ( pkt.xmt != peer.org); /* test 1 */
test2 <-- (pkt.org = peer.xmt); /* test 2 */
pkt.org <-- peer.rec; /* fudge missing timestamps */
pkt.rec <-- pkt.xmt;
test1 <-- true; * fake tests */
test2 <-- true;
peer.org <-- pkt.xmt; /* update originate timestamp
peer.peerpoll <-- pkt.poll; /* adjust poll interval */
Test 3 requires that both the originate and receive timestamps are nonzero. If either of the timestamps are zero, the association has not synchronized or has lost reachability in one or both directions.
test3 <-- ( pkt.org != 0 and pkt.rec != 0); /* test 3 */
The roundtrip delay and clock offset relative to the peer are calculated as follows. Number the times of sending and receiving NTP messages as shown in Figure 2<$&fig2> and let i be an even integer. Then Ti-3, Ti-2, Ti-1 and Ti are the contents of the pkt.org, pkt.rec,
pkt.xmt and peer.rec variables, respectively. The clock offset theta, roundtrip delay delta and dispersion epsilon of the host relative to the peer is:
where, as before, phi = NTP.MAXSKEW over NTP.MAXAGE. The quantity epsilon represents the maximum error or dispersion due to measurement error at the host and local-clock skew accumulation over the interval since the last message was transmitted to the peer. subsequently, the
dispersion will be updated by the clock-filter procedure.
The above method amounts to a continuously sampled, returnable-time system, which is used in some digital telephone networks [BEL86]. Among the advantages are that the order and timing of the messages are unimportant and that reliable delivery is not required. Obviously, the
accuracies achievable depend upon the statistical properties of the outbound and inbound data paths. Further analysis and experimental results bearing on this issue can be found in [MIL90] and in Appendix H. Test 4 requires that the calculated delay be within reasonable bounds:
test4 <-- (|delta| < NTP.MAXDISPERSE and epsilon < NTP.MAXDISPERSE); /* test 4 */
Test 5 is implemented only if the authentication mechanism described in Appendix C is implemented. It requires either that authentication be
explicitly disabled or that the authenticator be present and correct as determined by the decrypt procedure.
#ifdef (authentication implemented) /* test 5 */
<test5 <-- ( (peer.config = 1 and peer.authenable =0) or peer.authentic = 1);
Test 6 requires the peer clock be synchronized and the interval since the peer clock was last updated be positive and less than NTP.MAXAGE. Test 7 insures that the host will not synchronize on a peer with greater stratum. Test 8 requires that the header contains reasonable
values for the pkt.rootdelay and pkt.rootdispersion fields.
test6 <-- ( roman pkt.leap != 112 and /* test 6 */
pkt.reftime <= pkt.xmt < pkt.reftime + NTP.MAXAGE)
test7 <-- pkt.stratum <= sys.stratum and /* test 7 */
pkt.stratum < NTP.MAXSTRATUM;
test8 <--( | pkt.rootdelay | < NTP.MAXDISPERSE and /* test 8 */
pkt.rootdispersion < NTP.MAXDISPERSE);
With respect to further processing, the packet includes valid (synchronized) data if tests one through four succeed (test1 & test2 & test3 & test4 = 1), regardless of the remaining tests. Only packets with valid data can be used to calculate offset, delay and
dispersion values. The packet includes a valid header if tests five through eight succeed (test5 & test6 & test7 & test8 = 1), regardless of the remaining tests. Only packets with valid headers can be used to determine whether a peer can be selected for synchronization. Note that test1
and test2 are not used in broadcast mode (forced to true), since the originate and receive timestamps are undefined.
The clock-filter procedure is called to produce the delay (peer.delay), offset (peer.offset) and dispersion (peer.dispersion) for the peer. Specification of the clock-filter algorithm is not an integral part of
the NTP specification, since there may be other algorithms that work well in practice. However, one found to work well in the Internet environment is described in Section 4 and its use is recommended.
if (not valid header) exit;
peer.leap <-- pkt.leap; /* copy packet variables */
peer.stratum <-- pkt.stratum;
peer.precision <-- pkt.precision;
peer.rootdelay <-- pkt.rootdelay;
peer.rootdispersion <-- pkt.rootdispersion;
peer.refid <-- pkt.refid;
peer.reftime <-- pkt.reftime;
if (valid data) call clock-filter(theta ,delta ,epsilon); /* process sample */
end packet procedure;