Introduction to NTP (1/2)
Introduction to NTP
By Dan Ragle
From time to time as a Web developer, you may find it necessary to ensure that the application you are creating can operate in a synchronized fashion with another application or system; possibly on the same server, a separate server within the same subnet, or even an entirely separate server located on another continent. If you are developing any type of messaging application, for example, then it may be critical (and will certainly be helpful) for you to identify your messages with accurate timestamps, timestamps that agree with some internationally agreed upon measurement of the world's current time. Or if you are creating an application that you will use to trade securities on NASDAQ, then it will be imperative that your application know when 4:00pm is. And not just any 4:00pm, mind you; the 4:00pm.
While it is relatively easy to synchronize two processes on the same server on the basis of the machine's system clock; what if (as in the above examples) you need to run your process in synchronization with another system across the street, or around the world? Even for those processes that need synchronization across the same server, are you certain that the clock settings from the server you are relying on are accurate to any national standards, i.e., if the server's clock says it's 4:00pm, is it really 4:00pm?
At first glance, synchronizing the time of two or more machines would seem to be a trivial matter. You just have one machine ask another machine, which is presumed to have a more accurate notion of what time it is, to provide the current time. Then you set the time of the local machine based on the answer you receive. And if your needs are such that "within a few seconds" of accuracy are acceptable, then such a simplistic approach would be more then adequate. But what if your needs are more stringent; say, requiring accuracy to within a fraction of a second, or even within milliseconds? Such a simplistic approach fails because it simply does not take into consideration a multitude of variables having to do with the effect of the synchronization process itself -specifically, the time it takes- on the timestamp received from the queried server. For example, how many milliseconds did it take for your machine to retrieve the current time from your system's clock? How long did it take to send a message over the Internet to the target time server? How long did it take the target server to process your request, and send you a reply? For you to set your clock with the highest degree of accuracy, each of these intervals must be measured and quantified via the best possible means. And by the way, how accurate is that timestamp returned by the target server? Is it comparable to other available standard time servers? And for the purposes of continued accuracy in your own application, how accurate is your own clock over a given period of time?
Enter the Network Time Protocol, or NTP. NTP was initially developed in the early 80's, with the first formal specification (Version 1) authored by Professor Professor David L. Mills of The University of Delaware and appearing in RFC 1059. The specification itself presents not only the communication protocol that allows machines to exchange the necessary information to synchronize their clocks, but has evolved over the years to include the discussions, algorithms, and methodologies required to address each of the issues noted in the above paragraph (and many others) such that geographically disperse machines can synchronize their clocks to be within milliseconds of one another using Internet (IP/UDP) communications. The latest official NTP specification is RFC 1305, which represents NTP version 3. Among other concerns, the RFC details such issues as the polling of multiple time servers in order to determine which are most accurate (and then to draw your synchronized time from an average of the best ones) to avoid inaccuracies in any one specific server; and the graceful adjustment of the local clock to match the new time setting. On a large, shared, public server it can be a disaster to suddenly reset the server's time to a different setting, as you may not be able to predict how all processes operating on the server will be effected by the sudden time shift. The official development version of NTP is version 4; however, no official RFC has been produced for version 4 NTP as of yet.
NTP uses as its time basis Coordinated Universal Time, or UTC, which utilizes atomic clocks (which in turn measure time in relation to an atomic transition of the element cesium under specific conditions) and periodically adds or subtracts "leap seconds" to account for variations in the atomic clock time as it relates to the (relatively speaking) inconsistent rotation speed of the Earth. (Consistent or not, it would not do to have an official time that gradually drifted such that it was dark at noon and sunny and bright at midnight.)
Chances are, such extended methodologies as mentioned above (intended to produce the most accurate timestamps possible) are well beyond your time synchronization requirements, where accuracy to within a fraction of a second is generally more than adequate. For this reason, Professor Mills has also provided us with SNTP, the Simple Network Time Protocol. SNTP is currently described as version 4, and presented in RFC 2030. It is structurally similar to NTP; but is much easier to grasp. Basically, SNTP is targeted primarily to simple client/server implementations; where a client queries a single server (as opposed to the multi-server algorithms as described in NTP) for a time and sets its hardware or logical clock accordingly (the RFC also provides for operation in multicast or anycast modes). Nonetheless, properly implemented SNTP servers can still provide an extremely high level of accuracy; and it is this simplified usage of NTP communications that we will concern ourselves with for the remainder of this article. For those interested in delving into the intricacies of the full NTP specification, I recommend the documentation of the NTP Public Services Project, the previously mentioned RFCs, and the NTP FAQ.
The SNTP Protocol
At the center of the SNTP protocol itself, is the communication packet that is exchanged between a client and a server, which includes the necessary information that will allow the client to update its system clock to the accurate time presented by the queried server. Such messages are by definition passed through port 123, and consist of the following payload:
1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |LI | VN |Mode | Stratum | Poll | Precision | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Root Delay | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Root Dispersion | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Reference Identifier | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Reference Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Originate Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Receive Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Transmit Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Identifier (optional) (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | Message Digest (optional) (128) | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
For a detailed examination of each field, I refer you to RFC 1305 (from which the above diagram was taken). For our purposes, note that timestamps as provided in NTP and SNTP messages are represented as 64-bit numerals, with the first 32 bits of the timestamp representing the integer portion of the timestamp, and the second 32 bits representing the fractional portion; and that the mode bits will be set to 3 when we send a request, and 4 when the reply is received from our target server.
In SNTP, many of the above fields are filled with pre-specified data. When sending a request, for example, it is adequate to set the Leap Second indicator bits (LI) to 0, the Mode bits to 3, and the VN bits (Version) to match the version number of the server you will be querying (more on how to find a server on the next page). Note that version 4 servers will accept all previous NTP version requests (except version 0, which is no longer supported by any version). All the remaining fields can be zeroed; with the Transmit Timestamp field optional (but recommended; as it can be used to determine delay and thus increase the accuracy of your local clock adjustment, as described below).
When the target server receives your request, it copies the Transmit Timestamp into the Originate Timestamp, and sets the Receive and Transmit Timestamps according to its own clock for the reply to you. You then generate a Destination Timestamp variable (the timestamp of your local machine when you receive the reply). Again, from RFC 1305, the calculation to determine both the round trip delay and the necessary offset from which to adjust your clock to match the target server is represented as follows:
Timestamp Name ID When Generated ------------------------------------------------------------ Originate Timestamp T1 time request sent by client Receive Timestamp T2 time request received by server Transmit Timestamp T3 time reply sent by server Destination Timestamp T4 time reply received by client The roundtrip delay d and local clock offset t are defined as d = (T4 - T1) - (T2 - T3) t = ((T2 - T1) + (T3 - T4)) / 2
You can then use this offset to adjust your local clock, or, if you're on a shared server or a hosted server that you are not allowed to adjust the time on (and even if you are, remember the brief discussion above on the potential danger involved in making sudden adjustments to your server's time) you can use the offset in subsequent time-based processing to ensure your process is in synchronization with UTC (even if everything else on the server isn't). It is this latter possibility that we will explore in more detail on the next page, when we discuss a simple Perl-based proof of concept script that triggers an alarm message at a specific--and accurate--time of day. While the above algorithm is simple enough, it turns out that ready-made Perl modules from CPAN make the whole NTP communication process virtually a plug-and-play affair.
Created: June 10, 2005
Revised: June 10, 2005