NetworkMonitor.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // NetworkMonitor.m
  3. // ZeroTier One
  4. //
  5. // Created by Grant Limberg on 8/7/16.
  6. // Copyright © 2016 ZeroTier, Inc. All rights reserved.
  7. //
  8. #import "NetworkMonitor.h"
  9. #import "Network.h"
  10. #import "ServiceCom.h"
  11. #import "NodeStatus.h"
  12. NSString * const NetworkUpdateKey = @"com.zerotier.one.network-list";
  13. NSString * const StatusUpdateKey = @"com.zerotier.one.status";
  14. @interface NetworkMonitor (private)
  15. - (NSString*)dataFile;
  16. - (void)internal_updateNetworkInfo;
  17. - (NSInteger)findNetworkWithID:(UInt64)networkId;
  18. - (NSInteger)findSavedNetworkWithID:(UInt64)networkId;
  19. - (void)saveNetworks;
  20. @end
  21. @implementation NetworkMonitor
  22. - (id)init
  23. {
  24. self = [super init];
  25. if(self)
  26. {
  27. _savedNetworks = [NSMutableArray<Network*> array];
  28. _receivedNetworks = [NSArray<Network*> array];
  29. _allNetworks = [NSMutableArray<Network*> array];
  30. _timer = nil;
  31. }
  32. return self;
  33. }
  34. - (void)dealloc
  35. {
  36. [_timer invalidate];
  37. }
  38. - (void)start
  39. {
  40. NSLog(@"ZeroTier monitor started");
  41. _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
  42. target:self
  43. selector:@selector(updateNetworkInfo)
  44. userInfo:nil
  45. repeats:YES];
  46. }
  47. - (void)stop
  48. {
  49. NSLog(@"ZeroTier monitor stopped");
  50. [_timer invalidate];
  51. _timer = nil;
  52. }
  53. - (void)updateNetworkInfo
  54. {
  55. NSString *filePath = [self dataFile];
  56. if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
  57. NSArray<Network*> *networks = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
  58. if(networks != nil) {
  59. _savedNetworks = [networks mutableCopy];
  60. }
  61. }
  62. [[ServiceCom sharedInstance] getNetworklist:^(NSArray<Network *> *networkList) {
  63. _receivedNetworks = networkList;
  64. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  65. [self internal_updateNetworkInfo];
  66. }];
  67. }];
  68. [[ServiceCom sharedInstance] getNodeStatus:^(NodeStatus *status) {
  69. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:status forKey:@"status"];
  70. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  71. [[NSNotificationCenter defaultCenter] postNotificationName:StatusUpdateKey
  72. object:nil
  73. userInfo:userInfo];
  74. }];
  75. }];
  76. }
  77. - (void)deleteSavedNetwork:(NSString*)networkId
  78. {
  79. UInt64 nwid = 0;
  80. NSScanner *scanner = [NSScanner scannerWithString:networkId];
  81. [scanner scanHexLongLong:&nwid];
  82. NSInteger index = [self findNetworkWithID:nwid];
  83. if(index != NSNotFound) {
  84. [_allNetworks removeObjectAtIndex:index];
  85. }
  86. index = [self findSavedNetworkWithID:nwid];
  87. if(index != NSNotFound) {
  88. [_savedNetworks removeObjectAtIndex:index];
  89. }
  90. [self saveNetworks];
  91. }
  92. @end
  93. @implementation NetworkMonitor (private)
  94. - (NSString*)dataFile
  95. {
  96. NSURL *appSupport = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
  97. inDomains:NSUserDomainMask] objectAtIndex:0];
  98. appSupport = [[[appSupport URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"] URLByAppendingPathComponent:@"networkinfo.dat"];
  99. return appSupport.path;
  100. }
  101. - (void)internal_updateNetworkInfo
  102. {
  103. NSMutableArray<Network*> *networks = [_savedNetworks mutableCopy];
  104. for(Network *nw in _receivedNetworks) {
  105. NSInteger index = [self findSavedNetworkWithID:nw.nwid];
  106. if(index != NSNotFound) {
  107. [networks setObject:nw atIndexedSubscript:index];
  108. }
  109. else {
  110. [networks addObject:nw];
  111. }
  112. }
  113. [networks sortUsingComparator:^NSComparisonResult(Network *obj1, Network *obj2) {
  114. if(obj1.nwid > obj2.nwid) {
  115. return true;
  116. }
  117. return false;
  118. }];
  119. @synchronized(_allNetworks) {
  120. _allNetworks = networks;
  121. }
  122. [self saveNetworks];
  123. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:networks forKey:@"networks"];
  124. [[NSNotificationCenter defaultCenter] postNotificationName:NetworkUpdateKey
  125. object:nil
  126. userInfo:userInfo];
  127. }
  128. - (NSInteger)findNetworkWithID:(UInt64)networkId
  129. {
  130. for(int i = 0; i < [_allNetworks count]; ++i) {
  131. Network *nw = [_allNetworks objectAtIndex:i];
  132. if(nw.nwid == networkId) {
  133. return i;
  134. }
  135. }
  136. return NSNotFound;
  137. }
  138. - (NSInteger)findSavedNetworkWithID:(UInt64)networkId
  139. {
  140. for(int i = 0; i < [_savedNetworks count]; ++i) {
  141. Network *nw = [_savedNetworks objectAtIndex:i];
  142. if(nw.nwid == networkId) {
  143. return i;
  144. }
  145. }
  146. return NSNotFound;
  147. }
  148. - (void)saveNetworks
  149. {
  150. NSString *filePath = [self dataFile];
  151. @synchronized(_allNetworks) {
  152. [NSKeyedArchiver archiveRootObject:_allNetworks toFile:filePath];
  153. }
  154. }
  155. @end