1

NTP (Network Time Protocol) is basically the de-facto standard to adjust setup server clocks. I have already raised a question about the expectations in terms of native clock accuracy on Windows Azure. Here comes a slightly different one: how I can validate the current clock reliability with NTP? The catch is that UDP is not available on Windows Azure (only TCP), and it seems there is no TCP implementation available of NTP (although the discussion is nearly one decade old).

Any take?

Community
  • 1
  • 1
Joannes Vermorel
  • 8,976
  • 12
  • 64
  • 104
  • *No UDP*? The mind, it boggles... [Insert generic rant here] Would it be possible to open a VPN connection to some server under your control that's on the Internet? IIRC OpenVPN can connect over TCP and tunnel any IP traffic. – Piskvor left the building May 31 '11 at 11:33

3 Answers3

1

Assuming that UDP outgoing packets are still blocked by Azure (I'm surprised/disappointed this is still the case!) then maybe you could drop down to a TCP service with less resolution such as TIME or DAYTIME - see descriptions of both on http://www.nist.gov/pml/div688/grp40/its.cfm - you would obviously need to measure the length of time your network call took in order to be sure the answer coming back is sufficiently accurate for you.

Stuart
  • 66,722
  • 7
  • 114
  • 165
  • Nice, DAYTIME works indeed! I have also found a nice hack which consists of using the time returned by HTTP servers http://mina86.com/2010/01/16/ntp-over-http/ Even less reliable, but good enough to detect vast clock drifts. – Joannes Vermorel Jun 01 '11 at 09:49
1

Joannes and Stuart: You are correct that Windows Azure roles (Web, Worker, and VM Roles) do not support hosting of UDP endpoints currently. However, NTP support is already included by default on Windows Azure role VMs, currently configured by default to synch the clock against server time.windows.com once a week (evidence here - search for "time service").

You can tweak a registry setting in a Startup Task if a weekly sync is not frequent enough.

HTH!

codingoutloud
  • 2,115
  • 19
  • 21
  • FYI - I recently blogged about NTP on Azure: http://blog.codingoutloud.com/2011/08/25/azure-faq-how-frequently-is-the-clock-on-my-windows-azure-vm-synchronized/ – codingoutloud Sep 08 '11 at 22:13
0

I'm a bit surprised by your answer about udp while i'm actually connect to NTP server from my azure web role to serve our JS client synchronization. This is working fine...

Note the azure web role time is a lot different thant the NTP one ( actually 30s ahead !! ). However, the NTP time is nearly the same as my local machine synchronized with time.microsoft.com

{"network":"2013-07-16T18:18:25.9558581Z","server":"2013-07-16T18:18:52.5415999Z"}

Here the code i use :

    static uint SwapEndianness(ulong x)
    {
        return (uint)(((x & 0x000000ff) << 24) +
                       ((x & 0x0000ff00) << 8) +
                       ((x & 0x00ff0000) >> 8) +
                       ((x & 0xff000000) >> 24));
    }

    static DateTime Update(string server)
    {
        // NTP message size - 16 bytes of the digest (RFC 2030)
        var ntpData = new byte[48];

        //Setting the Leap Indicator, Version Number and Mode values
        ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

        var addresses = Dns.GetHostEntry(server).AddressList;

        //The UDP port number assigned to NTP is 123
        var ipEndPoint = new IPEndPoint(addresses[0], NTPPort);
        //NTP uses UDP
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        socket.Connect(ipEndPoint);

        socket.Send(ntpData);
        DateTime l_now = DateTime.UtcNow;
        socket.Receive(ntpData);
        socket.Close();

        //Offset to get to the "Transmit Timestamp" field (time at which the reply 
        //departed the server for the client, in 64-bit timestamp format."
        const byte serverReplyTime = 40;

        //Get the seconds part
        ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);

        //Get the seconds fraction
        ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);

        //Convert From big-endian to little-endian
        intPart = SwapEndianness(intPart);
        fractPart = SwapEndianness(fractPart);

        var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);

        //**UTC** time
        var l_networkTime = (new DateTime(_epocBaseTicks, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
        _networkTimeDelta = l_networkTime.Ticks - l_now.Ticks ;
        return l_networkTime;
    }

Hope this help.