Coder Social home page Coder Social logo

ios-ntp's Introduction

ios-ntp

A network time protocol client (and an application testbed for iOS). This project is no longer being worked on, but issues will be responded to.

Created by Gavin Eadie on Oct 17, 2010

News

June 4, 2018: (version 1.1.9) There was a conflict when using cocoasyncsocket and ios-ntp; added pod dependency and removed asyncsocket files from network-lib. The necessary files can be found at https://github.com/robbiehanson/CocoaAsyncSocket

January 24, 2018: (version 1.1.6) improvements have been made in a few areas:

  • a podspec target for tvOS has been added.
  • the files from CocoaAsyncSocket have been replaced with the most recent versions.

December 20, 2016: (version 1.1.4) improvements have been made in a few areas:

  • the use of pool ntp server host names is strongly discouraged so they have been removed from this code and documentation. Read the NTP Pool Project page at http://www.pool.ntp.org/vendors.html for context. NOTE: The library will query NO servers in its new default state .. now a ntp.hosts file MUST be provided.

February 1, 2016: (version 1.1.3) improvements have been made in a few areas:

  • arithmetic operating on an NTP 64-bit time has been improved slightly.
  • the delegate callback from NetAssocation now runs on the main thread, which allows it to modify any UI component (illegal from a background thread).
  • a "receive packet filter" has been added, but not yet invoked. This will used to drop UPD packets that don't pass validation.
  • [NetAssociation finish] now invalidates its timer so that association plays no further part in time derivation.
  • upgrade sources to most recent Objective-C conventions.

Getting a Quick Timecheck

ios-ntp is often (mostly?) used to make sure someone hasn't fiddled with the system clock. The complications involved in using multiple servers and averaging time offsets is overkill for this purpose. The following skeleton code is all that is needed to check the time. If you want some more assurance of accuracy, repeat the operation a few time; if you want to continue to watch the clock, you might invoke this at infrequent intervals:

	#import "ios-ntp.h"

	@interface ntpViewController : UIViewController <NetAssociationDelegate>

	@end

	@implementation ntpViewController
	- (void)viewDidLoad {
		[super viewDidLoad];

		netAssociation = [[NetAssociation alloc]
		initWithServerName:[NetAssociation ipAddrFromName:@"time.apple.com"]];
		netAssociation.delegate = self;
		[netAssociation sendTimeQuery];
	}

	- (void) reportFromDelegate {
		printf("time offset: %5.3f mSec", netAssociation.offset * 1000.0];
	}

January 17, 2016: (version 1.1.2) minor cleanup for Xcode 7.x

July 22, 2015: (version 1.1.1) ios-ntp has contained a resource file (called ntp.hosts) which contained a list of time server hosts to be used for querying the time. That file has been removed in this release.

The logic is that, since ios-ntp can now be added to a project via CocoaPods, any local changes made to that file will be overwritten the next time the ios-ntp pod is updated and, since ios-ntp already contains a built-in list of time servers, removing this file from the pod should not impact the behavior of the ios-ntp code.

If you want to use your own list of time servers, you need to create a file containing time host names, one per line, name it ntp.hosts and place it in the main bundle of your application (the sample app ios-ntp-app does this to use the server at time.apple.com).

June 10, 2015: (version 1.1) I recently discovered a re-entrancy bug when John Grismore brought my attention to inaccuracies in reported network time offsets. When a NetAssociation notified the NetClock that it had a new time offset, that event might interrupt the offset averaging that NetClock does causing the averaging to break.

In fact, this mechanism isn't optimal anyway! The notifications that cause offset averaging arrive at NetClock constantly whether the result is used or not. We're keeping the NetClock network time offset property up to date whether we need it or not. Better would be to perform the averaging only when the offset NetClock property is called for, and that is how ios-ntp now works.

The API is not changed, so your application should require no changes.

February 22, 2015: Several important changes have been made including one that will be helpful for those who want to get a quick one-time value of the difference between system time and network time.

Before this change, ios-ntp would use time estimates from a set of NetAssociations (one per time servers), constantly determining the best time by sampling these values. This is the model for computers which have a continuous low level task monitoring the time. Application in iOS often have a different need; they are more likely to want an fast estimate of the time on demand. To provide the ability to the developer, access has been provided to use a NetAssociations directly

An NetAssociation can now be asked for one measure of the time from one time server so an iOS app can create an NetAssociation, use it to get the time, and be done.

This code operates on 32-bit and 64-bit iOS devices.

This code requires iOS 7, or higher.


About

The clock on the oldest iPhone, iTouch or iPad is not closely synchronized to the correct time. In the case of a device which is obtaining its time from the telephone system, there is a setting to enable synchronizing to the phone company time, but that time has been known to be over a minute different from the correct time.

Note: Recent versions of iOS have NTP time derivation built in so that the system clock now varies from 'real time' by less than one second (it's usually accurate to about 10mS).

In addition, users may change their device time and severely affect applications that rely on correct times to enforce functionality, or may set their devices clock into the past in an attempt to dodge an expiry date.

This project contains code to provide time obtained from standard time servers using the simple network time protocol (SNTP: RFC 5905). The implementation is not a rigorous as described in that document since the goal was to improve time accuracy to tens of milliSeconds, not to microseconds.

Computers using the NTP protocol usually employ it in a continuous low level task to keep track of the time on a continuous basis. A background application uses occasional time estimates from a set of time servers to determine the best time by sampling these values over time. iOS applications are different, being more likely to want a one-time, quick estimate of the time.

ios-ntp provides both the continuous and on-demand modes of operation. The continuous mode uses multiple 'associations' with time servers which use timers to repeatedly obtain time estimates. These associations can, however, be used by the developer to get one time from one server.

Usage

The code can be incorporated as source code or as a framework in an Xcode project. The framework usage is temporarily unavailable but will be restored soon.

More to come about using a framework.

Download the ios-ntp project, add the necessary to your project, build and run. You will need:

	#import "ios-ntp.h"

where ios-ntp is referenced.

Continuous Mode

Simply create a NetworkClock. As soon as you create it, the NTP process will begin polling the time servers in the "ntp.hosts" file. You may wish to start it when the application starts, so that the time is well synchronized by the time you actually want to use it, just call it in your AppDelegate's didFinishLaunching method.:

	NetworkClock * nc = [NetworkClock sharedNetworkClock];

then wait at least ten seconds for some time servers to respond before calling:

	NSDate * nt = nc.networkTime;

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.

On Demand Mode

This usage is slightly more complicated. The developer must create an NetAssociation (with some specified time server), and then tell it get the time from that server. The association uses a delegate method to return itself with time information.

	netAssociation = [[NetAssociation alloc] initWithServerName:@"time.apple.com"];
	netAssociation.delegate = self;
	[netAssociation sendTimeQuery];

	...

	- (void) reportFromDelegate {
	   double timeOffset = netAssociation.offset;
	}

Performance

iOS is an event driven system with an emphasis on rapid response to gestures at the cost of other activity. This encourages the extensive use of design patterns like notification and delegation so, I think, the calculation of small time differences in this environment suffers as a result.

License

The MIT License Copyright (c) 2010-2019, Ramsay Consulting

History

November 19, 2014: A large update was made today to bring ios-ntp into the modern world. The changes do include one bug fix, but are mostly related to making the code comply with the recent Xcode changes and requirements.

Finally, note that this code was first written when there were only 32-bit iOS devices. As I write this there are still 32-bit devices which run the latest version of iOS (iPhone 4S, for example), but all newer iOS devices have a 64-bit architecture (iPhone 6, for example), and Apple requires that this be supported.

ios-ntp's People

Contributors

adamn avatar bassrock avatar gavineadie avatar huynguyencong avatar jbenet avatar pakistancan avatar ruddct avatar thomasjoulin avatar tristansokol avatar tyork avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ios-ntp's Issues

fast question

Your project is very good but I have one question: does your project compensate for the time it takes to receive the answer from the time server? I mean, I request the time, the server answers at t = 0, but there is a delay between the time the server answers and the time I receive it. Does your project corrects for that delay? thanks!

What is missing from RFC 5905

In the README it is mentioned

This project contains code to provide time obtained from standard time servers using the simple network time protocol (SNTP: RFC 5905). The implementation is not a rigorous as described in that document since the goal was to improve time accuracy to tens of milliSeconds, not to microseconds.

I was wondering if more detail could be given about what portions of the 5905 spec are not implemented. Specifically, is it possible to extend this implementation to provide even more accurate time than iOS now has out of the box?

iOS-ntp returning same value as device

iOS-ntp returning same value as device, when i change device time network time change as well please help what m i missing? as i check didReceiveData not get called in NetAssociation.

Commit CocoaPod to make it easier to integrate

Hi there! Great project and thanks for the time you've spent on it over the years.

Have you considered adding a CocoaPod spec to the repo so people can very easily integrate it into their Xcode projects?

Integration would then be as simple as me adding pod 'ios-ntp' and then running pod install and it'd add it to Xcode and automatically pull in a stable/tested version of CocoaAsyncSocket pod from their repo as well so you wouldn't have to maintain that code in your own repo. This allows teams of people to all effortlessly have the same code and setup.

All you'd need to do is:

  • Add a .podspec file (I created a template for you in the commit below)
  • After you push up that commit, just tag it using git tag -a v1.0.0 -m "v1.0.0", reference that version in the podspec file, and push it up for us.
  • Use CocoaPods trunk tool if you'd like the spec in their central repo so others can easily find it by searching for NTP: http://guides.cocoapods.org/making/getting-setup-with-trunk.html

I've tweaked your project slightly to work with CocoaPods and added a podspec to our own repo for now (luxe-eng@f1fee66) since we need the library today, but we would really appreciate you considering this.

Thanks!

import error

When i was use this library in cocoa pods i found two error . First is the version 1.1.4 is not on the pod repo. Second is when i enable use_frameworks in pod file there will be occur an import error about
#import "GCDAsyncUdpSocket.h" if i replace to @import CocoaAsyncSocket; will fix this error.
Hope you fix these errors. Thanks.

Does not compile because of lacking GCDAsyncUpdSocket

When the source files of ios-ntp are added to a project, trying to compile gives an error from NetAssociation.h because of importing a non-existent <CocoaAsyncSocket/GCDAsyncUpdScoket.h>

From what I can gather, this is not a Cocoa system library, but apparently some random third-party library from somewhere. This doesn't seem to be included in the ios-ntp git project, nor can I find a single mention of it anywhere in its documentation, apart from an obscure "the files from CocoaAsyncSocket have been replaced with the most recent versions" (which quite clearly is untrue, as no such files are found anywhere in the ios-ntp git project.)

milliseconds

hey all, is it possible to achieve granularity down to the millisecond?

Question for one-time check

I'm using NetAssociation for one-time check, and I found sometimes it won't work.
I have check your code, and found you are using UDP socket, I'm not sure but if my problem is due to the UDP protocol? I want to know do you have some work to make sure the one-time check always work well even using UDP.

Static Analysis

Hi,
I will be using your library on one of my iOS projects soon but have a been a bit worried because after running ios-ntp through AppCode's static analysis there are a lot of valid warnings. For example in various places an integer is return from a function that is supposed to return an unsigned integer. -- see GCDAsyncUdpSocket.m line 1663. Though it doesn't speak to whether the library works or not it would be great if you could fix the code up a bit in the hopes of maybe prevent any crashes or problems that may occur. See Appcode at https://www.jetbrains.com/objc/

Thanks

When to stop it?

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!

Version 1.1 not in CocoaPods

I'm using ios-ntp via CocoaPods, but the only version I can get is 1.0.1. I'd really like to get the fix for the re-entrancy bug without having to switch away from the CocoaPods version. Could someone please push 1.1 out to the CocoaPods repository?

Not compiling on XCode 6

Is this library suppose to work for xcode 6? I'm getting the following error when I tried using it following the instructions in the README:

ld: warning: ignoring file /Users/*******/Desktop/Dev/Blackout/Blackout/ios-ntp.framework/ios-ntp, missing required architecture arm64 in file Users/*******/Desktop/Dev/Blackout/Blackout/ios-ntp.framework/ios-ntp (2 slices)
Undefined symbols for architecture arm64:
"OBJC_CLASS$_NetworkClock", referenced from:
objc-class-ref in BOAppDelegate.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Not to mention that I needed to #import using #import <ios-ntp/ios-ntp.h> not "ios-ntp.h"

Grabbing ntpClientRecvTime Twice

In udpSocket: didReceiveData: fromAddress: withFilterContext: you grab the ntpClientRecvTime, then you call decodePacket: and grab it again right after?

I assume the 2nd one should be skipped, plus it'll be about 8 nanoseconds later.

User changing clock

I'm trying to stop the user from setting their clock forward to gain access to content ahead of time. But, when I manually set my device time, ios-ntp returns the false time. It looks like the offset from the timeservers is too great, so they're all marked as untrustworthy?

Noob question about ntp.hosts overriding

Hi!

I'm in Brasil and to reduce the connection lag with ntp servers would be great if I could use my own ntp.hosts files.

There is a recommended way to accomplish that? (I'm using CocoaPods btw)

Great job! Thanks ;)

Locking up main thread at times

Doesn't happen often, but occasionally sendTimeQuery locks up the main thread in the beginReceiving for as much as 10-15 seconds:

- (void) sendTimeQuery {
    NSError *   error = nil;

    [socket sendData:[self createPacket] toHost:server port:123 withTimeout:2.0 tag:0];

    if(![socket beginReceiving:&error]) {
        NTP_Logging(@"Unable to start listening on socket for [%@] due to error [%@]", server, error);
        return;
    }
}

Breaking on this, it seems it's getting stuck in GCSAsyncUdpSocket's on dispatch_sync(socketQueue, block);

Any insight into what could be going wrong? Ideally, none of this should ever be touching the main thread.

demo clock is wrong

hi, when i run ios-ntp-app ,both system clock and network clock are eight hours late,what should i do to correct it?thanks!
like this
image

v1.1.7 updates coming soon ..

I've added recent changes to the GCDAsyncUdpSocket code to my local repo, and that will be the basis for a v1.1.7 release as soon as v1.1.6 has settled down. I believe there will not be any functional changes to ios-ntp as a result.

EXC_BAD_ACCESS

Hi, I'm having issues when I call networkOffset method, I get a bad_access error.

@interface NTPClient:NSObject{
    NetworkClock * nc;
}
- (id)init;
- (bool)isInitialized;
- (Array<int>)now;
@end

@implementation NTPClient

- (id)init {
    self = [super init];
    nc = [NetworkClock sharedNetworkClock];
//    NSDate * nt= nc.networkTime; <-----It's fine if I call it here
    return self;
}

- (bool) isInitialized{
    return true;
}

- (Array<int>) now {
//    nc = [NetworkClock sharedNetworkClock];
    NSDate * nt= nc.networkTime; // <-------------- It breaks here

    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:nt];

    Array<int> a= *new Array<int>;
    a[0] = (int)[components year];
    a[1] = (int)[components month];
    a[2] = (int)[components day];
    a[3] = (int)[components hour];
    a[4] = (int)[components minute];
    a[5] = (int)[components second];
    a[6] = 0;
    return a;
}

@end

Thanks

Synch Inssue

when application goes to background and i changed the device time in settings . then after that if i again make application active by tapping on it , then it's giving wrong gmt time . if i quit the application and launch it again , in that case it's working as expected . please suggest how to fix this

Account for Packet Loss in One-Off Mode

Right now if you use NetAssociation in one-off mode, and the UDP packet gets lost and never arrives... the delegate method would never be called.

Maybe there should be some timeout, and success/failure reporting?

Block-based would also be heavenly :)

Possible to use NetAssociation with systemUptime?

Like many others I use NTP to detect time manipulation, and to retrieve accurate time. This is often difficult to deal with when a user leaves the app, changes the time, comes back, and NTP takes a bit of time to figure out the new offset.

Would it be possible to get an NTP response with an offset, and associate it with the current systemUptime? Once established, seconds since uptime would becoming a meaningful measure of time and we wouldn't need further NTP checks or to use the system time.

Does this seem plausible?
cc @gavineadie

Network time is incorrect

When I change my clock forward n minute, the time I receive is forward 2*n minute. The networkTime is double wrong

Ex: If current server time is 15:30. I change my phone time to 15:33. The networkTime I receive from [NetworkClock sharedNetworkClock].networkTime is 15:36

I use it by call [NetworkClock sharedNetworkClock]; in application:didFinishLaunchingWithOptions: and get [NetworkClock sharedNetworkClock].networkTime in a button touch event.

It happen from version:
c6f2d2b
Restructure so the NetAssociations tick and hold state as independent…

In correct version, I see networkTime adding has "-" sign:
return [[NSDate date] dateByAddingTimeInterval:-timeIntervalSinceDeviceTime/1000.0];
But current version is missed
return [[NSDate date] dateByAddingTimeInterval:[self networkOffset]];

my issue

Hi
First, thank you because you provide such code for all coders!
Thank you again.

But i has some issue as follow:

  • 'AyncUdpSocket' should be 'AsyncUdpSocket'?
  • When can provide new code for 64-bit?

Best regards.

Crash when returning from background after loss of network connection

I experienced a crash when returning from background after a network connection loss.

Steps to reproduce:

  1. Make sure you have an internet connection
  2. Open the app (wait 30 seconds)
  3. Close the app (put it in background mode)
  4. Turn off internet connection (turn off data or go to airplane mode)
  5. Reopen the app
  6. It will crash

Thanks.

NetAssociation doesn't post any notification

This was working fine for some time, but then something changed. I traced the calls and every call of [NetAssociation evaluatePacket] the good = 0, fail = 1, unused = 7. And it skips the assoc-fail/good notification part.

I was wondering what could affect it? Could there be a flag in the Build Settings? The code is part of a library, which hasn't been changed. But it stopped working. By the way, I tried different NTP servers and nothing helps.

I would really appreciate the help.

NetAssociation enables itself on foreground even when not previously enabled

I'm trying to do one-off queries of the NTP server using sendTimeQuery. I thus never enable my NetAssociation but it gets enable by the foregrounding event. I just commented those sections out for my own use, but you might want to do some kind of check of whether the user wants the services enabled at all.

有啥用呢?

一直是本地时间 即使本地时间修改后也会跟着本地时间变

Can't compile static library

Trying to compile target ios-ntp -> iPhone 6.1 simulator
Getting:
lipo: can't open input file: /Users/me/Library/Developer/Xcode/DerivedData/ios-ntp-dugtdxdmajqvrpbzrxshalcsxzng/Build/Products/Debug-iphoneos/ios-ntp.framework/ios-ntp (No such file or directory)

NetAssociation's -enable re-registers the instance as observer

This causes -finish and -enable to be called additional times for the same instance. Reproducible by locking/unlocking the phone. After unlocking for the 5th time, the UI starts to lag while -enable is being called, and ultimately leads to a crash in GCDAsyncUDPSocket.

Access denied ..

Sorry, guys .. I seem to lost the ability to make changes to this repository; no idea why. There are changes in half a dozen files that I cannot commit. I've been fighting this too long and am going to give up till my temper cools down and a pile of more important tasks as finished.

Cocoa Pods released version

Hi,

I found that released version on Cocoa pods (1.1.1) is different comparing to this repository (1.1.3).
Could you check and fix this?

Thanks!

Wrong network time when app returns from background

When I put the app in background, change the time from settings and then go back to the application, it seems that it is returning the wrong network time. Do you have any work around for this? Thank you very much in advance.

Bug

When [NetworkClock sharedNetworkClock] is first called when there is no internet connection, no network associations will be created, meaning that no timers are ever created, so even when internet is back on at a later point in time, nothing will happen / no pings to any time servers will happen.

Ability to Change the Time Servers Without Reboot

hi again. What about finishing/clearing the timeAssociations array in NetworkClock.m, whenever createAssociationsWithServers: is called? (Assuming it were filled).

Given how infrequently a lot of users update their apps.... I think it would be handy to be able to remotely fully refresh the time servers. (Right now would have to wait until the app was rebooted).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.