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

Experimental support of RINA

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