summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-06-28 02:34:09 +0200
committerRuben Pollan <meskio@sindominio.net>2017-06-29 00:32:21 +0200
commit94d339ca4db68c0788f8ae768d69b16c1e80d676 (patch)
tree78d529c8185eb81c594fafa9c9eb7396ef33a735
parentc15e59940b15d6fd4128809287882eb0386f783f (diff)
[feat] restart openvpn automatically
Right now we are trying to restart openvpn every 2 seconds, for ever (or until the user turns down the VPN). Maybe we can be more smart making the retries longer with time. - Resolves: #8049
-rw-r--r--docs/changelog.rst1
-rw-r--r--src/leap/bitmask/vpn/_control.py20
-rw-r--r--src/leap/bitmask/vpn/process.py4
3 files changed, 15 insertions, 10 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 455be5da..64a47e89 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -13,6 +13,7 @@ Features
- `#8765 <https://0xacab.org/leap/bitmask-dev/issues/8765>`_: Require a global authentication token for the api
- `#8819 <https://0xacab.org/leap/bitmask-dev/issues/8819>`_: Send key to provider if a new priv key is putted in the keyring
- `#8821 <https://0xacab.org/leap/bitmask-dev/issues/8821>`_: Add a 'fetch' flag to key export
+- `#8049 <https://0xacab.org/leap/bitmask-dev/issues/8049>`_: Restart the VPN automatically
- Initial cli port of the legacy vpn code
- Add VPN API to bitmask.js
- Add vpn get_cert command
diff --git a/src/leap/bitmask/vpn/_control.py b/src/leap/bitmask/vpn/_control.py
index 98e94bba..1c352bed 100644
--- a/src/leap/bitmask/vpn/_control.py
+++ b/src/leap/bitmask/vpn/_control.py
@@ -1,7 +1,7 @@
import os
from twisted.internet.task import LoopingCall
-from twisted.internet import reactor
+from twisted.internet import reactor, defer
from twisted.logger import Logger
from .process import VPNProcess
@@ -91,8 +91,9 @@ class VPNControl(object):
self._start_pollers()
return True
+ @defer.inlineCallbacks
def restart(self):
- self.stop(shutdown=False, restart=True)
+ yield self.stop(shutdown=False, restart=True)
reactor.callLater(
self.RESTART_WAIT, self.start)
@@ -115,6 +116,7 @@ class VPNControl(object):
self.log.error('Error on vpn pre-down {0!r}'.format(e))
raise
+ d = defer.succeed(True)
if IS_LINUX:
# TODO factor this out to a linux-only launcher mechanism.
# First we try to be polite and send a SIGTERM...
@@ -122,17 +124,17 @@ class VPNControl(object):
# We assume that the only valid stops are initiated
# by an user action, not hard restarts
self._user_stopped = not restart
- self._vpnproc.restarting = restart
self._sentterm = True
self._vpnproc.terminate(shutdown=shutdown)
# ...but we also trigger a countdown to be unpolite
# if strictly needed.
+ d = defer.Deferred()
reactor.callLater(
- self.TERMINATE_WAIT, self._kill_if_left_alive)
+ self.TERMINATE_WAIT, self._kill_if_left_alive, d)
self._vpnproc.traffic_status = (0, 0)
- return True
+ return d
@property
def status(self):
@@ -155,7 +157,7 @@ class VPNControl(object):
self._vpnproc.aborted = True
self._vpnproc.killProcess()
- def _kill_if_left_alive(self, tries=0):
+ def _kill_if_left_alive(self, deferred, tries=0):
"""
Check if the process is still alive, and send a
SIGKILL after a timeout period.
@@ -163,15 +165,16 @@ class VPNControl(object):
:param tries: counter of tries, used in recursion
:type tries: int
"""
- while tries < self.TERMINATE_MAXTRIES:
+ if tries < self.TERMINATE_MAXTRIES:
if self._vpnproc.transport.pid is None:
+ deferred.callback(True)
return
else:
self.log.debug('Process did not die, waiting...')
tries += 1
reactor.callLater(self.TERMINATE_WAIT,
- self._kill_if_left_alive, tries)
+ self._kill_if_left_alive, deferred, tries)
return
# after running out of patience, we try a killProcess
@@ -180,6 +183,7 @@ class VPNControl(object):
self._killit()
except OSError:
self.log.error('Could not kill process!')
+ deferred.callback(True)
def _start_pollers(self):
"""
diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py
index 170df446..5b8bc1b7 100644
--- a/src/leap/bitmask/vpn/process.py
+++ b/src/leap/bitmask/vpn/process.py
@@ -96,7 +96,7 @@ class _VPNProcess(protocol.ProcessProtocol, _management.VPNManagement):
self._status = _status.VPNStatus()
self.set_watcher(self._status)
- self.restarting = False
+ self.restarting = True
self._remotes = remotes
@property
@@ -171,7 +171,7 @@ class _VPNProcess(protocol.ProcessProtocol, _management.VPNManagement):
self.log.debug('processEnded, status %d' % (exit_code,))
if self.restarting:
self.log.debug('Restarting VPN process')
- reactor.callLater(2, self._restartfun)
+ self._restartfun()
# polling