diff options
Diffstat (limited to 'src/leap/base')
-rw-r--r-- | src/leap/base/checks.py | 23 | ||||
-rw-r--r-- | src/leap/base/network.py | 17 | ||||
-rw-r--r-- | src/leap/base/tests/test_checks.py | 38 |
3 files changed, 76 insertions, 2 deletions
diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 4d4a5d8b..e5767018 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -12,6 +12,9 @@ from leap.base import exceptions logger = logging.getLogger(name=__name__) +#EVENTS OF NOTE +EVENT_CONNECT_REFUSED = "[ECONNREFUSED]: Connection refused (code=111)" + class LeapNetworkChecker(object): """ @@ -34,6 +37,8 @@ class LeapNetworkChecker(object): if self.provider_gateway: checker.ping_gateway(self.provider_gateway) + checker.parse_log_and_react([], ()) + def check_internet_connection(self): try: # XXX remove this hardcoded random ip @@ -136,3 +141,21 @@ class LeapNetworkChecker(object): return True except socket.gaierror: raise exceptions.CannotResolveDomainError + + def parse_log_and_react(self, log, error_matrix=None): + """ + compares the recent openvpn status log to + strings passed in and executes the callbacks passed in. + @param log: openvpn log + @type log: list of strings + @param error_matrix: tuples of strings and tuples of callbacks + @type error_matrix: tuples strings and call backs + """ + for line in log: + # we could compile a regex here to save some cycles up -- kali + for each in error_matrix: + error, callbacks = each + if error in line: + for cb in callbacks: + if callable(cb): + cb() diff --git a/src/leap/base/network.py b/src/leap/base/network.py index 765d8ea0..d841e692 100644 --- a/src/leap/base/network.py +++ b/src/leap/base/network.py @@ -21,8 +21,8 @@ class NetworkCheckerThread(object): connection. """ def __init__(self, *args, **kwargs): + self.status_signals = kwargs.pop('status_signals', None) - #self.watcher_cb = kwargs.pop('status_signals', None) self.error_cb = kwargs.pop( 'error_cb', lambda exc: logger.error("%s", exc.message)) @@ -48,6 +48,7 @@ class NetworkCheckerThread(object): (self.error_cb,)) def stop(self): + self.process_handle.join(timeout=0.1) self.shutdown.set() logger.debug("network checked stopped.") @@ -59,6 +60,7 @@ class NetworkCheckerThread(object): #here all the observers in fail_callbacks expect one positional argument, #which is exception so we can try by passing a lambda with logger to #check it works. + def _network_checks_thread(self, fail_callbacks): #TODO: replace this with waiting for a signal from openvpn while True: @@ -69,11 +71,15 @@ class NetworkCheckerThread(object): # XXX ??? why do we sleep here??? # aa: If the openvpn isn't up and running yet, # let's give it a moment to breath. + #logger.error('NOT DEFAULT ROUTE!----') + # Instead of this, we should flag when the + # iface IS SUPPOSED to be up imo. -- kali sleep(1) fail_observer_dict = dict((( observer, process_events(observer)) for observer in fail_callbacks)) + while not self.shutdown.is_set(): try: self.checker.check_tunnel_default_interface() @@ -83,11 +89,18 @@ class NetworkCheckerThread(object): for obs in fail_observer_dict: fail_observer_dict[obs].send(exc) sleep(ROUTE_CHECK_INTERVAL) + #reset event + # I see a problem with this. You cannot stop it, it + # resets itself forever. -- kali + + # XXX use QTimer for the recurrent triggers, + # and ditch the sleeps. + logger.debug('resetting event') self.shutdown.clear() def _launch_recurrent_network_checks(self, fail_callbacks): - #we need to wrap the fail callback in a tuple + # XXX reimplement using QTimer -- kali watcher = launch_thread( self._network_checks_thread, (fail_callbacks,)) diff --git a/src/leap/base/tests/test_checks.py b/src/leap/base/tests/test_checks.py index 7a694f89..645e615c 100644 --- a/src/leap/base/tests/test_checks.py +++ b/src/leap/base/tests/test_checks.py @@ -37,6 +37,8 @@ class LeapNetworkCheckTest(BaseLeapTest): "missing meth") self.assertTrue(hasattr(checker, "ping_gateway"), "missing meth") + self.assertTrue(hasattr(checker, "parse_log_and_react"), + "missing meth") def test_checker_should_actually_call_all_tests(self): checker = checks.LeapNetworkChecker() @@ -45,6 +47,7 @@ class LeapNetworkCheckTest(BaseLeapTest): self.assertTrue(mc.check_internet_connection.called, "not called") self.assertTrue(mc.check_tunnel_default_interface.called, "not called") self.assertTrue(mc.is_internet_up.called, "not called") + self.assertTrue(mc.parse_log_and_react.called, "not called") # ping gateway only called if we pass provider_gw checker = checks.LeapNetworkChecker(provider_gw="0.0.0.0") @@ -54,6 +57,7 @@ class LeapNetworkCheckTest(BaseLeapTest): self.assertTrue(mc.check_tunnel_default_interface.called, "not called") self.assertTrue(mc.ping_gateway.called, "not called") self.assertTrue(mc.is_internet_up.called, "not called") + self.assertTrue(mc.parse_log_and_react.called, "not called") def test_get_default_interface_no_interface(self): checker = checks.LeapNetworkChecker() @@ -134,6 +138,40 @@ class LeapNetworkCheckTest(BaseLeapTest): mock_ping.side_effect = exceptions.NoConnectionToGateway checker.check_internet_connection() + def test_parse_log_and_react(self): + checker = checks.LeapNetworkChecker() + to_call = Mock() + log = [("leap.openvpn - INFO - Mon Nov 19 13:36:24 2012 " + "read UDPv4 [ECONNREFUSED]: Connection refused (code=111)"] + err_matrix = [(checks.EVENT_CONNECT_REFUSED, (to_call, ))] + checker.parse_log_and_react(log, err_matrix) + self.assertTrue(to_call.called) + + log = [("2012-11-19 13:36:26,177 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:24 2012 ERROR: Linux route delete command " + "failed: external program exited"), + ("2012-11-19 13:36:26,178 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:24 2012 ERROR: Linux route delete command " + "failed: external program exited"), + ("2012-11-19 13:36:26,180 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:24 2012 ERROR: Linux route delete command " + "failed: external program exited"), + ("2012-11-19 13:36:26,181 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:24 2012 /sbin/ifconfig tun0 0.0.0.0"), + ("2012-11-19 13:36:26,182 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:24 2012 Linux ip addr del failed: external " + "program exited with error stat"), + ("2012-11-19 13:36:26,183 - leap.openvpn - INFO - " + "Mon Nov 19 13:36:26 2012 SIGTERM[hard,] received, process" + "exiting"), ] + to_call.reset_mock() + checker.parse_log_and_react(log, err_matrix) + self.assertFalse(to_call.called) + + to_call.reset_mock() + checker.parse_log_and_react([], err_matrix) + self.assertFalse(to_call.called) + @unittest.skipUnless(_uid == 0, "root only") def test_ping_gateway(self): checker = checks.LeapNetworkChecker() |