Commit ab232120 authored by Ulysse Beaugnon's avatar Ulysse Beaugnon

Peers can now discover themselves without a central registry.

Currently, a peer broadcast its address to evrybody but this should change
parent 3b4883a8
...@@ -6,6 +6,13 @@ To be done : ...@@ -6,6 +6,13 @@ To be done :
Choose the number of peer we ask to the server Choose the number of peer we ask to the server
Test the package Test the package
remove some peers if their is too much in addpeer
check the ips attributed
remove populate
remove unused methodes from the registry
how do we make sure that none inject some false packets ?
how do we make sur that noone is declaring too much false nodes ?
--------------------------------------------------------------------------------- ---------------------------------------------------------------------------------
Put more information in the token mail ( registry ), such as : Put more information in the token mail ( registry ), such as :
......
...@@ -8,7 +8,7 @@ class PeerManager: ...@@ -8,7 +8,7 @@ class PeerManager:
def __init__(self, db_path, registry, key_path, refresh_time, address, def __init__(self, db_path, registry, key_path, refresh_time, address,
internal_ip, prefix, manual, pp, db_size): internal_ip, prefix, manual, pp, db_size):
self._refresh_time = refresh_time self._refresh_time = refresh_time
self._address = address self.address = address
self._internal_ip = internal_ip self._internal_ip = internal_ip
self._prefix = prefix self._prefix = prefix
self._db_size = db_size self._db_size = db_size
...@@ -17,8 +17,6 @@ class PeerManager: ...@@ -17,8 +17,6 @@ class PeerManager:
self._pp = pp self._pp = pp
self._manual = manual self._manual = manual
self.tunnel_manager = None self.tunnel_manager = None
self._sock = None
self.socket_file = None
logging.info('Connecting to peers database...') logging.info('Connecting to peers database...')
self._db = sqlite3.connect(db_path, isolation_level=None) self._db = sqlite3.connect(db_path, isolation_level=None)
...@@ -87,9 +85,9 @@ class PeerManager: ...@@ -87,9 +85,9 @@ class PeerManager:
return False return False
def _declare(self): def _declare(self):
if self._address != None: if self.address != None:
logging.info('Sending connection info to server...') logging.info('Sending connection info to server...')
self._proxy.declare(utils.address_str(self._address)) self._proxy.declare(utils.address_str(self.address))
logging.debug('Info sent') logging.debug('Info sent')
else: else:
logging.warning("Warning : couldn't send ip, unknown external config") logging.warning("Warning : couldn't send ip, unknown external config")
...@@ -129,20 +127,14 @@ class PeerManager: ...@@ -129,20 +127,14 @@ class PeerManager:
p = subprocess.Popen(('openssl', 'rsautl', '-decrypt', '-inkey', self._key_path), p = subprocess.Popen(('openssl', 'rsautl', '-decrypt', '-inkey', self._key_path),
stdin=subprocess.PIPE, stdout=subprocess.PIPE) stdin=subprocess.PIPE, stdout=subprocess.PIPE)
bootpeer = p.communicate(bootpeer)[0].split() bootpeer = p.communicate(bootpeer)[0].split()
if bootpeer[0] != self._prefix: return self._addPeer(bootpeer)
if int(self._db.execute("""SELECT COUNT(*) FROM blacklist.flag WHERE prefix = ?""", (bootpeer[0],)).next()[0]) > 0:
logging.info('BootPeer is blacklisted')
return False
self._db.execute("INSERT INTO peers (prefix, address) VALUES (?,?)", bootpeer)
logging.debug('Boot peer added')
return True
except socket.error: except socket.error:
pass pass
except sqlite3.IntegrityError, e: except sqlite3.IntegrityError, e:
if e.args[0] != 'column prefix is not unique': if e.args[0] != 'column prefix is not unique':
raise raise
except StopIteration: except:
logging.info('No peer available for bootstrap') logging.info('Unable to bootstrap')
return False return False
def usePeer(self, prefix): def usePeer(self, prefix):
...@@ -178,8 +170,8 @@ class PeerManager: ...@@ -178,8 +170,8 @@ class PeerManager:
external_ip = arg external_ip = arg
new_address = list([external_ip, port, proto] new_address = list([external_ip, port, proto]
for port, proto, _ in self._pp) for port, proto, _ in self._pp)
if self._address != new_address: if self.address != new_address:
self._address = new_address self.address = new_address
logging.info('Received new external ip : %s' logging.info('Received new external ip : %s'
% (external_ip,)) % (external_ip,))
try: try:
...@@ -188,18 +180,22 @@ class PeerManager: ...@@ -188,18 +180,22 @@ class PeerManager:
logging.debug('socket.error : %s' % e) logging.debug('socket.error : %s' % e)
logging.info('''Connection to server failed while logging.info('''Connection to server failed while
declaring external infos''') declaring external infos''')
elif script_type == 'up':
if int(arg) != 0:
logging.info('Server creation failed, terminating')
raise RuntimeError
logging.debug('Creating the socket for peer advertising')
time.sleep(5)
self._sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
self._sock.bind((self._internal_ip, 326))
self._socket_file = self._sock.makefile()
else: else:
logging.debug('Unknow message recieved from the openvpn pipe : %s' logging.debug('Unknow message recieved from the openvpn pipe : %s'
% msg) % msg)
def readSocket(self): def readSocket(self, msg):
print 'reading socket' peer = msg.split(' ')
if len(peer) != 2:
logging.debug('Invalid package recieved : %s' % msg)
return
self._addPeer(peer)
def _addPeer(self, peer):
logging.debug('Adding peer %s' % peer)
if int(self._db.execute("""SELECT COUNT(*) FROM blacklist.flag WHERE prefix = ?""", (peer[0],)).next()[0]) > 0:
logging.info('Peer is blacklisted')
return False
self._db.execute("INSERT INTO peers (prefix, address) VALUES (?,?)", peer)
logging.debug('Peer added')
return True
...@@ -42,13 +42,11 @@ script_type = os.environ['script_type'] ...@@ -42,13 +42,11 @@ script_type = os.environ['script_type']
if script_type == 'up': if script_type == 'up':
from subprocess import call from subprocess import call
dev = os.environ['dev'] dev = os.environ['dev']
if sys.argv[2] != 'none': if sys.argv[1] != 'none':
out = (call(('ip', 'link', 'set', dev, 'up')) sys.exit(call(('ip', 'link', 'set', dev, 'up'))
or call(('ip', 'addr', 'add', sys.argv[2], 'dev', dev))) or call(('ip', 'addr', 'add', sys.argv[1], 'dev', dev)))
os.write(int(sys.argv[1]), 'up %s\n' % out)
else: else:
out = call(('ip', 'link', 'set', dev, 'up')) sys.exit(call(('ip', 'link', 'set', dev, 'up')))
sys.exit(out)
if script_type == 'client-connect': if script_type == 'client-connect':
# Send client its external ip address # Send client its external ip address
......
...@@ -28,9 +28,9 @@ def openvpn(hello_interval, encrypt, *args, **kw): ...@@ -28,9 +28,9 @@ def openvpn(hello_interval, encrypt, *args, **kw):
def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hello_interval, encrypt, *args, **kw): def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hello_interval, encrypt, *args, **kw):
logging.debug('Starting server...') logging.debug('Starting server...')
if server_ip != '': if server_ip != '':
script_up = '%s %s %s/%u' % (ovpn_server, pipe_fd, server_ip, 64) script_up = '%s %s/%u' % (ovpn_server, server_ip, 64)
else: else:
script_up = '%s %s none' % (ovpn_server, pipe_fd) script_up = '%s none' % (ovpn_server)
return openvpn(hello_interval, encrypt, return openvpn(hello_interval, encrypt,
'--tls-server', '--tls-server',
'--mode', 'server', '--mode', 'server',
......
import os, traceback, time, subprocess, logging import os, traceback, time, subprocess, logging
import random import socket
import plib import plib
# Be carfull the refresh interval should let the routes be established # Be carfull the refresh interval should let the routes be established
...@@ -163,6 +163,13 @@ class TunnelManager: ...@@ -163,6 +163,13 @@ class TunnelManager:
return True return True
def _notifyPeer(self, peerIp): def _notifyPeer(self, peerIp):
ip = '%s:%s:%s:%s:%s:%s:%s:%s' % (peerIp[0:3], peerIp[4:7], peerIp[8:11], try:
peerIp[12:15], peerIp[16:19], peerIp[20:23], peerIp[24:27], peerIp[28:32]) if self._peer_db.address:
print ip ip = '%s:%s:%s:%s:%s:%s:%s:%s' % (peerIp[0:4], peerIp[4:8], peerIp[8:12],
peerIp[12:16], peerIp[16:20], peerIp[20:24], peerIp[24:28], peerIp[28:32])
logging.debug('Notifying peer %s' % ip)
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.sendto('%s %s\n' % (self._prefix, self._peer_db.address), (ip, 326))
except socket.error, e:
logging.debug('Unable to notify %s' % ip)
logging.debug('socket.error : %s' % e)
#!/usr/bin/env python #!/usr/bin/env python
import os, sys, select, time import os, sys, select, time, socket
import argparse, subprocess, sqlite3, logging, traceback import argparse, subprocess, sqlite3, logging, traceback
from argparse import ArgumentParser from argparse import ArgumentParser
from re6st import plib, utils, db, upnpigd, tunnel from re6st import plib, utils, db, upnpigd, tunnel
...@@ -144,6 +144,11 @@ def main(): ...@@ -144,6 +144,11 @@ def main():
config.iface_list, network, prefix, 2, config.encrypt) config.iface_list, network, prefix, 2, config.encrypt)
peer_db.tunnel_manager = tunnel_manager peer_db.tunnel_manager = tunnel_manager
# Create the socket to listen on
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.bind(('::', 326))
socket_file = sock.makefile()
# Launch routing protocol. WARNING : you have to be root to start babeld # Launch routing protocol. WARNING : you have to be root to start babeld
interface_list = list(tunnel_manager.free_interface_set) \ interface_list = list(tunnel_manager.free_interface_set) \
+ config.iface_list + list(iface + config.iface_list + list(iface
...@@ -175,10 +180,7 @@ def main(): ...@@ -175,10 +180,7 @@ def main():
if forwarder != None: if forwarder != None:
nextUpdate = min(nextUpdate, forwarder.next_refresh) nextUpdate = min(nextUpdate, forwarder.next_refresh)
nextUpdate = max(0, nextUpdate - time.time()) nextUpdate = max(0, nextUpdate - time.time())
select_list = [read_pipe] ready, tmp1, tmp2 = select.select([read_pipe, socket_file], [], [], nextUpdate)
if peer_db.socket_file:
select_list.append(peer_db.socket_file)
ready, tmp1, tmp2 = select.select(select_list, [], [], nextUpdate)
if read_pipe in ready: if read_pipe in ready:
peer_db.handle_message(read_pipe.readline()) peer_db.handle_message(read_pipe.readline())
if time.time() >= peer_db.next_refresh: if time.time() >= peer_db.next_refresh:
...@@ -187,8 +189,8 @@ def main(): ...@@ -187,8 +189,8 @@ def main():
tunnel_manager.refresh() tunnel_manager.refresh()
if forwarder != None and time.time() > forwarder.next_refresh: if forwarder != None and time.time() > forwarder.next_refresh:
forwarder.refresh() forwarder.refresh()
if peer_db.socket_file in ready: if socket_file in ready:
peer_db.readSocket() peer_db.readSocket(socket_file.readline())
finally: finally:
for p in [router] + server_process: for p in [router] + server_process:
try: try:
......
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