Poll Process (NTP Reference Implementation) (Computer Network Time Synchronization)

The poll process sends packets to the server at designated intervals t and updates the reach register, which establishes whether the server is reachable. The poll() routine is shown in Figure 14.16. Each time the poll() routine is called, the reach variable is shifted left by one bit. When a packet is accepted by the packet() routine in the peer process, the rightmost bit is set to one. As long as reach is nonzero, the server is considered reachable. However, if the rightmost three bits become zero, indicating that packets from the server have not been received for at least three poll intervals, a sample with MAXDIST dispersion is shifted in the clock filter. This causes the dispersion to increase and the server to be devalued in the mitigation process. The unreach counter increments at each poll interval; it is reset to zero if the reach register is nonzero. If the counter exceeds the UNREACH parameter, the poll exponent is incremented for each succeeding poll. This reduces useless network load in case of server failure.

The poll() routine can operate in three modes. Ordinarily, polls are sent at the interval selected by hpoll and ppoll poll exponents assigned. However, if the iburst option in Section 5.9 is enabled and the server is not reachable, a burst of eight polls is sent at 2-s intervals. Alternatively or in addition, if the burst option is enabled and the server is reachable, a burst of eight polls is sent as with iburst. This is especially useful at very large poll intervals of many hours.


The remaining routines are straightforward. The poll() routine calls the peer_xmit() routine when an association has been mobilized. The receive() routine calls fast_xmit() when a client mode packet is received. Both cases are shown in Figure 14.17.

Routine poll().

FIGURE 14.16

Routine poll().

These routines copy values from the association (peer_xmit()) or from the arriving packet (fast_xmit()), as shown in the accompanying tables. The poll_update() routine shown in Figure 14.18 determines the next poll interval or burst interval.

Parting Shots

An issue worth mentioning is the relationship between the published standard and the reference implementation. It is tempting to construct a standard from first principles, submit it for formal verification, then tell somebody to build it. Of the four generations of NTP, it did not work that way. Both the standard and the reference implementation were evolved from an earlier version, then carefully and methodically cross-checked to make sure that the implementation did what the standard said and vice versa. Along the way, many minor tweaks were needed in both the specification and implementation to ensure that was the case. In the most recent versions, a simulation tool, properly described as a skeleton, was used as a verification tool.

Routines peer_xmit() and fast_xmit().

FIGURE 14.17

Routines peer_xmit() and fast_xmit().

Routine poll_update().

FIGURE 14.18

Routine poll_update().

On several occasions during construction of the flowcharts and descriptions in this topic, some little thing or other suggested a specific test. For example, two symmetric peers cannot ever get in symmetric passive mode with each other. That might even be true in practice, but what would happen if they did? Testing confirmed unsuspected errors in the code and were quickly corrected. Some little errors like this have persisted for many years before rigorous testing exposed them.

Next post:

Previous post: