Commit 4f03db54 authored by Guillaume Bury's avatar Guillaume Bury

Used db for available peers, added interface handling

parent 18dee845
#!/usr/bin/env python #!/usr/bin/env python
import argparse, errno, os, subprocess, sys, time import argparse, errno, os, sqlite3, subprocess, sys, time
import traceback
import upnpigd import upnpigd
import openvpn import openvpn
import random import random
VIFIB_NET = "2001:db8:42::/48" VIFIB_NET = "2001:db8:42::/48"
connection_dict = {} # to remember current connections
avalaible_peer_list = [('10.1.4.2', 1194), ('10.1.4.3', 1194), ('10.1.3.2', 1194)]
free_interface_set = set(('client1', 'client2'))
# TODO : How do we get our vifib ip ? # TODO : How do we get our vifib ip ?
...@@ -16,7 +20,7 @@ def babel(network_ip, network_mask, verbose_level): ...@@ -16,7 +20,7 @@ def babel(network_ip, network_mask, verbose_level):
'-C', 'in ip %s' % VIFIB_NET, '-C', 'in ip %s' % VIFIB_NET,
# Route only addresse in the 'local' network, # Route only addresse in the 'local' network,
# or other entire networks # or other entire networks
#'-C', 'in ip %s/%s' % (network_ip,network_mask), '-C', 'in ip %s/%s' % (network_ip,network_mask),
#'-C', 'in ip ::/0 le %s' % network_mask, #'-C', 'in ip ::/0 le %s' % network_mask,
# Don't route other addresses # Don't route other addresses
'-C', 'in ip deny', '-C', 'in ip deny',
...@@ -26,27 +30,33 @@ def babel(network_ip, network_mask, verbose_level): ...@@ -26,27 +30,33 @@ def babel(network_ip, network_mask, verbose_level):
if config.babel_state: if config.babel_state:
args += '-S', config.babel_state args += '-S', config.babel_state
# TODO : add list of interfaces to use with babel # TODO : add list of interfaces to use with babel
return subprocess.Popen(args) return subprocess.Popen(args + list(free_interface_set))
def getConfig(): def getConfig():
global config global config
parser = argparse.ArgumentParser(description='Resilient virtual private network application') parser = argparse.ArgumentParser(
description='Resilient virtual private network application')
_ = parser.add_argument _ = parser.add_argument
_('--max-peer', help='the number of peers that can connect to the server', default='10') _('--client-count', default=2, type=int,
# TODO : use it help='the number servers the peers try to connect to')
_('--client-count', help='the number servers the peers try to connect to', default = '2') # TODO : use max-peer, refresh-time, refresh-count
_('--refresh-time', help='the time (seconds) to wait before changing the connections', default = '20') _('--max-peer', default=10, type=int
# TODO : use it help='the number of peers that can connect to the server')
_('--refresh-count', help='The number of connections to drop when refreshing the connections', default='1') _('--refresh-time', default=20, type=int
# TODO : use it help='the time (seconds) to wait before changing the connections')
_('--refresh-count', default=1, type=int
help='The number of connections to drop when refreshing the connections')
_('--db', default='/var/lib/vifibnet/peers.db',
help='Path to peers database')
_('--dh', required=True, _('--dh', required=True,
help='Path to dh file') help='Path to dh file')
_('--babel-state', _('--babel-state', default='/var/lib/vifibnet/babel_state',
help='Path to babeld state-file') help='Path to babeld state-file')
_('--verbose', '-v', default='0', _('--verbose', '-v', default=0, type=int,
help='Defines the verbose level') help='Defines the verbose level')
# Temporary args # Temporary args
_('--ip', required=True, help='IPv6 of the server') _('--ip', required=True,
help='IPv6 of the server')
# Openvpn options # Openvpn options
_('openvpn_args', nargs=argparse.REMAINDER, _('openvpn_args', nargs=argparse.REMAINDER,
help="Common OpenVPN options (e.g. certificates)") help="Common OpenVPN options (e.g. certificates)")
...@@ -54,60 +64,85 @@ def getConfig(): ...@@ -54,60 +64,85 @@ def getConfig():
if config.openvpn_args[0] == "--": if config.openvpn_args[0] == "--":
del config.openvpn_args[0] del config.openvpn_args[0]
# TODO : start n connections in one try ( only 1 database acces )
# TODO : use port and proto in openvpn client
def startNewConnection(): def startNewConnection():
try: try:
peer = random.choice(avalaiblePeers.keys()) for id, ip, port, proto in peer_db.execute(
if config.verbose > 2: "SELECT id, ip, port, proto FROM peers WHERE used = 0"):
print 'Establishing a connection with ' + peer if config.verbose >= 2:
del avalaiblePeers[peer] print 'Establishing a connection with %s' % ip
connections[peer] = openvpn.client(config, peer) iface = free_interface_set.pop()
connection_dict[id] = ( openvpn.client(ip, '--dev', iface) , iface)
peer_db.execute("UPDATE peers SET used = 1 WHERE id = ?", (id,))
break
except KeyError:
if config.verbose >= 2:
print "Can't establish connection with %s : no available interface" % ip
pass
except Exception:
traceback.print_exc()
def killConnection(id):
try:
if config.verbose >= 2:
print 'Killing the connection with ' + peer
p, iface = connection_dict.pop(id)
p.kill()
free_interface_set.add(iface)
peer_db.execute("UPDATE peers SET used = 0 WHERE id = ?", (id,))
except KeyError:
if config.verbose >= 1:
print "Can't kill connection to " + peer + ": no existing connection"
pass
except Exception: except Exception:
if config.verbose >= 1:
print "Can't kill connection to " + peer + ": uncaught error"
pass pass
# TODO :
def killConnection(peer):
if config.verbose > 2:
print 'Killing the connection with ' + peer
subprocess.Popen.kill(connections[peer])
del connections[peer]
avalaiblePeers[peer] = 1194 # TODO : give the real port
def refreshConnections(): def refreshConnections():
# Kill some random connections
try: try:
for i in range(0, int(config.refresh_count)): for i in range(0, int(config.refresh_count)):
peer = random.choice(connections.keys()) id = random.choice(connection_dict.keys())
killConnection(peer) killConnection(id)
except Exception: except Exception:
pass pass
# Establish new connections
for i in range(len(connections), int(config.client_count)): for i in range(len(connection_dict), int(config.client_count)):
startNewConnection() startNewConnection()
def main(): def main():
# init variables # Get arguments
global connections
global avalaiblePeers # the list of peers we can connect to
avalaiblePeers = { '10.1.4.2' : 1194, '10.1.4.3' : 1194, '10.1.3.2' : 1194 }
connections = {} # to remember current connections
getConfig() getConfig()
(externalIp, externalPort) = upnpigd.GetExternalInfo(1194) (externalIp, externalPort) = upnpigd.GetExternalInfo(1194)
try:
del avalaiblePeers[externalIp]
except Exception:
pass
# establish connections # Setup database
serverProcess = openvpn.server(config, config.ip) global peer_db # stop using global variables for everything ?
for i in range(0, int(config.client_count)): peer_db = sqlite3.connect(config.db, isolation_level=None)
peer_db.execute("""CREATE TABLE IF NOT EXISTS peers
( id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT NOT NULL,
port INTEGER NOT NULL,
proto TEXT NOT NULL,
used INTEGER NOT NULL)""")
peer_db.execute("CREATE INDEX IF NOT EXISTS _peers_used ON peers(used)")
peer_db.execute("UPDATE peers SET used = 0")
# Establish connections
serverProcess = openvpn.server(config.ip, '--dev', 'vifibnet')
for i in range(config.client_count):
startNewConnection() startNewConnection()
# main loop # main loop
try: try:
while True: while True:
# TODO : use select to get openvpn events from pipes
time.sleep(float(config.refresh_time)) time.sleep(float(config.refresh_time))
refreshConnections() refreshConnections()
except KeyboardInterrupt: except KeyboardInterrupt:
pass return 1
if __name__ == "__main__": if __name__ == "__main__":
main() main()
......
...@@ -8,9 +8,10 @@ def openvpn(*args, **kw): ...@@ -8,9 +8,10 @@ def openvpn(*args, **kw):
'--script-security', '2', '--script-security', '2',
'--user', 'nobody', '--user', 'nobody',
'--group', 'nogroup', '--group', 'nogroup',
'--verb', config.verbose, #'--verb', str(config.verbose),
] + list(args) + config.openvpn_args ] + list(args) + config.openvpn_args
print repr(args) if config.verbose >= 5:
print repr(args)
return subprocess.Popen(args, **kw) return subprocess.Popen(args, **kw)
# TODO : set iface up when creating a server/client # TODO : set iface up when creating a server/client
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment