Fix race condition that could cause pairing state to be lost

If a mDNS response for a host happened during the period where we
had removed the host from discovery, it would be re-added by mDNS
without the pairing cert. Now we no longer completely remove the host
and instead just remember that it's paused.
This commit is contained in:
Cameron Gutman
2020-04-18 17:16:53 -07:00
parent b833d3b3b7
commit 4aca666df4
3 changed files with 44 additions and 7 deletions

View File

@@ -24,6 +24,8 @@
- (void) resetDiscoveryState;
- (BOOL) addHostToDiscovery:(TemporaryHost*)host;
- (void) removeHostFromDiscovery:(TemporaryHost*)host;
- (void) pauseDiscoveryForHost:(TemporaryHost *)host;
- (void) resumeDiscoveryForHost:(TemporaryHost *)host;
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(TemporaryHost*, NSString*))callback;
@end

View File

@@ -17,6 +17,7 @@
@implementation DiscoveryManager {
NSMutableArray* _hostQueue;
NSMutableSet* _pausedHosts;
id<DiscoveryCallback> _callback;
MDNSManager* _mdnsMan;
NSOperationQueue* _opQueue;
@@ -33,6 +34,7 @@
_callback = callback;
shouldDiscover = NO;
_hostQueue = [NSMutableArray array];
_pausedHosts = [NSMutableSet set];
for (TemporaryHost* host in hosts)
{
[self addHostToDiscovery:host];
@@ -85,7 +87,9 @@
@synchronized (_hostQueue) {
for (TemporaryHost* host in _hostQueue) {
[_opQueue addOperation:[self createWorkerForHost:host]];
if (![_pausedHosts containsObject:host]) {
[_opQueue addOperation:[self createWorkerForHost:host]];
}
}
}
}
@@ -168,6 +172,33 @@
}
[_hostQueue removeObject:host];
[_pausedHosts removeObject:host];
}
}
- (void) pauseDiscoveryForHost:(TemporaryHost *)host {
@synchronized (_hostQueue) {
// Stop any worker for the host
for (DiscoveryWorker* worker in [_opQueue operations]) {
if ([worker getHost] == host) {
[worker cancel];
}
}
// Add it to the paused hosts list
[_pausedHosts addObject:host];
}
}
- (void) resumeDiscoveryForHost:(TemporaryHost *)host {
@synchronized (_hostQueue) {
// Remove it from the paused hosts list
[_pausedHosts removeObject:host];
// Start discovery again
if (shouldDiscover) {
[_opQueue addOperation:[self createWorkerForHost:host]];
}
}
}