mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-05-19 16:20:15 +00:00
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:
@@ -24,6 +24,8 @@
|
|||||||
- (void) resetDiscoveryState;
|
- (void) resetDiscoveryState;
|
||||||
- (BOOL) addHostToDiscovery:(TemporaryHost*)host;
|
- (BOOL) addHostToDiscovery:(TemporaryHost*)host;
|
||||||
- (void) removeHostFromDiscovery:(TemporaryHost*)host;
|
- (void) removeHostFromDiscovery:(TemporaryHost*)host;
|
||||||
|
- (void) pauseDiscoveryForHost:(TemporaryHost *)host;
|
||||||
|
- (void) resumeDiscoveryForHost:(TemporaryHost *)host;
|
||||||
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(TemporaryHost*, NSString*))callback;
|
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(TemporaryHost*, NSString*))callback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
@implementation DiscoveryManager {
|
@implementation DiscoveryManager {
|
||||||
NSMutableArray* _hostQueue;
|
NSMutableArray* _hostQueue;
|
||||||
|
NSMutableSet* _pausedHosts;
|
||||||
id<DiscoveryCallback> _callback;
|
id<DiscoveryCallback> _callback;
|
||||||
MDNSManager* _mdnsMan;
|
MDNSManager* _mdnsMan;
|
||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
_callback = callback;
|
_callback = callback;
|
||||||
shouldDiscover = NO;
|
shouldDiscover = NO;
|
||||||
_hostQueue = [NSMutableArray array];
|
_hostQueue = [NSMutableArray array];
|
||||||
|
_pausedHosts = [NSMutableSet set];
|
||||||
for (TemporaryHost* host in hosts)
|
for (TemporaryHost* host in hosts)
|
||||||
{
|
{
|
||||||
[self addHostToDiscovery:host];
|
[self addHostToDiscovery:host];
|
||||||
@@ -85,10 +87,12 @@
|
|||||||
|
|
||||||
@synchronized (_hostQueue) {
|
@synchronized (_hostQueue) {
|
||||||
for (TemporaryHost* host in _hostQueue) {
|
for (TemporaryHost* host in _hostQueue) {
|
||||||
|
if (![_pausedHosts containsObject:host]) {
|
||||||
[_opQueue addOperation:[self createWorkerForHost:host]];
|
[_opQueue addOperation:[self createWorkerForHost:host]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) stopDiscovery {
|
- (void) stopDiscovery {
|
||||||
if (!shouldDiscover) {
|
if (!shouldDiscover) {
|
||||||
@@ -168,6 +172,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[_hostQueue removeObject:host];
|
[_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]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,10 @@ static NSMutableSet* hostList;
|
|||||||
// Capture the host here because it can change once we
|
// Capture the host here because it can change once we
|
||||||
// leave the main thread
|
// leave the main thread
|
||||||
TemporaryHost* host = _selectedHost;
|
TemporaryHost* host = _selectedHost;
|
||||||
|
if (host == nil) {
|
||||||
|
[self hideLoadingFrame: nil];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ([host.appList count] > 0) {
|
if ([host.appList count] > 0) {
|
||||||
usingCachedAppList = true;
|
usingCachedAppList = true;
|
||||||
@@ -149,11 +153,11 @@ static NSMutableSet* hostList;
|
|||||||
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
|
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
// Exempt this host from discovery while handling the applist query
|
// Exempt this host from discovery while handling the applist query
|
||||||
[self->_discMan removeHostFromDiscovery:host];
|
[self->_discMan pauseDiscoveryForHost:host];
|
||||||
|
|
||||||
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress serverCert:host.serverCert uniqueID:self->_uniqueId];
|
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress serverCert:host.serverCert uniqueID:self->_uniqueId];
|
||||||
|
|
||||||
[self->_discMan addHostToDiscovery:host];
|
[self->_discMan resumeDiscoveryForHost:host];
|
||||||
|
|
||||||
if (![appListResp isStatusOk] || [appListResp getAppList] == nil) {
|
if (![appListResp isStatusOk] || [appListResp getAppList] == nil) {
|
||||||
Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage);
|
Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage);
|
||||||
@@ -340,10 +344,10 @@ static NSMutableSet* hostList;
|
|||||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
|
|
||||||
// Exempt this host from discovery while handling the serverinfo request
|
// Exempt this host from discovery while handling the serverinfo request
|
||||||
[self->_discMan removeHostFromDiscovery:host];
|
[self->_discMan pauseDiscoveryForHost:host];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest:false]
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest:false]
|
||||||
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||||
[self->_discMan addHostToDiscovery:host];
|
[self->_discMan resumeDiscoveryForHost:host];
|
||||||
|
|
||||||
if (![serverInfoResp isStatusOk]) {
|
if (![serverInfoResp isStatusOk]) {
|
||||||
Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage);
|
Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage);
|
||||||
@@ -612,7 +616,7 @@ static NSMutableSet* hostList;
|
|||||||
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
||||||
|
|
||||||
// Exempt this host from discovery while handling the quit operation
|
// Exempt this host from discovery while handling the quit operation
|
||||||
[self->_discMan removeHostFromDiscovery:app.host];
|
[self->_discMan pauseDiscoveryForHost:app.host];
|
||||||
[hMan executeRequestSynchronously:quitRequest];
|
[hMan executeRequestSynchronously:quitRequest];
|
||||||
if (quitResponse.statusCode == 200) {
|
if (quitResponse.statusCode == 200) {
|
||||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
@@ -629,7 +633,7 @@ static NSMutableSet* hostList;
|
|||||||
[serverInfoResp populateHost:app.host];
|
[serverInfoResp populateHost:app.host];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[self->_discMan addHostToDiscovery:app.host];
|
[self->_discMan resumeDiscoveryForHost:app.host];
|
||||||
|
|
||||||
// If it fails, display an error and stop the current operation
|
// If it fails, display an error and stop the current operation
|
||||||
if (quitResponse.statusCode != 200) {
|
if (quitResponse.statusCode != 200) {
|
||||||
|
|||||||
Reference in New Issue
Block a user