jbenet / ios-ntp

SNTP implementation for iOS
http://code.google.com/p/ios-ntp/
MIT License
370 stars 112 forks source link

When to stop it? #29

Closed scottybe closed 8 years ago

scottybe commented 9 years ago

This is not really an issue, but I'm not sure the proper way to go about asking...

Rather than continuously running, I would like to stop ios-ntp as soon as it reaches a "reasonably accurate" offset from the system clock.

I saw the following comments: "It will take about one minute before untrustworthy servers start to get dropped from the pool.

It would probably be better if NetworkClock called back to a delegate method, like NetAssociation does below, when it had a good time but that's not how it works, yet, so you have to wait till things settle down."

So how can I determine when it has a "good time", or should I wait 10 seconds or so, or wait a full minute?

Thanks!

gavineadie commented 9 years ago

It's a really good question. There's a trade-off between how long to wait and desired accuracy. NTP was not designed to give accurate time quickly, it was designed to run 'forever' (on a Mac it gets started when you boot the computer, and it runs till you shut down), and to adjust the system clock occasionally, as required. In fact, NTP runs in the same way in iOS (maybe from about iOS 6 onwards, I don't when it was added to iOS). But iOS is a challenging environment for NTP .. phones don't maintain a continuous connection, and people can turn off NTP to set whatever time they want.

I wrote ios-ntp a long time time ago when the iOS system clock could be as much as 2 minutes off. After I made it available on GitHub, I realized it was being used to check for people 'cheating' expiry dates in games etc.

For the former use, keeping accurate to within a second, with no concern for cheating, I don't use ios-ntp any more; the system clock in modern iOS is good enough. For the latter use, checking the reported system time hasn't been tampered with, for example, something much simpler than NTP will do the job. Simpler code is embedded in ios-ntp (the complicated NTP algorithms use simpler methods to get the time samples they use) and I want to liberate it.

I've been meaning to just finish that simple piece of work for some time .. maybe you pushed me over the edge!!

scottybe commented 9 years ago

Thanks for your reply. I've been playing around with the "Instant Time Check". That is, I'm sending all hosts through it at once, collecting the replies, removing the offsets that fall outside of 1 standard deviation from the average, then taking the average of those that remain. Seems to work fairly well.

Two notes: 1) None of the netAssociations received using this method are "trusty". Is that expected?

2) I kept getting the following error after about the 6th or 7th time I clicked the "Instant Time Check" button: "Must bind socket before you can receive data." I don't believe that is really the problem, as the GCDAsyncUdpSocket documentation says binding is optional. I think the actual problem is that the socket isn't closed after receiving data. I added "[sock close]" inside the didReceiveData delegate method and I stopped getting the error.

gavineadie commented 9 years ago

I really have to get back to this! I'm feeling guilty!!

1) I think "trusty" is an attribute gained after averages have been stable enough for confidence.

2) There have been some bugs in the GCDAsyncUdpSocket code fixed. Don't know if this is related, but I will put the latest version in on the next commit.

scottybe commented 9 years ago

Thanks! I ultimately decided to start the network clock when my app opens and set a timer to go off after 12 (arbitrary) seconds to save the offset and stop the clock.

As long as you're working on it, I think it would be cool to have it work find of like iOS location services, where it periodically calls a delegate with new time info and a "confidence" factor.