diff options
author | Kali Kaneko <kali@leap.se> | 2017-08-23 00:34:22 -0400 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2017-08-30 16:18:01 -0400 |
commit | b314c73432da0797fc00e7a6d270b783929d4c08 (patch) | |
tree | 431c515b1c577593952848cd589369a930323e9b /src/leap/bitmask/vpn | |
parent | 2d7543e8c3828a8a0ab7b77b1c3a492c7ff28ed7 (diff) |
[refactor] re-add retries for connecting to management
Diffstat (limited to 'src/leap/bitmask/vpn')
-rw-r--r-- | src/leap/bitmask/vpn/process.py | 29 | ||||
-rw-r--r-- | src/leap/bitmask/vpn/tunnel.py | 25 |
2 files changed, 37 insertions, 17 deletions
diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py index 48d3f1a..4ef9fd9 100644 --- a/src/leap/bitmask/vpn/process.py +++ b/src/leap/bitmask/vpn/process.py @@ -89,6 +89,7 @@ class _VPNProcess(protocol.ProcessProtocol): self._restartfun = restartfun self.restarting = True + self.failed = False self.proto = None self._remotes = remotes @@ -106,18 +107,28 @@ class _VPNProcess(protocol.ProcessProtocol): except Exception as exc: print('[!] Error: %s' % exc) - def _connect_to_management(self): - # TODO -- add retries, twisted style, to this. - # this sometimes raises 'file not found' error + def _connect_to_management(self, retries=30): + if retries == 0: + self.log.error('Timeout whilte connecting to management') + self.failed = True + return + + def retry(retries): + ctr = retries - 1 + self.log.warn( + 'Error connecting to management, retrying. Retries left: %s' % ctr) + reactor.callLater( + 0.1, self._connect_to_management, ctr) + self._d = connectProtocol( self._management_endpoint, ManagementProtocol(verbose=True)) - self._d.addCallback(self._got_management_protocol) - self._d.addErrback(self.log.error) + self._d.addCallbacks( + self._got_management_protocol, + lambda f: retry(retries)) def connectionMade(self): - # TODO cut this wait time when retries are done - reactor.callLater(0.5, self._connect_to_management) + reactor.callLater(0.1, self._connect_to_management) def processExited(self, failure): err = failure.trap( @@ -143,7 +154,9 @@ class _VPNProcess(protocol.ProcessProtocol): Called when the child process exits and all file descriptors associated with it have been closed. """ + self.proto = None exit_code = reason.value.exitCode + if isinstance(exit_code, int): self.log.debug('processEnded, status %d' % (exit_code,)) if self.restarting: @@ -174,6 +187,7 @@ class _VPNProcess(protocol.ProcessProtocol): if not self.proto: status = {'status': 'off', 'error': None} return status + status = {'status': self.proto.state.simple.lower(), 'error': None} if self.proto.traffic: @@ -230,7 +244,6 @@ class _VPNProcess(protocol.ProcessProtocol): self.log.debug('Process Exited Already') def terminate_or_kill(self): - # XXX this returns a deferred return self._launcher.terminate_or_kill( self.terminate, self.kill, self) diff --git a/src/leap/bitmask/vpn/tunnel.py b/src/leap/bitmask/vpn/tunnel.py index d05a50e..d9a8be3 100644 --- a/src/leap/bitmask/vpn/tunnel.py +++ b/src/leap/bitmask/vpn/tunnel.py @@ -76,11 +76,15 @@ class ConfiguredTunnel(object): self._port = port self._vpnproc = None + @defer.inlineCallbacks def start(self): - return self._start_vpn() + started = yield self._start_vpn() + defer.returnValue(started) + @defer.inlineCallbacks def stop(self): - return self._stop_vpn(restart=False) + stopped = yield self._stop_vpn(restart=False) + defer.returnValue(stopped) # status @@ -96,6 +100,7 @@ class ConfiguredTunnel(object): # VPN Control + @defer.inlineCallbacks def _start_vpn(self): self.log.debug('VPN: start') args = [self._vpnconfig, self._providerconfig, self._host, @@ -105,15 +110,15 @@ class ConfiguredTunnel(object): vpnproc = VPNProcess(*args, **kwargs) self._vpnproc = vpnproc - self._start_pre_up(vpnproc) + self.__start_pre_up(vpnproc) cmd = self.__start_get_cmd(vpnproc) - # XXX this should be a deferred - running = self.__start_spawn_proc(vpnproc, cmd) + + running = yield self.__start_spawn_proc(vpnproc, cmd) if running: vpnproc.pid = running.pid - return True + defer.returnValue(True) else: - return False + defer.returnValue(False) def __start_pre_up(self, proc): try: @@ -147,6 +152,7 @@ class ConfiguredTunnel(object): reactor.callLater( self.RESTART_WAIT, self.start) + @defer.inlineCallbacks def _stop_vpn(self, restart=False): """ Stops the openvpn subprocess. @@ -162,11 +168,12 @@ class ConfiguredTunnel(object): if self._vpnproc is None: self.log.debug('Tried to stop VPN but no process found') - return + defer.returnValue(False) self._vpnproc.restarting = restart self.__stop_pre_down(self._vpnproc) - self._vpnproc.terminate_or_kill() + stopped = yield self._vpnproc.terminate_or_kill() + defer.returnValue(stopped) def __stop_pre_down(self, proc): try: |