From 336c21f8f5691f30cdf43c025695c5476be7fcec Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 13 Jun 2013 18:04:38 -0300 Subject: Autoselect VPN gateway based on timezone. --- src/leap/services/eip/eipconfig.py | 91 +++++++++++++++++++++++++++++++++-- src/leap/services/eip/vpnlaunchers.py | 12 +++-- 2 files changed, 96 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/leap/services/eip/eipconfig.py b/src/leap/services/eip/eipconfig.py index 0a7d2b23..f7d03963 100644 --- a/src/leap/services/eip/eipconfig.py +++ b/src/leap/services/eip/eipconfig.py @@ -21,6 +21,8 @@ Provider configuration import logging import os import re +import datetime +import time import ipaddr @@ -32,6 +34,79 @@ from leap.services.eip.eipspec import eipservice_config_spec logger = logging.getLogger(__name__) +class VPNGatewaySelector(object): + """ + VPN Gateway selector. + """ + + def __init__(self, eipconfig): + ''' + Constructor for VPNGatewaySelector. + + :param eipconfig: a valid EIP Configuration. + :type eipconfig: EIPConfig + ''' + leap_assert_type(eipconfig, EIPConfig) + self._local_offset = 0 # defaults to GMT + self._local_timezone = None + self._set_local_offset() + self._eipconfig = eipconfig + + def _get_best_gateway(self): + """ + Returns index of the closest gateway, using timezones offsets. + + :rtype: int + """ + best_gateway = (-1, 99) # gateway, distance + locations = self._eipconfig.get_locations() + gateways = self._eipconfig.get_gateways() + for idx, gateway in enumerate(gateways): + gateway_offset = int(locations[gateway['location']]['timezone']) + gateway_distance = self._get_timezone_distance(gateway_offset) + if gateway_distance < best_gateway[1]: + best_gateway = (idx, gateway_distance) + + return best_gateway[0] + + def get_best_gateway_ip(self): + """ + Returns the ip of the best possible gateway. + + :rtype: An IPv4Address or IPv6Address object. + """ + best_gateway = self._get_best_gateway() + gateway_ip = self._eipconfig.get_gateway_ip(best_gateway) + + return gateway_ip + + def _get_timezone_distance(self, offset): + ''' + Returns the distance between the local timezone and + the one with offset 'offset'. + + :param offset: the distance of a timezone to GMT. + :type offset: int + :returns: distance between local offset and param offset. + :rtype: int + ''' + delta1 = datetime.timedelta(hours=offset) + delta2 = self._local_offset + diff = abs(delta1 - delta2) + hours = diff.seconds / (60 * 60) + return hours + + def _set_local_offset(self): + ''' + Sets the distance between GMT and the local timezone. + ''' + local_offset = time.timezone + if time.daylight: + local_offset = time.altzone + + self._local_offset = datetime.timedelta(seconds=-local_offset) + + class EIPConfig(BaseConfig): """ Provider configuration abstraction class @@ -56,6 +131,14 @@ class EIPConfig(BaseConfig): # TODO: create an abstraction for gateways return self._safe_get_value("gateways") + def get_locations(self): + ''' + Returns a list of locations + + :rtype: dict + ''' + return self._safe_get_value("locations") + def get_openvpn_configuration(self): """ Returns a dictionary containing the openvpn configuration @@ -63,8 +146,8 @@ class EIPConfig(BaseConfig): These are sanitized with alphanumeric whitelist. - @returns: openvpn configuration dict - @rtype: C{dict} + :returns: openvpn configuration dict + :rtype: C{dict} """ ovpncfg = self._safe_get_value("openvpn_configuration") config = {} @@ -84,7 +167,9 @@ class EIPConfig(BaseConfig): def get_gateway_ip(self, index=0): """ - Returns the ip of the gateway + Returns the ip of the gateway. + + :rtype: An IPv4Address or IPv6Address object. """ gateways = self.get_gateways() leap_assert(len(gateways) > 0, "We don't have any gateway!") diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 6c2ff006..fa2989bc 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -34,7 +34,7 @@ from functools import partial from leap.common.check import leap_assert, leap_assert_type from leap.common.files import which from leap.config.providerconfig import ProviderConfig -from leap.services.eip.eipconfig import EIPConfig +from leap.services.eip.eipconfig import EIPConfig, VPNGatewaySelector logger = logging.getLogger(__name__) @@ -228,7 +228,8 @@ class LinuxVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() logger.debug("Using gateway ip %s" % (gateway_ip,)) @@ -391,7 +392,9 @@ class DarwinVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() + logger.debug("Using gateway ip %s" % (gateway_ip,)) args += [ @@ -530,7 +533,8 @@ class WindowsVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() logger.debug("Using gateway ip %s" % (gateway_ip,)) -- cgit v1.2.3 From e6e88154f3b274ff97474a26a36dd6453f55de0b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 14 Jun 2013 12:51:18 -0300 Subject: Bugfix: add logs to history. Closes #2871. --- src/leap/util/leap_log_handler.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index 5b8ae789..e5bc87e1 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -31,16 +31,16 @@ class LogHandler(logging.Handler): MESSAGE_KEY = 'message' RECORD_KEY = 'record' - # TODO This is going to eat lots of memory after some time. - # Should be pruned at some moment. - _log_history = [] - def __init__(self, qtsignal): """ LogHander initialization. Calls parent method and keeps a reference to the qtsignal that will be used to fire the gui update. """ + # TODO This is going to eat lots of memory after some time. + # Should be pruned at some moment. + self._log_history = [] + logging.Handler.__init__(self) self._qtsignal = qtsignal @@ -85,6 +85,7 @@ class LogHandler(logging.Handler): self._set_format(logRecord.levelname) log = self.format(logRecord) log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} + self._log_history.append(log_item) self._qtsignal(log_item) -- cgit v1.2.3