diff options
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 36 | ||||
-rw-r--r-- | Source/SPSSHTunnel.m | 6 |
2 files changed, 31 insertions, 11 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index 549d0013..8fc42a3e 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -461,28 +461,50 @@ static BOOL sTruncateLongFieldInLogs = YES; mConnected = NO; isDisconnecting = NO; - // If there is a tunnel, ensure it's disconnected and attempt to reconnect it in blocking fashion + // If there is a proxy, ensure it's disconnected and attempt to reconnect it in blocking fashion if (connectionProxy) { [connectionProxy setConnectionStateChangeSelector:nil delegate:nil]; if ([connectionProxy state] != PROXY_STATE_IDLE) [connectionProxy disconnect]; + + // Loop until the proxy has disconnected or the connection timeout has passed + NSDate *proxyDisconnectStartDate = [NSDate date], *eventLoopStartDate; + while ([connectionProxy state] != PROXY_STATE_IDLE + && [[NSDate date] timeIntervalSinceDate:proxyDisconnectStartDate] < connectionTimeout) + { + eventLoopStartDate = [NSDate date]; + [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; + if ([[NSDate date] timeIntervalSinceDate:eventLoopStartDate] < 0.25) { + usleep(250000 - (100000 * [[NSDate date] timeIntervalSinceDate:eventLoopStartDate])); + } + } + + // Reconnect the proxy, looping up to the connection timeout [connectionProxy connect]; - NSDate *tunnelStartDate = [NSDate date], *interfaceInteractionTimer; - - // Allow the tunnel to attempt to connect in a loop + NSDate *proxyStartDate = [NSDate date], *interfaceInteractionTimer; while (1) { + + // If the proxy has connected, break out of the loop if ([connectionProxy state] == PROXY_STATE_CONNECTED) { connectionPort = [connectionProxy localPort]; break; } - if ([[NSDate date] timeIntervalSinceDate:tunnelStartDate] > (connectionTimeout + 1)) { + + // If the proxy connection attempt time has exceeded the timeout, abort. + if ([[NSDate date] timeIntervalSinceDate:proxyStartDate] > (connectionTimeout + 1)) { [connectionProxy disconnect]; break; } - // Process events for a short time, allowing dialogs to be shown but waiting for the tunnel + // Process events for a short time, allowing dialogs to be shown but waiting for + // the proxy. Capture how long this interface action took, so that if it was + // longer than the time alloted it can be added to the connection timeout. interfaceInteractionTimer = [NSDate date]; [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; - tunnelStartDate = [tunnelStartDate addTimeInterval:([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] - 0.25)]; + if ([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] > 0.25) { + proxyStartDate = [proxyStartDate addTimeInterval:([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] - 0.25)]; + } else { + usleep(250000 - (100000 * [[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer])); + } } currentProxyState = [connectionProxy state]; diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index e6d9729a..46ceea97 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -163,7 +163,7 @@ - (void) connect { localPort = 0; - + if (connectionState != PROXY_STATE_IDLE) return; [debugMessages removeAllObjects]; [NSThread detachNewThreadSelector:@selector(launchTask:) toTarget: self withObject: nil ]; @@ -350,12 +350,10 @@ - (void)disconnect { if (connectionState == PROXY_STATE_IDLE) return; - + // Before terminating the tunnel, check that it's actually running. This is to accommodate tunnels which // suddenly disappear as a result of network disconnections. if ([task isRunning]) [task terminate]; - - connectionState = PROXY_STATE_IDLE; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } |