feat: multi-IP storage for host (tested with zeroTier)

This commit is contained in:
TrueZhuanjia committed 2025-12-23 01:15:37 +08:00
1 parent 75f1d4d392
commit 2912a3a5cb
8 files changed
+50 -3

No files matched your search

+1
View File
@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (atomic, retain) NSString *name; @property (atomic, retain) NSString *name;
@property (atomic, retain) NSString *uuid; @property (atomic, retain) NSString *uuid;
@property (atomic, retain) NSSet *appList; @property (atomic, retain) NSSet *appList;
@property (atomic, retain) NSMutableSet * activeAddressPool;
- (id) initFromHost:(Host*)host; - (id) initFromHost:(Host*)host;
+21 -1
View File
@@ -28,6 +28,17 @@
self = [self init]; self = [self init];
self.address = host.address; self.address = host.address;
NSSet *classes = [NSSet setWithObjects: [NSMutableSet class], nil];
NSError *error = nil;
self.activeAddressPool = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:host.activeAddressPool error:&error];
if(self.activeAddressPool){
for(NSString* address in _activeAddressPool){
NSLog(@"%@, persisted addr: %@", host.name, address);
}
}
else self.activeAddressPool = [[NSMutableSet alloc] init];
self.externalAddress = host.externalAddress; self.externalAddress = host.externalAddress;
self.localAddress = host.localAddress; self.localAddress = host.localAddress;
self.ipv6Address = host.ipv6Address; self.ipv6Address = host.ipv6Address;
@@ -57,7 +68,7 @@
return self; return self;
} }
- (void) propagateChangesToParent:(Host*)parentHost { - (void) propagateChangesToParent:(Host*)parentHost { // update persisted host data
// Avoid overwriting existing data with nil if // Avoid overwriting existing data with nil if
// we don't have everything populated in the temporary // we don't have everything populated in the temporary
// host. // host.
@@ -73,6 +84,15 @@
if (self.ipv6Address != nil) { if (self.ipv6Address != nil) {
parentHost.ipv6Address = self.ipv6Address; parentHost.ipv6Address = self.ipv6Address;
} }
if(self.activeAddressPool.count>0){
NSError *error;
parentHost.activeAddressPool = [NSKeyedArchiver archivedDataWithRootObject:self.activeAddressPool requiringSecureCoding:YES error:&error];
}
else [self.activeAddressPool addObject:self.activeAddress];
// NSLog(@"Persisting activeAddressPool, pool count %lu ... %f, host: %@", (unsigned long)self.activeAddressPool.count, CACurrentMediaTime(), self.name);
// try to fix invalid mac happens in some cases // try to fix invalid mac happens in some cases
// 添加主机crash问题重点关注 // 添加主机crash问题重点关注
if (!(self.mac == nil || [self.mac isEqualToString:@"00:00:00:00:00:00"])) parentHost.mac = self.mac; if (!(self.mac == nil || [self.mac isEqualToString:@"00:00:00:00:00:00"])) parentHost.mac = self.mac;
@@ -8,6 +8,7 @@
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/> <relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
</entity> </entity>
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class"> <entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
<attribute name="activeAddressPool" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/> <attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/> <attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/> <attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/>
+6 -1
View File
@@ -30,6 +30,7 @@
NSString* _uniqueId; NSString* _uniqueId;
NSData* _cert; NSData* _cert;
BOOL shouldDiscover; BOOL shouldDiscover;
DataManager* dataMan;
} }
- (id)initWithHosts:(NSArray *)hosts andCallback:(id<DiscoveryCallback>)callback { - (id)initWithHosts:(NSArray *)hosts andCallback:(id<DiscoveryCallback>)callback {
@@ -52,6 +53,7 @@
[CryptoManager generateKeyPairUsingSSL]; [CryptoManager generateKeyPairUsingSSL];
_uniqueId = [IdManager getUniqueId]; _uniqueId = [IdManager getUniqueId];
_cert = [CryptoManager readCertFromFile]; _cert = [CryptoManager readCertFromFile];
DataManager* dataMan = [[DataManager alloc] init];
return self; return self;
} }
@@ -139,6 +141,8 @@
if ([serverInfoResponse isStatusOk]) { if ([serverInfoResponse isStatusOk]) {
host = [[TemporaryHost alloc] init]; host = [[TemporaryHost alloc] init];
host.activeAddress = host.address = hostAddress; host.activeAddress = host.address = hostAddress;
if(!host.activeAddressPool) host.activeAddressPool = [[NSMutableSet alloc] init];
[host.activeAddressPool addObject:host.activeAddress];
host.state = StateOnline; host.state = StateOnline;
[serverInfoResponse populateHost:host]; [serverInfoResponse populateHost:host];
@@ -284,8 +288,9 @@
existingHost.externalAddress = host.externalAddress; existingHost.externalAddress = host.externalAddress;
} }
existingHost.activeAddress = host.activeAddress; existingHost.activeAddress = host.activeAddress;
[existingHost.activeAddressPool addObject:host.activeAddress];
existingHost.state = host.state; existingHost.state = host.state;
return NO; return NO; // returning a "NO" here means Updating addresses of existing host
} }
else { else {
@synchronized (_hostQueue) { @synchronized (_hostQueue) {
+14 -1
View File
@@ -41,11 +41,21 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
} }
- (NSArray*) getHostAddressList { - (NSArray*) getHostAddressList {
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:3]; NSMutableArray *array = [[NSMutableArray alloc] init];
if (_host.localAddress != nil) { if (_host.localAddress != nil) {
[array addObject:_host.localAddress]; [array addObject:_host.localAddress];
} }
if(_host.activeAddressPool.count>0){
for(NSString* address in _host.activeAddressPool){
if([address containsString:@":"]) break;
[array addObject:address];
}
for(NSString* address in _host.activeAddressPool){
if(![address containsString:@":"]) break;
[array addObject:address];
}
}
if (_host.address != nil) { if (_host.address != nil) {
[array addObject:_host.address]; [array addObject:_host.address];
} }
@@ -61,6 +71,7 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
// to preserve insertion order of addresses. // to preserve insertion order of addresses.
for (int i = 0; i < [array count]; i++) { for (int i = 0; i < [array count]; i++) {
NSString *addr1 = [array objectAtIndex:i]; NSString *addr1 = [array objectAtIndex:i];
NSLog(@"iterates discovery addrs %@, host: %@", addr1, _host.name);
for (int j = 1; j < [array count]; j++) { for (int j = 1; j < [array count]; j++) {
if (i == j) { if (i == j) {
@@ -104,6 +115,8 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
receivedResponse = [self checkResponse:serverInfoResp]; receivedResponse = [self checkResponse:serverInfoResp];
if (receivedResponse) { if (receivedResponse) {
_host.activeAddress = address; _host.activeAddress = address;
if(!_host.activeAddressPool) _host.activeAddressPool = [[NSMutableSet alloc] init];
[_host.activeAddressPool addObject:address];
[serverInfoResp populateHost:_host]; [serverInfoResp populateHost:_host];
// Update the database using the response // Update the database using the response
+1
View File
@@ -228,6 +228,7 @@ static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp";
Log(LOG_I, @"IPv6 address chosen: %@ -> %@", [service hostName], host.ipv6Address); Log(LOG_I, @"IPv6 address chosen: %@ -> %@", [service hostName], host.ipv6Address);
host.activeAddress = host.localAddress; host.activeAddress = host.localAddress;
// [host.activeAddressPool addObject:host.localAddress];
host.name = service.hostName; host.name = service.hostName;
[self.callback updateHost:host]; [self.callback updateHost:host];
}); });
+2
View File
@@ -46,6 +46,7 @@
// If we reached this host through this port, store our port there // If we reached this host through this port, store our port there
if (host.activeAddress && [lanAddr isEqualToString:[Utils addressPortStringToAddress:host.activeAddress]]) { if (host.activeAddress && [lanAddr isEqualToString:[Utils addressPortStringToAddress:host.activeAddress]]) {
localPort = [Utils addressPortStringToPort:host.activeAddress]; localPort = [Utils addressPortStringToPort:host.activeAddress];
[host.activeAddressPool addObject:host.activeAddress];
} }
else if (host.localAddress) { else if (host.localAddress) {
// If there's an existing local address, use the port from that // If there's an existing local address, use the port from that
@@ -57,6 +58,7 @@
} }
host.localAddress = [Utils addressAndPortToAddressPortString:lanAddr port:localPort]; host.localAddress = [Utils addressAndPortToAddressPortString:lanAddr port:localPort];
[host.activeAddressPool addObject:lanAddr];
} }
// This is a Sunshine extension for WAN port remapping // This is a Sunshine extension for WAN port remapping
@@ -765,6 +765,10 @@ static NSMutableSet* hostList;
[hostNotFoundAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; [hostNotFoundAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self hideLoadingFrame:^{ [self hideLoadingFrame:^{
if([error isEqualToString:[LocalizationHelper localizedStringForKey:@"Host information updated"]]){
DataManager* dataMan = [[DataManager alloc] init];
[dataMan updateHost:host];
}
[[self activeViewController] presentViewController:hostNotFoundAlert animated:YES completion:nil]; [[self activeViewController] presentViewController:hostNotFoundAlert animated:YES completion:nil];
}]; }];
}); });