Commit 596050eb authored by Julien Muchembled's avatar Julien Muchembled

Experimental support of RINA

parent 674cad32
...@@ -271,7 +271,8 @@ def main(): ...@@ -271,7 +271,8 @@ def main():
remote_gateway, config.disable_proto, config.neighbour) remote_gateway, config.disable_proto, config.neighbour)
config.babel_args += tunnel_manager.new_iface_list config.babel_args += tunnel_manager.new_iface_list
else: else:
tunnel_manager = tunnel.BaseTunnelManager(cache, cert, address) tunnel_manager = tunnel.BaseTunnelManager(control_socket,
cache, cert, address)
cleanup.append(tunnel_manager.sock.close) cleanup.append(tunnel_manager.sock.close)
try: try:
...@@ -279,7 +280,7 @@ def main(): ...@@ -279,7 +280,7 @@ def main():
ipv4 = getattr(cache, 'ipv4', None) ipv4 = getattr(cache, 'ipv4', None)
if ipv4: if ipv4:
serial = int(cert.cert.get_subject().serialNumber) serial = cert.subject_serial
if cache.ipv4_sublen <= 16 and serial < 1 << cache.ipv4_sublen: if cache.ipv4_sublen <= 16 and serial < 1 << cache.ipv4_sublen:
dot4 = lambda x: socket.inet_ntoa(struct.pack('!I', x)) dot4 = lambda x: socket.inet_ntoa(struct.pack('!I', x))
ip4('route', 'unreachable', ipv4, 'proto', 'static') ip4('route', 'unreachable', ipv4, 'proto', 'static')
......
This diff is collapsed.
import errno, logging, os, random, socket, subprocess, struct, time, weakref import errno, json, logging, os, random
import socket, subprocess, struct, time, weakref
from collections import defaultdict, deque from collections import defaultdict, deque
from bisect import bisect, insort from bisect import bisect, insort
from OpenSSL import crypto from OpenSSL import crypto
from . import ctl, plib, utils, version, x509 from . import ctl, plib, rina, utils, version, x509
PORT = 326 PORT = 326
...@@ -172,8 +173,9 @@ class BaseTunnelManager(object): ...@@ -172,8 +173,9 @@ class BaseTunnelManager(object):
'ipv4', 'ipv4_sublen')) 'ipv4', 'ipv4_sublen'))
_forward = None _forward = None
_next_rina = True
def __init__(self, cache, cert, address=()): def __init__(self, control_socket, cache, cert, address=()):
self.cert = cert self.cert = cert
self._network = cert.network self._network = cert.network
self._prefix = cert.prefix self._prefix = cert.prefix
...@@ -200,6 +202,8 @@ class BaseTunnelManager(object): ...@@ -200,6 +202,8 @@ class BaseTunnelManager(object):
self._peers = [p] self._peers = [p]
self._timeouts = [(p.stop_date, self.invalidatePeers)] self._timeouts = [(p.stop_date, self.invalidatePeers)]
self.ctl = ctl.Babel(control_socket, weakref.proxy(self), self._network)
# Only to check routing cache. Should go back to # Only to check routing cache. Should go back to
# TunnelManager when we don't need to check it anymore. # TunnelManager when we don't need to check it anymore.
self._next_refresh = time.time() self._next_refresh = time.time()
...@@ -209,11 +213,19 @@ class BaseTunnelManager(object): ...@@ -209,11 +213,19 @@ class BaseTunnelManager(object):
t += self._timeouts t += self._timeouts
if self._next_refresh: # same comment as in __init__ if self._next_refresh: # same comment as in __init__
t.append((self._next_refresh, self.refresh)) t.append((self._next_refresh, self.refresh))
self.ctl.select(r, w, t)
def refresh(self): def refresh(self):
self._next_refresh = time.time() + 5 if self._next_rina and rina.update(self, False):
self._next_rina = False
self.ctl.request_dump()
self._next_refresh = time.time() + self.cache.hello
self.checkRoutingCache() self.checkRoutingCache()
def babel_dump(self):
rina.update(self, True)
self._next_rina = True
def selectTimeout(self, next, callback, force=True): def selectTimeout(self, next, callback, force=True):
t = self._timeouts t = self._timeouts
for i, x in enumerate(t): for i, x in enumerate(t):
...@@ -403,7 +415,17 @@ class BaseTunnelManager(object): ...@@ -403,7 +415,17 @@ class BaseTunnelManager(object):
if code == 3 and tunnel_killer.state == 'locked': # response if code == 3 and tunnel_killer.state == 'locked': # response
self._kill(peer) self._kill(peer)
elif code == 4: # node information elif code == 4: # node information
if not msg: if msg:
if not peer:
return
try:
ask, ver, protocol, rina_enabled = json.loads(msg)
except ValueError:
ask = rina_enabled = False
rina.enabled(self, peer, rina_enabled)
if ask:
return self._info(False)
else:
return version.version return version.version
elif code == 5: elif code == 5:
# the registry wants to know the topology for debugging purpose # the registry wants to know the topology for debugging purpose
...@@ -417,6 +439,16 @@ class BaseTunnelManager(object): ...@@ -417,6 +439,16 @@ class BaseTunnelManager(object):
if peer and self._prefix == self.cache.registry_prefix: if peer and self._prefix == self.cache.registry_prefix:
logging.info("%s/%s: %s", int(peer, 2), len(peer), msg) logging.info("%s/%s: %s", int(peer, 2), len(peer), msg)
def askInfo(self, prefix):
return self.sendto(prefix, '\4' + self._info(True))
def _info(self, ask):
return json.dumps((ask,
version.version,
version.protocol,
rina.shim is not None,
))
@staticmethod @staticmethod
def _restart(): def _restart():
raise utils.ReexecException( raise utils.ReexecException(
...@@ -542,8 +574,8 @@ class TunnelManager(BaseTunnelManager): ...@@ -542,8 +574,8 @@ class TunnelManager(BaseTunnelManager):
def __init__(self, control_socket, cache, cert, openvpn_args, def __init__(self, control_socket, cache, cert, openvpn_args,
timeout, client_count, iface_list, address, ip_changed, timeout, client_count, iface_list, address, ip_changed,
remote_gateway, disable_proto, neighbour_list=()): remote_gateway, disable_proto, neighbour_list=()):
super(TunnelManager, self).__init__(cache, cert, address) super(TunnelManager, self).__init__(control_socket,
self.ctl = ctl.Babel(control_socket, weakref.proxy(self), self._network) cache, cert, address)
self.ovpn_args = openvpn_args self.ovpn_args = openvpn_args
self.timeout = timeout self.timeout = timeout
self._read_sock, self.write_sock = socket.socketpair( self._read_sock, self.write_sock = socket.socketpair(
...@@ -609,7 +641,6 @@ class TunnelManager(BaseTunnelManager): ...@@ -609,7 +641,6 @@ class TunnelManager(BaseTunnelManager):
def select(self, r, w, t): def select(self, r, w, t):
super(TunnelManager, self).select(r, w, t) super(TunnelManager, self).select(r, w, t)
r[self._read_sock] = self.handleClientEvent r[self._read_sock] = self.handleClientEvent
self.ctl.select(r, w, t)
def refresh(self): def refresh(self):
logging.debug('Checking tunnels...') logging.debug('Checking tunnels...')
...@@ -651,6 +682,7 @@ class TunnelManager(BaseTunnelManager): ...@@ -651,6 +682,7 @@ class TunnelManager(BaseTunnelManager):
#if remove and len(self._connecting) < len(self._free_iface_list): #if remove and len(self._connecting) < len(self._free_iface_list):
# self._tuntap(self._free_iface_list.pop()) # self._tuntap(self._free_iface_list.pop())
self._next_refresh = time.time() + 5 self._next_refresh = time.time() + 5
rina.update(self, True)
def _cleanDeads(self): def _cleanDeads(self):
disconnected = False disconnected = False
......
...@@ -32,7 +32,7 @@ if dirty: ...@@ -32,7 +32,7 @@ if dirty:
# they are intended to the network admin. # they are intended to the network admin.
# Only 'protocol' is important and it must be increased whenever they would be # Only 'protocol' is important and it must be increased whenever they would be
# a wish to force an update of nodes. # a wish to force an update of nodes.
protocol = 2 protocol = 3
min_protocol = 1 min_protocol = 1
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -105,6 +105,10 @@ class Cert(object): ...@@ -105,6 +105,10 @@ class Cert(object):
def network(self): def network(self):
return networkFromCa(self.ca) return networkFromCa(self.ca)
@property
def subject_serial(self):
return int(self.cert.get_subject().serialNumber)
@property @property
def openvpn_args(self): def openvpn_args(self):
return ('--ca', self.ca_path, return ('--ca', self.ca_path,
...@@ -197,6 +201,8 @@ class Peer(object): ...@@ -197,6 +201,8 @@ class Peer(object):
def connected(self): def connected(self):
return self._last is None or time.time() < self._last + 60 return self._last is None or time.time() < self._last + 60
subject_serial = Cert.subject_serial
def __ne__(self, other): def __ne__(self, other):
raise AssertionError raise AssertionError
__eq__ = __ge__ = __le__ = __ne__ __eq__ = __ge__ = __le__ = __ne__
......
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