SNTP Time Class |
Written by Harry Fairhead | ||||||
Sunday, 01 September 2024 | ||||||
Page 1 of 5 SNTP is a network protocol for obtaining an accurate time and it is an interesting exercise to build an SNTP client. In this article the language used is C# but it is easy enough to generalise to a language of your choice and extend the ideas to an SNTP server if you need to. The main aim is to describe and show how to implement the basic protocol. To start at the beginning I'd better tell you what SNTP is all about. All over the Internet there are servers which transmit the accurate time using different types of clock including some very accurate atomic clocks. In practice it doesn't really matter what type of clock is being used because almost anything is going to be more accurate than your system hardware clock which typically loses minutes every day! However most modern operating systems do include the ability to synchronise the system clock with an SNTP time server and so your system clock might well be more accurate than its hardware specification would suggest. The idea is that you can connect to one of these servers and simply request the time be sent to you. The protocol used for the request and the delivery is SNTP, Simple Network Time Protocol, or NTP, Network Time Protocol. This isn't a complicated protocol but implementing the client described took far longer than you might guess. The reason is, as always, that the protocol is described in a way that makes good sense to the protocol specification writer but leaves a lot vague and unclear to the implementer. Unicast SNTPThere are two versions of SNTP, Unicast and Multicast. The Mulitcast protocol broadcasts time packets that anyone can pick up and is useful for keeping a local network synchronised. The Unicast protocol is slightly more complicated from the client's point of view in that it has to request a packet but it is the norm on the wider Internet. To make use of Unicast SNTP we have to use the datagram or UDP protocol as opposed to a TCP connection. The simplest way of working with UDP in .NET is to use the UdpClient class but this is just a customisation of the more fundamental Socket class and you can easily use the Socket class to work with UDP if you want to. The basic transaction is simple.
The Structure Of TimeSounds too good to be true, and indeed it is easy, but the complications are hidden in the words "SNTP data structure". The structure consists of four 32-bit words followed by four 64-bit time stamps. There is also an optional 96-bit authenticator, which can be used to verify the server's identity, but this isn't used by publicly available time servers.
The SNTP time packet
Each of the time stamps uses the same 64-bit format. The first 32 bits is an unsigned binary integer that gives the number of seconds since 00h on 1 Jan 1900 - the fiducial date. The next 32 bits is a pure binary fraction giving the fractional part of the seconds since the fiducial date. Most time standards aren't accurate enough to fill the entire 32 bits and any unused bits are simply set to zero. Time Stamp format
Interestingly there is a problem contained in this time stamp format that is very similar to the year 2000 problem. Yes, you've guessed it – roll over! Currently the high bit of the time stamp is set and it is heading to roll over in 2036 so look out for the Y2036 bug problem. SNTPv4, the latest version, appears to introduce a standard which uses a 128-bit date format: 64 bits for the second and 64 bits for the fractional-second. This has enough range to work until the end of the universe or 585 billion years. However, this isn’t quite what it seems as even SNTPv4 uses the usual 64-bit format to send the current time and it is left to the client to expand this to a full 128-bit date by determining the “era” via other means. The prime epoch, i.e. 00h on 1 Jan 1900, corresponds to an era of zero, i.e. the high-order 64 bits are set to zero. Once the date passes 00h on 1 Jan 2036 the era will be set to one and the timestamp will roll over to zero. That is the full 128 bit date is given by 128-bit date = era x 2 32 + timestamp and it is for the client to determine the value of era by other means. Another way to look at this is that at the moment the timestamp measures the seconds from 00h on 1 Jan 1900 and after the rollover it measures seconds from 00h on 1 Jan 2036 and so on. As SNTP is used to set the current date and time you can effectively ignore the problem and set the current date and time using the timestamp from the fiducial date that is appropriate for your era. Notice that this approach doesn’t work for timestamps that are used to record when something happened as the era cannot be deduced in the same way. What time zone does the time stamp represent? The answer is that it doesn't reflect any time zone, the time stamp is always UT or Universal Time (which is the same as GMT, Greenwich Mean Time) Our time control is just going to ignore other time zones and will return UT no matter what time zone is in use. The final problem with the time stamp, and it is the problem with all such specifications, is the byte and bit order of the data. Although you can be reasonably certain of this using descriptions such as "high order bits to the right" and "Big Endian byte order" you can never be 100% sure that you have understood such a diagram and descriptions until you try it out. <ASIN:B00OD4LR06> <ASIN:B09FTLPTP9> |
||||||
Last Updated ( Sunday, 01 September 2024 ) |