Commit 81f49fab authored by Guillaume Bury's avatar Guillaume Bury

Added some logs, added blacklist in db, added lan discovery through babel +...

Added some logs, added blacklist in db, added lan discovery through babel + automatic blacklisting of node routed through the LAN
parent 23f47592
......@@ -15,28 +15,36 @@ class PeerManager:
self._server_port = server_port
self._db_size = db_size
self._pp = pp
self._blacklist = [(prefix,)]
self._manual = manual
self._proxy = xmlrpclib.ServerProxy('http://%s:%u'
% (server, server_port))
utils.log('Connectiong to peers database', 4)
utils.log('Connectiong to peers database...', 4)
self._db = sqlite3.connect(os.path.join(db_dir_path, 'peers.db'),
isolation_level=None)
utils.log('Preparing peers database', 4)
utils.log('Database opened', 5)
utils.log('Preparing peers database...', 4)
try:
self._db.execute("UPDATE peers SET used = 0")
except sqlite3.OperationalError, e:
if e.args[0] == 'no such table: peers':
raise RuntimeError
utils.log('Database prepared', 5)
self.next_refresh = time.time()
def blacklist(self, prefix):
utils.log('Blacklisting %s' % (prefix,), 4)
self._blacklist = list(set(self._blacklist + [(prefix,)]))
def refresh(self):
utils.log('Refreshing the peers DB', 2)
utils.log('Refreshing the peers DB...', 2)
try:
self._declare()
self._populate()
utils.log('DB refreshed', 3)
self.next_refresh = time.time() + self._refresh_time
except socket.error, e:
utils.log(str(e), 4)
......@@ -45,14 +53,15 @@ class PeerManager:
def _declare(self):
if self._address != None:
utils.log('Sending connection info to server', 3)
utils.log('Sending connection info to server...', 3)
self._proxy.declare((self._internal_ip,
utils.address_list(self._address)))
utils.log('Info sent', 5)
else:
utils.log("Warning : couldn't send ip, unknown external config", 4)
def _populate(self):
utils.log('Populating the peers DB', 2)
utils.log('Populating the peers DB...', 2)
new_peer_list = self._proxy.getPeerList(self._db_size,
self._internal_ip)
self._db.execute("""DELETE FROM peers WHERE used <= 0 ORDER BY used,
......@@ -61,7 +70,9 @@ class PeerManager:
(str(len(new_peer_list) - self._db_size),))
self._db.executemany("""INSERT OR IGNORE INTO peers (prefix, address)
VALUES (?,?)""", new_peer_list)
self._db.execute("DELETE FROM peers WHERE prefix = ?", (self._prefix,))
self._db.executemany("DELETE FROM peers WHERE prefix = ?",
self._blacklist)
utils.log('DB populated', 3)
utils.log('New peers : %s' % ', '.join(map(str, new_peer_list)), 5)
def getUnusedPeers(self, peer_count):
......@@ -73,16 +84,19 @@ class PeerManager:
utils.log('Updating peers database : using peer ' + str(prefix), 5)
self._db.execute("UPDATE peers SET used = 1 WHERE prefix = ?",
(prefix,))
utils.log('DB updated', 5)
def unusePeer(self, prefix):
utils.log('Updating peers database : unusing peer ' + str(prefix), 5)
self._db.execute("UPDATE peers SET used = 0 WHERE prefix = ?",
(prefix,))
utils.log('DB updated', 5)
def flagPeer(self, prefix):
utils.log('Updating peers database : flagging peer ' + str(prefix), 5)
self._db.execute("UPDATE peers SET used = -1 WHERE prefix = ?",
(prefix,))
utils.log('DB updated', 5)
def handle_message(self, msg):
script_type, arg = msg.split()
......
......@@ -18,7 +18,7 @@ def openvpn(hello_interval, *args, **kw):
return subprocess.Popen(args, **kw)
def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hello_interval, *args, **kw):
utils.log('Starting server', 3)
utils.log('Starting server...', 3)
return openvpn(hello_interval,
'--tls-server',
'--mode', 'server',
......@@ -32,7 +32,7 @@ def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hel
*args, **kw)
def client(server_address, pipe_fd, hello_interval, *args, **kw):
utils.log('Starting client', 5)
utils.log('Starting client...', 5)
remote= ['--nobind',
'--client',
'--up', 'ovpn-client',
......@@ -44,16 +44,16 @@ def client(server_address, pipe_fd, hello_interval, *args, **kw):
def router(network, internal_ip, interface_list,
wireless, hello_interval, state_path, **kw):
utils.log('Starting babel', 3)
utils.log('Starting babel...', 3)
args = ['babeld',
'-C', 'redistribute local ip %s' % (internal_ip),
'-C', 'redistribute local deny',
# Route VIFIB ip adresses
'-C', 'in ip %s::/%u' % (utils.ipFromBin(network), len(network)),
# Route only addresse in the 'local' network,
# or other entire networks
#'-C', 'in ip %s' % (config.internal_ip),
#'-C', 'in ip ::/0 le %s' % network_mask,
# Route only addresse in the 'local' network,
# or other entire networks
#'-C', 'in ip %s' % (config.internal_ip),
#'-C', 'in ip ::/0 le %s' % network_mask,
# Don't route other addresses
'-C', 'in deny',
'-d', str(verbose),
......
import os, random, traceback, time, struct
import os, random, traceback, time, struct, subprocess
import plib, utils, db
log = None
smooth = 0.3
class Connection:
def __init__(self, address, write_pipe, hello, iface, prefix,
......@@ -12,7 +11,8 @@ class Connection:
self.process = plib.client(address, write_pipe, hello, '--dev', iface,
*ovpn_args, stdout=os.open(os.path.join(log,
'vifibnet.client.%s.log' % (prefix,)),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC))
os.O_WRONLY | os.O_CREAT | os.O_TRUNC),
stderr=subprocess.STDOUT)
self.iface = iface
self.routes = 0
......@@ -64,7 +64,7 @@ class Connection:
class TunnelManager:
def __init__(self, write_pipe, peer_db, openvpn_args, hello_interval,
refresh, connection_count, refresh_rate):
refresh, connection_count, refresh_rate, iface_list, network):
self._write_pipe = write_pipe
self._peer_db = peer_db
self._connection_dict = {}
......@@ -72,6 +72,10 @@ class TunnelManager:
self._ovpn_args = openvpn_args
self._hello = hello_interval
self._refresh_time = refresh
self._network = network
self._net_len = len(network)
self._iface_list = iface_list
self.__indirect_connect = []
self.free_interface_set = set(('client1', 'client2', 'client3',
'client4', 'client5', 'client6',
'client7', 'client8', 'client9',
......@@ -82,11 +86,12 @@ class TunnelManager:
self._refresh_count = refresh_rate * self._client_count
def refresh(self):
utils.log('Refreshing the tunnels', 2)
utils.log('Refreshing the tunnels...', 2)
self._cleanDeads()
self._countRoutes()
self._removeSomeTunnels()
self._makeNewTunnels()
utils.log('Tunnels refreshed', 2)
self.next_refresh = time.time() + self._refresh_time
def _cleanDeads(self):
......@@ -102,7 +107,7 @@ class TunnelManager:
self._kill(prefix)
def _kill(self, prefix):
utils.log('Killing the connection with ' + prefix, 2)
utils.log('Killing the connection with %s...' % (prefix,), 2)
connection = self._connection_dict.pop(prefix)
try:
connection.process.kill()
......@@ -112,9 +117,11 @@ class TunnelManager:
self.free_interface_set.add(connection.iface)
self._peer_db.unusePeer(prefix)
del self._iface_to_prefix[connection.iface]
utils.log('Connection with %s killed' % (prefix,), 2)
def _makeNewTunnels(self):
utils.log('Trying to make %i new tunnels' %
i = 0
utils.log('Trying to make %i new tunnels...' %
(self._client_count - len(self._connection_dict)), 5)
try:
for prefix, address in self._peer_db.getUnusedPeers(
......@@ -126,6 +133,8 @@ class TunnelManager:
prefix, self._ovpn_args)
self._iface_to_prefix[iface] = prefix
self._peer_db.usePeer(prefix)
i += 1
utils.log('%u new tunnels established' %(i,), 3)
except KeyError:
utils.log("""Can't establish connection with %s
: no available interface""" % prefix, 2)
......@@ -133,7 +142,8 @@ class TunnelManager:
traceback.print_exc()
def _countRoutes(self):
utils.log('Starting to count the routes on each interface', 3)
utils.log('Starting to count the routes on each interface...', 3)
self._indirect_connect = []
for iface in self._iface_to_prefix.keys():
self._connection_dict[self._iface_to_prefix[iface]].routes = 0
f = open('/proc/net/ipv6_route', 'r')
......@@ -141,9 +151,21 @@ class TunnelManager:
ip, subnet_size, iface = struct.unpack('32s x 2s 106x %ss x'
% (len(line) - 142), line)
iface = iface.replace(' ', '')
utils.log('Route on iface %s detected to %s/%s'
% (iface,ip, subnet_size), 8)
if iface in self._iface_to_prefix.keys():
self._connection_dict[self._iface_to_prefix[iface]].routes += 1
if iface in self._iface_list:
subnet_size = int(subnet_size,16)
ip = bin(int(ip, 16))[2:].rjust(128, '0')
if self._net_len < subnet_size < 128 and ip.startswith(self._network):
prefix = ip[self._net_len:subnet_size]
utils.log('A route to %s has been discovered on the LAN'
% (prefix,), 3)
self._peer_db.blacklist(prefix)
utils.log("Routes have been counted", 3)
for p in self._connection_dict.keys():
utils.log('Routes on iface %s : %s' % (
self._connection_dict[p].iface,
self._connection_dict[p].routes), 5)
......@@ -3,17 +3,18 @@ import argparse, errno, os, select, subprocess, time
from argparse import ArgumentParser
import db, plib, upnpigd, utils, tunnel
class ArgParser(ArgumentParser):
def convert_arg_line_to_args(self, arg_line):
arg_line = arg_line.split('#')[0].rstrip()
if arg_line:
if arg_line.startswith('@'):
yield arg_line
return
for arg in ('--' + arg_line.lstrip('--')).split():
if arg.strip():
yield arg
def ovpnArgs(optional_args, ca_path, cert_path):
# Treat openvpn arguments
if optional_args[0] == "--":
......@@ -41,6 +42,8 @@ def getConfig():
help='Path to VPN state directory')
_('--verbose', '-v', default=0, type=int,
help='Defines the verbose level')
_('-i', '--interface', action='append', dest='iface_list', default=[],
help='Extra interface for LAN discovery')
#_('--babel-state', default='/var/lib/vifibnet/babel_state',
# help='Path to babeld state-file')
#_('--db', default='/var/lib/vifibnet/peers.db',
......@@ -94,22 +97,26 @@ def main():
tunnel.log = config.log
utils.verbose = plib.verbose = config.verbose
utils.log(str(config), 5)
# Create and open read_only pipe to get server events
utils.log('Creating pipe for server events', 3)
utils.log('Creating pipe for server events...', 3)
r_pipe, write_pipe = os.pipe()
read_pipe = os.fdopen(r_pipe)
utils.log('Pipe created', 5)
# Init db and tunnels
if manual:
utils.log('Manual external configuration', 3)
utils.log('Detected manual external configuration', 3)
forward = None
else:
utils.log('Attempting automatic configuration via UPnP', 4)
utils.log('Attempting automatic configuration via UPnP...', 4)
try:
forward = list([upnpigd.UpnpForward(int(port), proto), proto]
for port, proto in config.pp)
config.address = list([ext.external_ip, str(ext.external_port),
proto] for ext, proto in forward)
utils.log('Automatic configuration succeeded', 5)
except Exception:
forward = None
utils.log('An atempt to forward a port via UPnP failed', 4)
......@@ -119,10 +126,11 @@ def main():
manual, config.pp, 200)
tunnel_manager = tunnel.TunnelManager(write_pipe, peer_db, openvpn_args,
config.hello, config.tunnel_refresh, config.connection_count,
config.refresh_rate)
config.refresh_rate, config.iface_list, network)
# Launch routing protocol. WARNING : you have to be root to start babeld
interface_list = ['vifibnet'] + list(tunnel_manager.free_interface_set)
interface_list = ['vifibnet'] + list(tunnel_manager.free_interface_set) \
+ config.iface_list
router = plib.router(network, internal_ip, interface_list, config.wireless,
config.hello, os.path.join(config.state, 'vifibnet.babeld.state'),
stdout=os.open(os.path.join(config.log, 'vifibnet.babeld.log'),
......@@ -134,7 +142,8 @@ def main():
proto, config.hello, '--dev', 'vifibnet', *openvpn_args,
stdout=os.open(os.path.join(config.log,
'vifibnet.server.%s.log' % (proto,)),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC))
os.O_WRONLY | os.O_CREAT | os.O_TRUNC),
stderr=subprocess.STDOUT)
for port, proto in config.pp)
tunnel_manager.refresh()
......
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