diff --git a/README.md b/README.md index c44dd7f..161f2f8 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ * Download and extract the controller framework ``` - wget -O controller-framework-beta-v0.3.tar.gz https://goo.gl/UQHfCE - tar xvzf controller-framework-beta-v0.3.tar.gz - cd controller-framework-beta-v0.3 + wget -O controller-framework-beta-v0.3.1.tar.gz https://goo.gl/e7BSpo + tar xvzf controller-framework-beta-v0.3.1.tar.gz + cd controller-framework-beta-v0.3.1 ``` * Run IPOP-Tincan @@ -22,14 +22,15 @@ After starting IPOP-Tincan, you can either run the GroupVPN controller or the So * Change directory to gvpn ``` - cd gvpn + cd controller/modules/gvpn ``` -* Change config.json according to the requirement. Add xmpp_username, xmpp_password and xmpp_host to the config file and ensure that the IP addresses are different for all the nodes. +* Change gvpn-config.json according to the requirement. Add xmpp_username, xmpp_password and xmpp_host to the config file and ensure that the IP addresses are different for all the nodes. * Start GroupVPN controller ``` - python CFx.py -c config.json &> log.txt & + cd ../../.. + python -m controller.framework.CFx -c controller/modules/gvpn-config.json &> log.txt & ``` * Check the status @@ -41,14 +42,15 @@ After starting IPOP-Tincan, you can either run the GroupVPN controller or the So * Change directory to svpn ``` - cd svpn + cd controller/modules/svpn ``` -* Change config.json according to the requirement. Add xmpp_username, xmpp_password and xmpp_host to the config file. +* Change svpn-config.json according to the requirement. Add xmpp_username, xmpp_password and xmpp_host to the config file. * Start SocialVPN controller ``` - python CFx.py -c config.json &> log.txt & + cd ../../.. + python -m controller.framework.CFx -c controller/modules/svpn-config.json &> log.txt & ``` * Check the status diff --git a/controller/__init__.py b/controller/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gvpn/CBT.py b/controller/framework/CBT.py similarity index 100% rename from gvpn/CBT.py rename to controller/framework/CBT.py diff --git a/gvpn/CFx.py b/controller/framework/CFx.py similarity index 93% rename from gvpn/CFx.py rename to controller/framework/CFx.py index cf0145e..6c1041b 100644 --- a/gvpn/CFx.py +++ b/controller/framework/CFx.py @@ -21,14 +21,6 @@ class CFX(object): def __init__(self): - with open('config.json') as data_file: - - # Read config.json into an OrderedDict, to load the - # modules in the order in which they appear in config.json - self.json_data = json.load(data_file, - object_pairs_hook=OrderedDict) - - # Parse config and update default CONFIG in ipoplib self.parse_config() ipoplib.CONFIG = self.CONFIG @@ -123,8 +115,10 @@ def initialize(self,): try: time.sleep(3) self.sock_icc.bind((self.ip6, self.CONFIG['CFx']["icc_port"])) + except KeyboardInterrupt: + self.terminate() except Exception as e: - print("Wait until ipop tap is available") + print("Wait until IPOP Tap is available") continue else: break @@ -132,7 +126,7 @@ def initialize(self,): self.sock_list.append(self.sock_icc) else: - print "ICC is enabled but ipv6 is not supported. Exiting" + print "ICC is enabled but IPv6 is not supported. Exiting" sys.exit() # Register to the XMPP server @@ -187,7 +181,13 @@ def load_module(self, module_name): self.load_dependencies(module_name) # Dynamically importing the modules - module = importlib.import_module(module_name) + try: + module = importlib.import_module("controller.modules."+module_name) + except: + if(self.vpn_type == "GroupVPN"): + module = importlib.import_module("controller.modules.gvpn."+module_name) + elif(self.vpn_type == "SocialVPN"): + module = importlib.import_module("controller.modules.svpn."+module_name) # Get the class with name key from module module_class = getattr(module, module_name) @@ -277,10 +277,12 @@ def parse_config(self): # Load the config file with open(args.config_file) as f: - loaded_config = json.load(f) - for key in loaded_config: + # Read config file into an OrderedDict, to load the + # modules in the order in which they appear in config.json + self.json_data = json.load(f, object_pairs_hook=OrderedDict) + for key in self.json_data: if(self.CONFIG.get(key, None)): - self.CONFIG[key].update(loaded_config[key]) + self.CONFIG[key].update(self.json_data[key]) if args.config_string: # Load the config string diff --git a/gvpn/CFxHandle.py b/controller/framework/CFxHandle.py similarity index 100% rename from gvpn/CFxHandle.py rename to controller/framework/CFxHandle.py diff --git a/gvpn/ControllerModule.py b/controller/framework/ControllerModule.py similarity index 100% rename from gvpn/ControllerModule.py rename to controller/framework/ControllerModule.py diff --git a/controller/framework/__init__.py b/controller/framework/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gvpn/ipoplib.py b/controller/framework/ipoplib.py similarity index 100% rename from gvpn/ipoplib.py rename to controller/framework/ipoplib.py diff --git a/svpn/LinkManager.py b/controller/modules/LinkManager.py similarity index 97% rename from svpn/LinkManager.py rename to controller/modules/LinkManager.py index 42a03be..0e935f7 100644 --- a/svpn/LinkManager.py +++ b/controller/modules/LinkManager.py @@ -1,4 +1,4 @@ -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class LinkManager(ControllerModule): diff --git a/gvpn/Logger.py b/controller/modules/Logger.py similarity index 96% rename from gvpn/Logger.py rename to controller/modules/Logger.py index 92bfe80..76b74b7 100644 --- a/gvpn/Logger.py +++ b/controller/modules/Logger.py @@ -1,5 +1,5 @@ import logging -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class Logger(ControllerModule): diff --git a/gvpn/TincanListener.py b/controller/modules/TincanListener.py similarity index 97% rename from gvpn/TincanListener.py rename to controller/modules/TincanListener.py index b4709ac..37b2356 100644 --- a/gvpn/TincanListener.py +++ b/controller/modules/TincanListener.py @@ -1,6 +1,6 @@ import select from threading import Thread -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class TincanListener(ControllerModule): diff --git a/gvpn/TincanSender.py b/controller/modules/TincanSender.py similarity index 98% rename from gvpn/TincanSender.py rename to controller/modules/TincanSender.py index 96ea384..cefbd42 100644 --- a/gvpn/TincanSender.py +++ b/controller/modules/TincanSender.py @@ -1,8 +1,9 @@ import json import socket import random -import ipoplib -from ControllerModule import ControllerModule +import controller.framework.ipoplib as ipoplib +from controller.framework.ControllerModule import ControllerModule + class TincanSender(ControllerModule): diff --git a/gvpn/Watchdog.py b/controller/modules/Watchdog.py similarity index 96% rename from gvpn/Watchdog.py rename to controller/modules/Watchdog.py index 58913bf..07de8da 100644 --- a/gvpn/Watchdog.py +++ b/controller/modules/Watchdog.py @@ -1,4 +1,4 @@ -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class Watchdog(ControllerModule): diff --git a/controller/modules/__init__.py b/controller/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gvpn/config.json b/controller/modules/gvpn-config.json similarity index 100% rename from gvpn/config.json rename to controller/modules/gvpn-config.json diff --git a/gvpn/AddressMapper.py b/controller/modules/gvpn/AddressMapper.py similarity index 96% rename from gvpn/AddressMapper.py rename to controller/modules/gvpn/AddressMapper.py index a99dfe0..40c4c58 100644 --- a/gvpn/AddressMapper.py +++ b/controller/modules/gvpn/AddressMapper.py @@ -1,5 +1,5 @@ -from ControllerModule import ControllerModule -from ipoplib import gen_uid +from controller.framework.ipoplib import gen_uid +from controller.framework.ControllerModule import ControllerModule class AddressMapper(ControllerModule): diff --git a/gvpn/BaseTopologyManager.py b/controller/modules/gvpn/BaseTopologyManager.py similarity index 99% rename from gvpn/BaseTopologyManager.py rename to controller/modules/gvpn/BaseTopologyManager.py index edf9a06..c717daf 100644 --- a/gvpn/BaseTopologyManager.py +++ b/controller/modules/gvpn/BaseTopologyManager.py @@ -1,8 +1,8 @@ import time import socket import struct -import ipoplib -from ControllerModule import ControllerModule +import controller.framework.ipoplib as ipoplib +from controller.framework.ControllerModule import ControllerModule class BaseTopologyManager(ControllerModule): diff --git a/gvpn/Monitor.py b/controller/modules/gvpn/Monitor.py similarity index 99% rename from gvpn/Monitor.py rename to controller/modules/gvpn/Monitor.py index 6dcccf9..7dc7fdd 100644 --- a/gvpn/Monitor.py +++ b/controller/modules/gvpn/Monitor.py @@ -1,5 +1,5 @@ import time -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class Monitor(ControllerModule): diff --git a/gvpn/TincanDispatcher.py b/controller/modules/gvpn/TincanDispatcher.py similarity index 98% rename from gvpn/TincanDispatcher.py rename to controller/modules/gvpn/TincanDispatcher.py index b0546bd..5f38afe 100644 --- a/gvpn/TincanDispatcher.py +++ b/controller/modules/gvpn/TincanDispatcher.py @@ -1,5 +1,5 @@ import json -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class TincanDispatcher(ControllerModule): @@ -127,7 +127,7 @@ def processCBT(self, cbt): CBT = self.CFxHandle.createCBT(initiator='TincanDispatcher', recipient='BaseTopologyManager', action='TINCAN_PACKET', - data=data[2:]) + data=data) self.CFxHandle.submitCBT(CBT) else: diff --git a/controller/modules/gvpn/__init__.py b/controller/modules/gvpn/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/svpn/config.json b/controller/modules/svpn-config.json similarity index 100% rename from svpn/config.json rename to controller/modules/svpn-config.json diff --git a/svpn/AddressMapper.py b/controller/modules/svpn/AddressMapper.py similarity index 96% rename from svpn/AddressMapper.py rename to controller/modules/svpn/AddressMapper.py index 56024c9..5c499ff 100644 --- a/svpn/AddressMapper.py +++ b/controller/modules/svpn/AddressMapper.py @@ -1,5 +1,5 @@ -import ipoplib -from ControllerModule import ControllerModule +import controller.framework.ipoplib as ipoplib +from controller.framework.ControllerModule import ControllerModule class AddressMapper(ControllerModule): diff --git a/svpn/BaseTopologyManager.py b/controller/modules/svpn/BaseTopologyManager.py similarity index 99% rename from svpn/BaseTopologyManager.py rename to controller/modules/svpn/BaseTopologyManager.py index 0b06732..89ce9dc 100644 --- a/svpn/BaseTopologyManager.py +++ b/controller/modules/svpn/BaseTopologyManager.py @@ -1,5 +1,5 @@ -import ipoplib -from ControllerModule import ControllerModule +import controller.framework.ipoplib as ipoplib +from controller.framework.ControllerModule import ControllerModule class BaseTopologyManager(ControllerModule): diff --git a/svpn/Monitor.py b/controller/modules/svpn/Monitor.py similarity index 98% rename from svpn/Monitor.py rename to controller/modules/svpn/Monitor.py index b650769..89140e4 100644 --- a/svpn/Monitor.py +++ b/controller/modules/svpn/Monitor.py @@ -1,6 +1,6 @@ import time -import ipoplib -from ControllerModule import ControllerModule +import controller.framework.ipoplib as ipoplib +from controller.framework.ControllerModule import ControllerModule class Monitor(ControllerModule): diff --git a/svpn/TincanDispatcher.py b/controller/modules/svpn/TincanDispatcher.py similarity index 98% rename from svpn/TincanDispatcher.py rename to controller/modules/svpn/TincanDispatcher.py index f4ed947..883a448 100644 --- a/svpn/TincanDispatcher.py +++ b/controller/modules/svpn/TincanDispatcher.py @@ -1,5 +1,5 @@ import json -from ControllerModule import ControllerModule +from controller.framework.ControllerModule import ControllerModule class TincanDispatcher(ControllerModule): diff --git a/controller/modules/svpn/__init__.py b/controller/modules/svpn/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gvpn/LinkManager.py b/gvpn/LinkManager.py deleted file mode 100644 index 42a03be..0000000 --- a/gvpn/LinkManager.py +++ /dev/null @@ -1,68 +0,0 @@ -from ControllerModule import ControllerModule - - -class LinkManager(ControllerModule): - - def __init__(self, CFxHandle, paramDict): - - super(LinkManager, self).__init__() - self.CFxHandle = CFxHandle - self.CMConfig = paramDict - - def initialize(self): - - logCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='Logger', - action='info', - data="LinkManager Loaded") - self.CFxHandle.submitCBT(logCBT) - - def processCBT(self, cbt): - - if(cbt.action == "CREATE_LINK"): - - # cbt.data is a dict containing all the required - # paramters to create a link - - TincanCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='TincanSender', - action='DO_CREATE_LINK', - data=cbt.data) - self.CFxHandle.submitCBT(TincanCBT) - - logCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='Logger', - action='info', - data="Creating Link with peer") - self.CFxHandle.submitCBT(logCBT) - - elif(cbt.action == "TRIM_LINK"): - - # cbt.data is the UID of the peer node, whose link has - # to be trim - TincanCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='TincanSender', - action='DO_TRIM_LINK', - data=cbt.data) - self.CFxHandle.submitCBT(TincanCBT) - - logCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='Logger', - action='info', - data="Trimming Link " - "with peer " + cbt.data) - self.CFxHandle.submitCBT(logCBT) - - else: - logCBT = self.CFxHandle.createCBT(initiator='LinkManager', - recipient='Logger', - action='warning', - data="LinkManager: Invalid CBT " - "received from " + cbt.initiator) - self.CFxHandle.submitCBT(logCBT) - - def timer_method(self): - pass - - def terminate(self): - pass diff --git a/svpn/CBT.py b/svpn/CBT.py deleted file mode 100644 index 89241d1..0000000 --- a/svpn/CBT.py +++ /dev/null @@ -1,12 +0,0 @@ -import uuid - - -class CBT(object): - - def __init__(self, initiator='', recipient='', action='', data=''): - - self.uid = uuid.uuid4() # Unique ID for CBTs - self.initiator = initiator - self.recipient = recipient - self.action = action - self.data = data diff --git a/svpn/CFx.py b/svpn/CFx.py deleted file mode 100644 index 853c2ea..0000000 --- a/svpn/CFx.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -import json -import signal -import socket -import ipoplib -import argparse -import binascii -import threading -import importlib -from getpass import getpass -from collections import OrderedDict -from CBT import CBT as _CBT -from CFxHandle import CFxHandle - - -class CFX(object): - - def __init__(self): - - with open('config.json') as data_file: - - # Read config.json into an OrderedDict, to load the - # modules in the order in which they appear in config.json - self.json_data = json.load(data_file, - object_pairs_hook=OrderedDict) - - # Parse config and update default CONFIG in ipoplib - self.parse_config() - ipoplib.CONFIG = self.CONFIG - - # CFxHandleDict is a dict containing the references to - # CFxHandles of all CMs with key as the module name and - # value as the CFxHandle reference - self.CFxHandleDict = {} - - self.vpn_type = self.CONFIG['CFx']['vpn_type'] - self.user = self.CONFIG['CFx']["xmpp_username"] - self.password = self.CONFIG['CFx']["xmpp_password"] - self.host = self.CONFIG['CFx']["xmpp_host"] - self.ip4 = self.CONFIG['AddressMapper']["ip4"] - if(self.vpn_type == 'GroupVPN'): - self.uid = ipoplib.gen_uid(self.ip4) # SHA-1 Hash - elif(self.vpn_type == 'SocialVPN'): - self.uid = self.CONFIG['CFx']['local_uid'] - self.ip6 = ipoplib.gen_ip6(self.uid) - - if socket.has_ipv6: - self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) - self.sock_svr = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) - self.sock_svr.bind((self.CONFIG['TincanSender']["localhost6"], - self.CONFIG['CFx']["contr_port"])) - else: - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.sock_svr = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.sock_svr.bind((self.CONFIG['TincanSender']["localhost"], - self.CONFIG['CFx']["contr_port"])) - self.sock.bind(("", 0)) - self.sock_list = [self.sock, self.sock_svr] - - def submitCBT(self, CBT): - - recipient = CBT.recipient - self.CFxHandleDict[recipient].CMQueue.put(CBT) - - def createCBT(self, initiator='', recipient='', action='', data=''): - - # Create and return an empty CBT. The variables of the CBT - # will be assigned by the CM - cbt = _CBT(initiator, recipient, action, data) - return cbt - - def freeCBT(self): - - # Deallocate the CBT here - # Python automatic garbage collector handles it anyway - pass - - def initialize(self,): - - # Make Tincan API calls to initialize the controller - - # Set logging level - ipoplib.do_set_logging(self.sock, self.CONFIG["CFx"]["tincan_logging"]) - - if(self.vpn_type == "GroupVPN"): - ipoplib.do_set_translation(self.sock, 0) - ipoplib.do_set_switchmode(self.sock, - self.CONFIG["TincanSender"] - ["switchmode"]) - elif(self.vpn_type == "SocialVPN"): - ipoplib.do_set_translation(self.sock, 1) - - # Callback endpoint to receive notifications - ipoplib.do_set_cb_endpoint(self.sock, self.sock.getsockname()) - - # Configure the local node - if not self.CONFIG["CFx"]["router_mode"]: - ipoplib.do_set_local_ip(self.sock, self.uid, self.ip4, - self.ip6, - self.CONFIG["CFx"]["ip4_mask"], - self.CONFIG["CFx"]["ip6_mask"], - self.CONFIG["CFx"]["subnet_mask"], - self.CONFIG["TincanSender"]["switchmode"]) - - else: - ipoplib.do_set_local_ip(self.sock, self.uid, - self.CONFIG["CFx"]["router_ip"], - self.ip6, - self.CONFIG["CFx"]["router_ip4_mask"], - self.CONFIG["CFx"]["router_ip6_mask"], - self.CONFIG["CFx"]["subnet_mask"], - self.CONFIG["TincanSender"]["switchmode"]) - - # Register to the XMPP server - ipoplib.do_register_service(self.sock, self.user, - self.password, self.host) - ipoplib.do_set_trimpolicy(self.sock, - self.CONFIG["CFx"]["trim_enabled"]) - - # Retrieve the state of the local node - ipoplib.do_get_state(self.sock) - - # Ignore the network interfaces in the list - if "network_ignore_list" in self.CONFIG["CFx"]: - ipoplib.make_call(self.sock, m="set_network_ignore_list", - network_ignore_list=CONFIG["CFx"] - ["network_ignore_list"]) - - print "CFx initialized. Loading Controller Modules\n" - - self.loaded_modules = ['CFx'] # List of modules already loaded - - # Check for circular dependencies in config.json - dependency_graph = {} - for key in self.json_data: - if(key != 'CFx'): - try: - dependency_graph[key] = self.json_data[key]['dependencies'] - except: - pass - - if(self.detect_cyclic_dependency(dependency_graph)): - print "Circular dependency detected in config.json. Exiting" - sys.exit() - - # Iterate through the modules mentioned in config.json - # and load them. - for key in self.json_data: - if (key not in self.loaded_modules): - self.load_module(key) - - # Start all the worker and timer threads - for handle in self.CFxHandleDict: - self.CFxHandleDict[handle].CMThread.start() - if(self.CFxHandleDict[handle].timer_thread): - self.CFxHandleDict[handle].timer_thread.start() - - def load_module(self, module_name): - - if(module_name not in self.loaded_modules): - - # Load dependencies of the module - self.load_dependencies(module_name) - - # Dynamically importing the modules - module = importlib.import_module(module_name) - - # Get the class with name key from module - module_class = getattr(module, module_name) - - # Create a CFxHandle object for each module - handle = CFxHandle(self) - - # Instantiate the class, with CFxHandle reference and - # configuration parameters - - # Pass the sock_list as parameter to TincanListener - # and TincanSender modules - if(module_name in ['TincanListener', 'TincanSender']): - instance = module_class(self.sock_list, - handle, - self.CONFIG[module_name]) - else: - instance = module_class(handle, self.CONFIG[module_name]) - - handle.CMInstance = instance - handle.CMConfig = self.CONFIG[module_name] - - # Store the CFxHandle object references in the - # dict with module name as the key - self.CFxHandleDict[module_name] = handle - - # Intialize all the CFxHandles which in turn initialize the CMs - handle.initialize() - - self.loaded_modules.append(module_name) - - def load_dependencies(self, module_name): - - # Load dependencies of the module, if specified in config.json - try: - dependencies = self.json_data[module_name]['dependencies'] - for module in dependencies: - if(module not in self.loaded_modules): - self.load_module(module) - except KeyError: - pass - - def detect_cyclic_dependency(self, g): - - # Return True if the directed graph g has a cycle. - path = set() - - def visit(vertex): - path.add(vertex) - for neighbour in g.get(vertex, ()): - if neighbour in path or visit(neighbour): - return True - path.remove(vertex) - return False - - return any(visit(v) for v in g) - - def __handler(self, signum=None, frame=None): - - print 'Signal handler called with signal ' + str(signum) - - def parse_config(self): - - self.CONFIG = ipoplib.CONFIG - - parser = argparse.ArgumentParser() - parser.add_argument("-c", help="load configuration from a file", - dest="config_file", metavar="config_file") - parser.add_argument("-u", help="update configuration file if needed", - dest="update_config", action="store_true") - parser.add_argument("-p", help="load remote ip configuration file", - dest="ip_config", metavar="ip_config") - parser.add_argument("-s", help="configuration as json string" - " (overrides configuration from file)", - dest="config_string", metavar="config_string") - parser.add_argument("--pwdstdout", help="use stdout as " - "password stream", - dest="pwdstdout", action="store_true") - - args = parser.parse_args() - - if args.config_file: - # Load the config file - with open(args.config_file) as f: - - loaded_config = json.load(f) - for key in loaded_config: - if(self.CONFIG.get(key, None)): - self.CONFIG[key].update(loaded_config[key]) - - if args.config_string: - # Load the config string - loaded_config = json.loads(args.config_string) - for key in loaded_config: - if(self.CONFIG.get(key, None)): - self.CONFIG[key].update(loaded_config[key]) - - need_save = self.setup_config(self.CONFIG) - if need_save and args.config_file and args.update_config: - with open(args.config_file, "w") as f: - json.dump(self.CONFIG, f, indent=4, sort_keys=True) - - if not ("xmpp_username" in self.CONFIG["CFx"] and - "xmpp_host" in self.CONFIG["CFx"]): - raise ValueError("At least 'xmpp_username' and 'xmpp_host' " - "must be specified in config file or string") - - if "xmpp_password" not in self.CONFIG["CFx"]: - prompt = "\nPassword for %s:" % self.CONFIG["CFx"]["xmpp_username"] - if args.pwdstdout: - self.CONFIG["CFx"]["xmpp_password"] = getpass(prompt, - stream=sys.stdout) - else: - self.CONFIG["CFx"]["xmpp_password"] = getpass(prompt) - - if args.ip_config: - ipoplib.load_peer_ip_config(args.ip_config) - - def setup_config(self, config): - """Validate config and set default value here. Return ``True`` if config is - changed. - """ - if not config['CFx']['local_uid']: - uid = binascii.b2a_hex(os.urandom(self.CONFIG['CFx'] - ['uid_size'] / 2)) - self.CONFIG['CFx']["local_uid"] = uid - return True # modified - return False - - def waitForShutdownEvent(self): - - self.event = threading.Event() - - # Since signal.pause() is not avaialble on windows, use event.wait() - # with a timeout to catch KeyboardInterrupt. Without timeout, it's - # not possible to catch KeyboardInterrupt because event.wait() is - # a blocking call without timeout. The if condition checks if the os - # is windows. - if(os.name == 'nt'): - - while(True): - try: - self.event.wait(1) - except KeyboardInterrupt, SystemExit: - break - - else: - - for sig in [signal.SIGINT]: - signal.signal(sig, self.__handler) - - # signal.pause() sleeps until SIGINT is received - signal.pause() - - def terminate(self): - - for key in self.CFxHandleDict: - - # Create a special terminate CBT to terminate all the CMs - terminateCBT = self.createCBT('CFx', key, 'TERMINATE', '') - - # Clear all the queues and put the terminate CBT in all the queues - self.CFxHandleDict[key].CMQueue.queue.clear() - - self.submitCBT(terminateCBT) - - # Wait for the threads to process their current CBTs and exit - print "Waiting for timer threads to exit gracefully..." - for handle in self.CFxHandleDict: - if(self.CFxHandleDict[handle].joinEnabled): - self.CFxHandleDict[handle].CMThread.join() - self.CFxHandleDict[handle].timer_thread.join() - - sys.exit(0) - - -def main(): - - CFx = CFX() - CFx.initialize() - CFx.waitForShutdownEvent() - CFx.terminate() - -if __name__ == "__main__": - main() diff --git a/svpn/CFxHandle.py b/svpn/CFxHandle.py deleted file mode 100644 index b367cbc..0000000 --- a/svpn/CFxHandle.py +++ /dev/null @@ -1,103 +0,0 @@ -import Queue -import logging -import threading - - -class CFxHandle(object): - - def __init__(self, CFxObject): - - self.CMQueue = Queue.Queue() # CBT queue - self.CMInstance = None - self.CMThread = None # CM worker thread - self.CMConfig = None - self.__CFxObject = CFxObject # CFx object reference - self.joinEnabled = False - self.timer_thread = None - self.terminateFlag = False - - def __getCBT(self): - - cbt = self.CMQueue.get() # Blocking call - return cbt - - def submitCBT(self, cbt): - - # Submit CBT to the CFx - self.__CFxObject.submitCBT(cbt) - - def createCBT(self, initiator='', recipient='', action='', data=''): - - # Create and return a CBT with optional parameters - cbt = self.__CFxObject.createCBT(initiator, recipient, action, data) - return cbt - - def freeCBT(self): - - # Deallocate the CBT here - # Python automatic garbage collector handles it anyway - pass - - def initialize(self): - - # Intialize CM first - self.CMInstance.initialize() - - # Create worker thread, which is started by CFx - self.CMThread = threading.Thread(target=self.__worker) - self.CMThread.setDaemon(True) - - # Check whether CM requires join() or not - if(self.CMConfig['joinEnabled'] == 'True'): - self.joinEnabled = True - - # Check if the CMConfig has timer_interval specified - timer_enabled = False - - try: - interval = int(self.CMConfig['timer_interval']) - timer_enabled = True - except ValueError: - logging.warning("Invalid timer configuration for " + key + - ". Timer has been disabled for this module") - except KeyError: - pass - - if(timer_enabled): - - # Create timer worker thread. CFx is responsible to start - # this thread - self.timer_thread = threading.Thread(target=self.__timer_worker, - args=(interval,)) - self.timer_thread.setDaemon(False) - - def __worker(self): - - # Get CBT from local queue, and call processCBT() which - # is responsible for processing one CBT, given as a parameter - - while(True): - - cbt = self.__getCBT() - - # Break the loop if special terminate CBT is received - if(cbt.action == 'TERMINATE'): - self.terminateFlag = True - module_name = self.CMInstance.__class__.__name__ - logging.info(module_name+" exiting") - self.CMInstance.terminate() - break - else: - self.CMInstance.processCBT(cbt) - - def __timer_worker(self, interval): - - # Call the timer_method of CMs every x seconds - # x is specified in config.json as timer_interval - event = threading.Event() - - while(True): - if(self.terminateFlag): - break - event.wait(interval) - self.CMInstance.timer_method() diff --git a/svpn/ControllerModule.py b/svpn/ControllerModule.py deleted file mode 100644 index 0937ab8..0000000 --- a/svpn/ControllerModule.py +++ /dev/null @@ -1,50 +0,0 @@ -from abc import ABCMeta, abstractmethod # Only Python 2.6 and above - - -""" -Defining an abstract class which the controller -modules will implement, forcing them to override -all the abstract methods -""" - - -class ControllerModule(object): - - __metaclass__ = ABCMeta - - def __init__(self): - self.pendingCBT = {} - self.CBTMappings = {} - - @abstractmethod - def initialize(self): - pass - - @abstractmethod - def processCBT(self): - pass - - @abstractmethod - def timer_method(self): - pass - - @abstractmethod - def terminate(self): - pass - - # Check if the given cbt is a request sent by the current module - # If yes, returns the source CBT for which the request has been - # created, else return None - def checkMapping(self, cbt): - for key in self.CBTMappings: - if(cbt.uid in self.CBTMappings[key]): - return key - return None - - # For a given sourceCBT's uid, check if all requests are serviced - def allServicesCompleted(self, sourceCBT_uid): - requested_services = self.CBTMappings[sourceCBT_uid] - for service in requested_services: - if(service not in self.pendingCBT): - return False - return True diff --git a/svpn/Logger.py b/svpn/Logger.py deleted file mode 100644 index 92bfe80..0000000 --- a/svpn/Logger.py +++ /dev/null @@ -1,58 +0,0 @@ -import logging -from ControllerModule import ControllerModule - - -class Logger(ControllerModule): - - def __init__(self, CFxHandle, paramDict): - - super(Logger, self).__init__() - self.CFxHandle = CFxHandle - self.CMConfig = paramDict - - def initialize(self): - - if "controller_logging" in self.CMConfig: - level = getattr(logging, self.CMConfig["controller_logging"]) - logging.basicConfig(level=level) - - logging.info("Logger Module Loaded") - - # PKTDUMP mode is for more detailed than debug logging, - # especially for dump packet contents in hexadecimal to log - logging.addLevelName(5, "PKTDUMP") - logging.PKTDUMP = 5 - - def processCBT(self, cbt): - - if(cbt.action == 'debug'): - logging.debug(cbt.data) - elif(cbt.action == 'info'): - logging.info(cbt.data) - elif(cbt.action == 'warning'): - logging.warning(cbt.data) - elif(cbt.action == 'error'): - logging.error(cbt.data) - elif(cbt.action == "pktdump"): - self.pktdump(message=cbt.data.get('message'), - dump=cbt.data.get('dump')) - else: - logging.warning("Unrecognized CBT from "+cbt.initiator) - - def timer_method(self): - pass - - def pktdump(self, message, dump=None, *args, **argv): - hext = "" - if dump: - for i in range(0, len(dump), 2): - hext += dump[i:i+2].encode("hex") - hext += " " - if i % 16 == 14: - hext += "\n" - logging.log(5, message + "\n" + hext) - else: - logging.log(5, message, *args, **argv) - - def terminate(self): - pass diff --git a/svpn/TincanListener.py b/svpn/TincanListener.py deleted file mode 100644 index 0b71a94..0000000 --- a/svpn/TincanListener.py +++ /dev/null @@ -1,54 +0,0 @@ -import select -from threading import Thread -from ControllerModule import ControllerModule - - -class TincanListener(ControllerModule): - - def __init__(self, sock_list, CFxHandle, paramDict): - - super(TincanListener, self).__init__() - self.CFxHandle = CFxHandle - self.sock = sock_list[0] - self.sock_svr = sock_list[1] - self.sock_list = sock_list - self.CMConfig = paramDict - - def initialize(self): - - # Create a thread to listen to Tincan Notifications - self.TincanListenerThread = Thread(target=self.__tincan_listener) - self.TincanListenerThread.setDaemon(True) - self.TincanListenerThread.start() - - logCBT = self.CFxHandle.createCBT(initiator='TincanListener', - recipient='Logger', - action='info', - data="TincanListener Loaded") - self.CFxHandle.submitCBT(logCBT) - - def processCBT(self, cbt): - pass - - def timer_method(self): - pass - - def __tincan_listener(self): - - while(True): - socks, _, _ = select.select(self.sock_list, [], [], - self.CMConfig["socket_read_wait_time"]) - - for sock in socks: - if(sock == self.sock or sock == self.sock_svr): - sock_to_read = socks[0] - data, adr = sock_to_read.recvfrom(self.CMConfig["buf_size"]) - cbt = self.CFxHandle.createCBT(initiator='TincanListener', - recipient='Tincan' - 'Dispatcher', - action='TINCAN_PKT', - data=[data, adr]) - self.CFxHandle.submitCBT(cbt) - - def terminate(self): - pass diff --git a/svpn/TincanSender.py b/svpn/TincanSender.py deleted file mode 100644 index 6974fec..0000000 --- a/svpn/TincanSender.py +++ /dev/null @@ -1,147 +0,0 @@ -import json -import socket -import random -from ControllerModule import ControllerModule - - -class TincanSender(ControllerModule): - - ipop_ver = "\x02" - tincan_control = "\x01" - tincan_packet = "\x02" - - def __init__(self, sock_list, CFxHandle, paramDict): - - super(TincanSender, self).__init__() - self.CFxHandle = CFxHandle - self.CMConfig = paramDict - self.sock = sock_list[0] - self.sock_svr = sock_list[1] - - def initialize(self): - - logCBT = self.CFxHandle.createCBT(initiator='TincanSender', - recipient='Logger', - action='info', - data="TincanSender Loaded") - self.CFxHandle.submitCBT(logCBT) - - def processCBT(self, cbt): - - if(cbt.action == 'DO_CREATE_LINK'): - - uid = cbt.data.get('uid') - fpr = cbt.data.get('fpr') - nid = cbt.data.get('nid') - sec = cbt.data.get('sec') - cas = cbt.data.get('cas') - self.do_create_link(self.sock, uid, fpr, nid, sec, cas) - - elif(cbt.action == 'DO_TRIM_LINK'): - - # cbt.data contains the UID of the peer - self.do_trim_link(self.sock, cbt.data) - - elif(cbt.action == 'DO_GET_STATE'): - - self.do_get_state(self.sock) - - elif(cbt.action == 'DO_SEND_MSG'): - - method = cbt.data.get("method") - overlay_id = cbt.data.get("overlay_id") - uid = cbt.data.get("uid") - data = cbt.data.get("data") - self.do_send_msg(self.sock, method, overlay_id, uid, data) - - elif(cbt.action == 'DO_SET_REMOTE_IP'): - - uid = cbt.data.get("uid") - ip4 = cbt.data.get("ip4") - self.do_set_remote_ip(self.sock, - uid, ip4, self.gen_ip6(uid)) - - elif(cbt.action == 'ECHO_REPLY'): - m_type = cbt.data.get('m_type') - dest_addr = cbt.data.get('dest_addr') - dest_port = cbt.data.get('dest_port') - self.make_remote_call(self.sock_svr, m_type=m_type, - dest_addr=dest_addr, dest_port=dest_port, - payload=None, type="echo_reply") - - else: - logCBT = self.CFxHandle.createCBT(initiator='TincanSender', - recipient='Logger', - action='warning', - data="TincanSender: Unrecognized" - "CBT from " + cbt.initiator) - self.CFxHandle.submitCBT(logCBT) - - def do_create_link(self, sock, uid, fpr, overlay_id, sec, - cas, stun=None, turn=None): - if stun is None: - stun = random.choice(self.CMConfig["stun"]) - if turn is None: - if self.CMConfig["turn"]: - turn = random.choice(self.CMConfig["turn"]) - else: - turn = {"server": "", "user": "", "pass": ""} - return self.make_call(sock, m="create_link", uid=uid, fpr=fpr, - overlay_id=overlay_id, stun=stun, - turn=turn["server"], - turn_user=turn["user"], - turn_pass=turn["pass"], - sec=sec, cas=cas) - - def do_trim_link(self, sock, uid): - return self.make_call(sock, m="trim_link", uid=uid) - - def do_get_state(self, sock, peer_uid="", stats=True): - return self.make_call(sock, m="get_state", uid=peer_uid, stats=stats) - - def do_send_msg(self, sock, method, overlay_id, uid, data): - return self.make_call(sock, m=method, overlay_id=overlay_id, - uid=uid, data=data) - - def do_set_remote_ip(self, sock, uid, ip4, ip6): - if (self.CMConfig["switchmode"] == 1): - return self.make_call(sock, m="set_remote_ip", uid=uid, - ip4="127.0.0.1", ip6="::1/128") - else: - return self.make_call(sock, m="set_remote_ip", uid=uid, ip4=ip4, - ip6=ip6) - - def make_call(self, sock, payload=None, **params): - if socket.has_ipv6: - dest = (self.CMConfig["localhost6"], self.CMConfig["svpn_port"]) - else: - dest = (self.CMConfig["localhost"], self.CMConfig["svpn_port"]) - if payload is None: - return sock.sendto(self.ipop_ver + self.tincan_control + - json.dumps(params), dest) - else: - return sock.sendto(self.ipop_ver + self.tincan_packet + - payload, dest) - - def gen_ip6(self, uid, ip6=None): - if ip6 is None: - ip6 = self.CMConfig["ip6_prefix"] - for i in range(0, 16, 4): - ip6 += ":" + uid[i:i+4] - return ip6 - - def make_remote_call(self, sock, dest_addr, dest_port, m_type, - payload, **params): - dest = (dest_addr, dest_port) - if m_type == self.tincan_control: - return sock.sendto(self.ipop_ver + m_type + - json.dumps(params), dest) - else: - return sock.sendto(self.ipop_ver + m_type + - payload, dest) - - def timer_method(self): - pass - - def terminate(self): - pass diff --git a/svpn/Watchdog.py b/svpn/Watchdog.py deleted file mode 100644 index a970302..0000000 --- a/svpn/Watchdog.py +++ /dev/null @@ -1,57 +0,0 @@ -from ControllerModule import ControllerModule - - -class Watchdog(ControllerModule): - - def __init__(self, CFxHandle, paramDict): - - super(Watchdog, self).__init__() - self.CFxHandle = CFxHandle - self.CMConfig = paramDict - self.ipop_state = None - - def initialize(self): - - logCBT = self.CFxHandle.createCBT(initiator='Watchdog', - recipient='Logger', - action='info', - data="Watchdog Loaded") - self.CFxHandle.submitCBT(logCBT) - - def processCBT(self, cbt): - - if(cbt.action == 'STORE_IPOP_STATE'): - - # cbt.data contains the state of local node - msg = cbt.data - self.ipop_state = msg - - elif(cbt.action == 'QUERY_IPOP_STATE'): - - cbt.action = 'QUERY_IPOP_STATE_RESP' - cbt.data = self.ipop_state - cbt.initiator, cbt.recipient = cbt.recipient, cbt.initiator - - # Submit the CBT back to the initiator - # cbt.data contains ipop_state - self.CFxHandle.submitCBT(cbt) - - else: - - logCBT = self.CFxHandle.createCBT(initiator='Monitor', - recipient='Logger', - action='error', - data="Watchdog: Unrecognized CBT" - "from: " + cbt.initiator) - self.CFxHandle.submitCBT(logCBT) - - def timer_method(self): - - TincanCBT = self.CFxHandle.createCBT(initiator='Watchdog', - recipient='TincanSender', - action='DO_GET_STATE', - data='') - self.CFxHandle.submitCBT(TincanCBT) - - def terminate(self): - pass diff --git a/svpn/ipoplib.py b/svpn/ipoplib.py deleted file mode 100644 index c6b6807..0000000 --- a/svpn/ipoplib.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/env python - -import argparse -import binascii -import datetime -import getpass -import hashlib -import json -import logging -import os -import random -import select -import signal -import socket -import struct -import sys -import time -import urllib2 - -from threading import Timer - -# Set default config values - -CONFIG = { - "CFx": { - "ip4_mask": 24, - "ip6_mask": 64, - "subnet_mask": 32, - "contr_port": 5801, - "local_uid": "", - "uid_size": 40, - "router_mode": False, - "tincan_logging": 1, - "icc": False, # Inter-Controller Connection - "icc_port": 30000, - "trim_enabled": False, - "multihop_cl": 100, # Multihop connection count limit - "multihop_ihc": 3, # Multihop initial hop count - "multihop_hl": 10, # Multihop maximum hop count limit - "multihop_tl": 1, # Multihop time limit (second) - "multihop_sr": True, # Multihop source route - "stat_report": False, - "stat_server": "metrics.ipop-project.org", - "stat_server_port": 5000 - }, - "TincanListener": { - "buf_size": 65507, - "socket_read_wait_time": 15, - "joinEnabled": True - }, - "Logger": { - "controller_logging": "INFO", - "joinEnabled": True - }, - "TincanDispatcher": { - "joinEnabled": True - }, - "Monitor": { - "trigger_con_wait_time": 120, - "joinEnabled": True - }, - "BaseTopologyManager": { - "link_trimmer_wait_time": 30, - "on-demand_connection": False, - "on-demand_inactive_timeout": 600, - "multihop": False, - "sec": True, - "timer_interval": 15, - "joinEnabled": True - }, - "LinkManager": { - "joinEnabled": True - }, - "AddressMapper": { - "ip4": "172.16.0.1", - "joinEnabled": True - }, - "TincanSender": { - "stun": ["stun.l.google.com:19302", "stun1.l.google.com:19302", - "stun2.l.google.com:19302", "stun3.l.google.com:19302", - "stun4.l.google.com:19302"], - "turn": [], - "ip6_prefix": "fd50:0dbc:41f2:4a3c", - "switchmode": 0, - "localhost": "127.0.0.1", - "svpn_port": 5800, - "localhost6": "::1", - "joinEnabled": True - }, - "Watchdog": { - "timer_interval": 15, - "joinEnabled": False, - } -} - -IP_MAP = {} - -ipop_ver = "\x02" -tincan_control = "\x01" -tincan_packet = "\x02" -tincan_sr6 = "\x03" -tincan_sr6_end = "\x04" -null_uid = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" -null_uid += "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" -bc_mac = "\xff\xff\xff\xff\xff\xff" -null_mac = "\x00\x00\x00\x00\x00\x00" - -# server is cross-module(?) variable -server = None - -# server is assigned in each Social/GroupVPN controller and then should be -# assigned in library module too. -def set_global_variable_server(s): - global server - server = s - -# # When proces killed or keyboard interrupted exit_handler runs then exit -# def exit_handler(signum, frame): -# logging.info("Terminating Controller") -# if CONFIG["stat_report"]: -# if server != None: -# server.report() -# else: -# logging.debug("Controller socket is not created yet") -# sys.exit(0) - -# signal.signal(signal.SIGINT, exit_handler) -# AFAIK, there is no way to catch SIGKILL -# signal.signal(signal.SIGKILL, exit_handler) -# signal.signal(signal.SIGQUIT, exit_handler) -# signal.signal(signal.SIGTERM, exit_handler) - -def ip6_a2b(str_ip6): - return "".join(x.decode("hex") for x in str_ip6.split(':')) - -def ip6_b2a(bin_ip6): - return "".join(bin_ip6[x:x+2].encode("hex") + ":" for x in range(0, 14, 2))\ - + bin_ip6[14].encode("hex") + bin_ip6[15].encode("hex") - - -def ip4_a2b(str_ip4): - return "".join(chr(int(x)) for x in str_ip4.split('.')) - -def ip4_b2a(bin_ip4): - return "".join(str(ord(bin_ip4[x])) + "." for x in range(0, 3)) \ - + str(ord(bin_ip4[3])) - -def mac_a2b(str_mac): - return "".join(x.decode("hex") for x in str_mac.split(':')) - -def mac_b2a(bin_mac): - return "".join(bin_mac[x].encode("hex") + ":" for x in range(0, 5)) +\ - bin_mac[5].encode("hex") - -def uid_a2b(str_uid): - return str_uid.decode("hex") - -def gen_ip4(uid, peer_map, ip4=None): - ip4 = ip4 or CONFIG['AddressMapper']["ip4"] - try: - return peer_map[uid] - except KeyError: - pass - - ips = set(peer_map.itervalues()) - prefix, _ = ip4.rsplit(".", 1) - # We allocate to *.101 - *.254. This ensures a 3-digit suffix and avoids - # the broadcast address. *.100 is our IPv4 address. - for i in range(101, 255): - peer_map[uid] = "%s.%s" % (prefix, i) - if peer_map[uid] not in ips: - return peer_map[uid] - del peer_map[uid] - raise OverflowError("Too many peers, out of IPv4 addresses") - -def gen_ip6(uid, ip6=None): - if ip6 is None: - ip6 = CONFIG["TincanSender"]["ip6_prefix"] - for i in range(0, 16, 4): - ip6 += ":" + uid[i:i+4] - return ip6 - -def gen_uid(ip4): - return hashlib.sha1(ip4).hexdigest()[:CONFIG["CFx"]["uid_size"]] - -def make_call(sock, payload=None, **params): - if socket.has_ipv6: - dest = (CONFIG["TincanSender"]["localhost6"], - CONFIG["TincanSender"]["svpn_port"]) - else: - dest = (CONFIG["TincanSender"]["localhost"], - CONFIG["TincanSender"]["svpn_port"]) - if payload is None: - return sock.sendto(ipop_ver + tincan_control + json.dumps(params), dest) - else: - return sock.sendto(ipop_ver + tincan_packet + payload, dest) - -def make_remote_call(sock, dest_addr, dest_port, m_type, payload, **params): - dest = (dest_addr, dest_port) - if m_type == tincan_control: - return sock.sendto(ipop_ver + m_type + json.dumps(params), dest) - else: - return sock.sendto(ipop_ver + m_type + payload, dest) - -def send_packet(sock, msg): - if socket.has_ipv6: - dest = (CONFIG["TincanSender"]["localhost6"], - CONFIG["TincanSender"]["svpn_port"]) - else: - dest = (CONFIG["CFx"]["TincanSender"], - CONFIG["TincanSender"]["svpn_port"]) - return sock.sendto(ipop_ver + tincan_packet + msg, dest) - -def make_arp(src_uid=null_uid, dest_uid=null_uid, dest_mac=bc_mac, - src_mac=bc_mac, op="\x01", sender_mac=bc_mac, - sender_ip4=CONFIG['AddressMapper']["ip4"], target_mac=null_mac, - target_ip4=CONFIG['AddressMapper']["ip4"]): - arp_msg = "" - arp_msg += src_uid - arp_msg += dest_uid - arp_msg += dest_mac - arp_msg += src_mac - arp_msg += "\x08\x06" # Ether type of ARP - arp_msg += "\x00\x01" # Hardware Type - arp_msg += "\x08\x00" # Protocol Type - arp_msg += "\x06" # Hardware address length - arp_msg += "\x04" # Protocol address length - arp_msg += "\x00" # Operation (ARP reply) - arp_msg += op # Operation (ARP reply) - arp_msg += sender_mac - arp_msg += sender_ip4 - arp_msg += target_mac - arp_msg += target_ip4 - return arp_msg - -def do_send_msg(sock, method, overlay_id, uid, data): - return make_call(sock, m=method, overlay_id=overlay_id, uid=uid, data=data) - -def do_set_cb_endpoint(sock, addr): - return make_call(sock, m="set_cb_endpoint", ip=addr[0], port=addr[1]) - -def do_register_service(sock, username, password, host): - return make_call(sock, m="register_svc", username=username, - password=password, host=host) - -def do_create_link(sock, uid, fpr, overlay_id, sec, cas, stun=None, turn=None): - if stun is None: - stun = random.choice(CONFIG["CFx"]["stun"]) - if turn is None: - if CONFIG["CFx"]["turn"]: - turn = random.choice(CONFIG["CFx"]["turn"]) - else: - turn = {"server": "", "user": "", "pass": ""} - return make_call(sock, m="create_link", uid=uid, fpr=fpr, - overlay_id=overlay_id, stun=stun, turn=turn["server"], - turn_user=turn["user"], - turn_pass=turn["pass"], sec=sec, cas=cas) - -def do_trim_link(sock, uid): - return make_call(sock, m="trim_link", uid=uid) - -def do_set_local_ip(sock, uid, ip4, ip6, ip4_mask, ip6_mask, subnet_mask, - switchmode): - return make_call(sock, m="set_local_ip", uid=uid, ip4=ip4, ip6=ip6, - ip4_mask=ip4_mask, ip6_mask=ip6_mask, - subnet_mask=subnet_mask, switchmode=switchmode) - -def do_set_remote_ip(sock, uid, ip4, ip6): - if (CONFIG["TincanSender"]["switchmode"] == 1): - return make_call(sock, m="set_remote_ip", uid=uid, ip4="127.0.0.1", - ip6="::1/128") - else: - return make_call(sock, m="set_remote_ip", uid=uid, ip4=ip4, ip6=ip6) - -def do_get_state(sock, peer_uid="", stats=True): - return make_call(sock, m="get_state", uid=peer_uid, stats=stats) - -def do_set_logging(sock, logging): - return make_call(sock, m="set_logging", logging=logging) - -def do_set_translation(sock, translate): - return make_call(sock, m="set_translation", translate=translate) - -def do_set_switchmode(sock, switchmode): - return make_call(sock, m="set_switchmode", switchmode=switchmode) - -def do_set_trimpolicy(sock, trim_enabled): - return make_call(sock, m="set_trimpolicy", trim_enabled=trim_enabled) - -def load_peer_ip_config(ip_config): - with open(ip_config) as f: - ip_cfg = json.load(f) - - for peer_ip in ip_cfg: - uid = peer_ip["uid"] - ip = peer_ip["ipv4"] - IP_MAP[uid] = ip - logging.debug("MAP %s -> %s" % (ip, uid))