Commit 35b9ec40 authored by Ulysse Beaugnon's avatar Ulysse Beaugnon

--ping-exit option in openvpn has been restored so their is no more zombies connections

the --ip argument is now optional : it can be discovered automaticaly
parent 6a8fa1f1
......@@ -4,6 +4,7 @@ Bugs :
When no peer is avalaible without the --no-boot option, it crash => see below
Once in a while, when exiting vifibnet ( not very properly, via Ctrl+C ), processes ( openvpn and babel )
still remain and disturb further attemps ( must be killed for vifibnet to work again )
Babel seems to be very long to establish the routes : maybe we should tell him thant we are not on a wired network but on a mobile network ?
To be done :
Replace comments at the beginning of functions with docstrings & give all fn docstrings
......@@ -12,6 +13,7 @@ To be done :
Use the server events ( client connection/deconnection ) to do something usefull
In peers DB, remove some peers when they are too many of them
Contact the server using vifibnet and not the underlying network when possible
Use a timeout for the peersDB
To be discuss:
U : Remove the --no-boot option since we know when no node is avalaible
......@@ -30,3 +32,5 @@ To be discuss:
G : don't reconnect to server each time we repopulate in peers_db ?
U : we might recontact the server evry 1H or even less. So i think it is a good thing not to keep the connection alive
Why --ping-exit had been removed form openvpn args ? without this we can have zombie connections
......@@ -4,12 +4,13 @@ import utils
class PeerManager:
def __init__(self, dbPath, server, port, refresh_time):
def __init__(self, dbPath, server, port, refresh_time, external_ip):
utils.log('Connectiong to peers database', 4)
self._db = sqlite3.connect(dbPath, isolation_level=None)
self._server = server
self._port = port
self._server_port = port
self._refresh_time = refresh_time
self._external_ip = external_ip
utils.log('Preparing peers database', 4)
try:
self._db.execute("UPDATE peers SET used = 0")
......@@ -18,16 +19,19 @@ class PeerManager:
raise RuntimeError
self.next_refresh = time.time()
def populate(self, n, address):
# address = (internal_ip, external_ip, port, proto)
def populate(self, n, internal_ip, port, proto):
if self._external_ip != None:
address = (internal_ip, self._external_ip, port, proto)
else:
address = 0
utils.log('Connecting to remote server', 3)
self._proxy = xmlrpclib.ServerProxy('http://%s:%u' % (self._server, self._port))
self._proxy = xmlrpclib.ServerProxy('http://%s:%u' % (self._server, self._server_port))
utils.log('Updating peers database : populating', 2)
_, external_ip, _, _ = address
new_peer_list = self._proxy.getPeerList(n, address)
utils.log('New peers recieved from %s' % self._server, 5)
self._db.executemany("INSERT OR IGNORE INTO peers (ip, port, proto, used) VALUES (?,?,?,0)", new_peer_list)
self._db.execute("DELETE FROM peers WHERE ip = ?", (external_ip,))
if self._external_ip != None:
self._db.execute("DELETE FROM peers WHERE ip = ?", (self._external_ip,))
self.next_refresh = time.time() + self._refresh_time
utils.log('New peers : %s' % ', '.join(map(str, new_peer_list)), 5)
......@@ -51,5 +55,6 @@ class PeerManager:
utils.log('%s has disconnected' % (arg,), 3)
elif script_type == 'route-up':
utils.log('External Ip : ' + arg, 3)
self._external_ip = arg
else:
utils.log('Unknow message recieved from the openvpn pipe : ' + msg, 1)
......@@ -11,12 +11,8 @@ def openvpn(*args, **kw):
'--persist-key',
'--script-security', '2',
'--user', 'nobody',
# I don't kown how Babel works, but if it test the
# connection often, the ping directive might not be needed
# if it test the connection very often, we could also decrease
# ping-exit to 1 sec
# '--ping', '1',
# '--ping-exit', '3',
'--ping', '1',
'--ping-exit', '3',
'--group', 'nogroup',
'--verb', str(verbose),
] + list(args)
......@@ -26,7 +22,7 @@ def openvpn(*args, **kw):
# TODO : set iface up when creating a server/client
# ! check working directory before launching up script ?
def server(serverIp, network, max_clients, dh_path, pipe_fd, *args, **kw):
def server(serverIp, network, max_clients, dh_path, pipe_fd, port, proto, *args, **kw):
utils.log('Starting server', 3)
return openvpn(
'--tls-server',
......@@ -36,6 +32,8 @@ def server(serverIp, network, max_clients, dh_path, pipe_fd, *args, **kw):
'--client-disconnect', 'ovpn-server ' + str(pipe_fd),
'--dh', dh_path,
'--max-clients', str(max_clients),
'--port', str(port),
'--proto', proto,
*args, **kw)
def client(serverIp, pipe_fd, *args, **kw):
......
......@@ -193,9 +193,10 @@ class main(object):
def getPeerList(self, handler, n, address):
assert 0 < n < 1000
print "declaring new node"
if not self.declare(handler, address):
# TODO: do something intelligent
raise RuntimeError
if address != 0:
if not self.declare(handler, address):
# TODO: do something intelligent
raise RuntimeError
print "sending peers"
return self.db.execute("SELECT ip, port, proto FROM peers ORDER BY random() LIMIT ?", (n,)).fetchall()
......
......@@ -33,8 +33,8 @@ class TunnelManager:
if p.poll() != None:
utils.log('Connection with %s has failed with return code %s' % (id, p.returncode), 3)
self.free_interface_set.add(iface)
self.peer_db.unusePeer(id)
del self.connection_dict[id]
self._peer_db.unusePeer(id)
del self._connection_dict[id]
def _removeSomeTunnels(self):
for i in range(0, max(0, len(self._connection_dict) - self._client_count + self._refresh_count)):
......
......@@ -30,8 +30,14 @@ def getConfig():
help='Path to the certificate authority file')
_('--cert', required=True,
help='Path to the certificate file')
_('--ip', required=True, dest='external_ip',
_('--ip', default=None, dest='external_ip',
help='Ip address of the machine on the internet')
_('--internal-port', default=1194,
help='The internal port to listen on for incomming connections')
_('--external-port', default=1194,
help='The external port to advertise for other peers to connect')
_('--proto', default='udp',
help='The protocol to use for the others peers to connect')
# args to be removed ?
_('--connection-count', default=30, type=int,
help='Number of client connections')
......@@ -49,10 +55,6 @@ def main():
internal_ip = utils.ipFromCert(network, config.cert)
openvpn_args = utils.ovpnArgs(config.openvpn_args, config.ca, config.cert)
# Get real port and proto ?
port = 1194
proto = 'udp'
# Set global variables
tunnel.log = config.log
utils.verbose = plib.verbose = config.verbose
......@@ -63,7 +65,7 @@ def main():
read_pipe = os.fdopen(r_pipe)
# Init db and tunnels
peer_db = db.PeerManager(config.db, config.server, config.server_port, config.peers_db_refresh)
peer_db = db.PeerManager(config.db, config.server, config.server_port, config.peers_db_refresh, config.external_ip)
tunnel_manager = tunnel.TunnelManager(write_pipe, peer_db, openvpn_args, config.tunnel_refresh, config.connection_count, config.refresh_rate)
# Launch babel on all interfaces. WARNING : you have to be root to start babeld
......@@ -73,8 +75,8 @@ def main():
os.O_WRONLY | os.O_CREAT | os.O_TRUNC), stderr=subprocess.STDOUT)
# Establish connections
server_process = plib.server(internal_ip, network, config.connection_count, config.dh, write_pipe,
'--dev', 'vifibnet', *openvpn_args,
server_process = plib.server(internal_ip, network, config.connection_count, config.dh, write_pipe,
config.internal_port, config.proto, '--dev', 'vifibnet', *openvpn_args,
stdout=os.open(os.path.join(config.log, 'vifibnet.server.log'), os.O_WRONLY | os.O_CREAT | os.O_TRUNC))
# main loop
......@@ -85,7 +87,7 @@ def main():
if ready:
peer_db.handle_message(read_pipe.readline())
if time.time() >= peer_db.next_refresh:
peer_db.populate(200, (internal_ip, config.external_ip, port, proto))
peer_db.populate(200, internal_ip, config.external_port, config.proto)
if time.time() >= tunnel_manager.next_refresh:
tunnel_manager.refresh()
except KeyboardInterrupt:
......
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