NetworkMonitor.m 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. @import AppKit;
  13. NSString * const NetworkUpdateKey = @"com.zerotier.one.network-list";
  14. NSString * const StatusUpdateKey = @"com.zerotier.one.status";
  15. @interface NetworkMonitor (private)
  16. - (NSString*)dataFile;
  17. - (void)internal_updateNetworkInfo;
  18. - (NSInteger)findNetworkWithID:(UInt64)networkId;
  19. - (NSInteger)findSavedNetworkWithID:(UInt64)networkId;
  20. - (void)saveNetworks;
  21. @end
  22. @implementation NetworkMonitor
  23. - (id)init
  24. {
  25. self = [super init];
  26. if(self)
  27. {
  28. _savedNetworks = [NSMutableArray<Network*> array];
  29. _receivedNetworks = [NSArray<Network*> array];
  30. _allNetworks = [NSMutableArray<Network*> array];
  31. _timer = nil;
  32. }
  33. return self;
  34. }
  35. - (void)dealloc
  36. {
  37. [_timer invalidate];
  38. }
  39. - (void)start
  40. {
  41. NSLog(@"ZeroTier monitor started");
  42. _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
  43. target:self
  44. selector:@selector(updateNetworkInfo)
  45. userInfo:nil
  46. repeats:YES];
  47. }
  48. - (void)stop
  49. {
  50. NSLog(@"ZeroTier monitor stopped");
  51. [_timer invalidate];
  52. _timer = nil;
  53. }
  54. - (void)updateNetworkInfo
  55. {
  56. NSString *filePath = [self dataFile];
  57. if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
  58. NSArray<Network*> *networks = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
  59. if(networks != nil) {
  60. _savedNetworks = [networks mutableCopy];
  61. }
  62. }
  63. NSError *error = nil;
  64. [[ServiceCom sharedInstance] getNetworklist:^(NSArray<Network *> *networkList) {
  65. _receivedNetworks = networkList;
  66. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  67. [self internal_updateNetworkInfo];
  68. } ];
  69. } error:&error];
  70. if(error) {
  71. [self stop];
  72. NSAlert *alert = [NSAlert alertWithError:error];
  73. alert.alertStyle = NSCriticalAlertStyle;
  74. [alert addButtonWithTitle:@"Quit"];
  75. [alert addButtonWithTitle:@"Retry"];
  76. NSModalResponse res = [alert runModal];
  77. if(res == NSAlertFirstButtonReturn) {
  78. [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
  79. }
  80. else if(res == NSAlertSecondButtonReturn) {
  81. [self start];
  82. return;
  83. }
  84. }
  85. [[ServiceCom sharedInstance] getNodeStatus:^(NodeStatus *status) {
  86. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:status forKey:@"status"];
  87. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  88. [[NSNotificationCenter defaultCenter] postNotificationName:StatusUpdateKey
  89. object:nil
  90. userInfo:userInfo];
  91. }];
  92. } error:&error];
  93. if (error) {
  94. [self stop];
  95. NSAlert *alert = [NSAlert alertWithError:error];
  96. alert.alertStyle = NSCriticalAlertStyle;
  97. [alert addButtonWithTitle:@"Quit"];
  98. [alert addButtonWithTitle:@"Retry"];
  99. NSModalResponse res = [alert runModal];
  100. if(res == NSAlertFirstButtonReturn) {
  101. [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
  102. }
  103. else if(res == NSAlertSecondButtonReturn) {
  104. [self start];
  105. return;
  106. }
  107. }
  108. }
  109. - (void)deleteSavedNetwork:(NSString*)networkId
  110. {
  111. UInt64 nwid = 0;
  112. NSScanner *scanner = [NSScanner scannerWithString:networkId];
  113. [scanner scanHexLongLong:&nwid];
  114. NSInteger index = [self findNetworkWithID:nwid];
  115. if(index != NSNotFound) {
  116. [_allNetworks removeObjectAtIndex:index];
  117. }
  118. index = [self findSavedNetworkWithID:nwid];
  119. if(index != NSNotFound) {
  120. [_savedNetworks removeObjectAtIndex:index];
  121. }
  122. [self saveNetworks];
  123. }
  124. @end
  125. @implementation NetworkMonitor (private)
  126. - (NSString*)dataFile
  127. {
  128. NSURL *appSupport = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
  129. inDomains:NSUserDomainMask] objectAtIndex:0];
  130. appSupport = [[[appSupport URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"] URLByAppendingPathComponent:@"networkinfo.dat"];
  131. return appSupport.path;
  132. }
  133. - (void)internal_updateNetworkInfo
  134. {
  135. NSMutableArray<Network*> *networks = [_savedNetworks mutableCopy];
  136. for(Network *nw in _receivedNetworks) {
  137. NSInteger index = [self findSavedNetworkWithID:nw.nwid];
  138. if(index != NSNotFound) {
  139. [networks setObject:nw atIndexedSubscript:index];
  140. }
  141. else {
  142. [networks addObject:nw];
  143. }
  144. }
  145. [networks sortUsingComparator:^NSComparisonResult(Network *obj1, Network *obj2) {
  146. if(obj1.nwid > obj2.nwid) {
  147. return true;
  148. }
  149. return false;
  150. }];
  151. @synchronized(_allNetworks) {
  152. _allNetworks = networks;
  153. }
  154. [self saveNetworks];
  155. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:networks forKey:@"networks"];
  156. [[NSNotificationCenter defaultCenter] postNotificationName:NetworkUpdateKey
  157. object:nil
  158. userInfo:userInfo];
  159. }
  160. - (NSInteger)findNetworkWithID:(UInt64)networkId
  161. {
  162. for(int i = 0; i < [_allNetworks count]; ++i) {
  163. Network *nw = [_allNetworks objectAtIndex:i];
  164. if(nw.nwid == networkId) {
  165. return i;
  166. }
  167. }
  168. return NSNotFound;
  169. }
  170. - (NSInteger)findSavedNetworkWithID:(UInt64)networkId
  171. {
  172. for(int i = 0; i < [_savedNetworks count]; ++i) {
  173. Network *nw = [_savedNetworks objectAtIndex:i];
  174. if(nw.nwid == networkId) {
  175. return i;
  176. }
  177. }
  178. return NSNotFound;
  179. }
  180. - (void)saveNetworks
  181. {
  182. NSString *filePath = [self dataFile];
  183. @synchronized(_allNetworks) {
  184. [NSKeyedArchiver archiveRootObject:_allNetworks toFile:filePath];
  185. }
  186. }
  187. @end