Commit eb9a9237 authored by Jondy Zhao's avatar Jondy Zhao

tunnel.py: fix conflict

parent 50275cc2
import logging, platform, random, socket, subprocess, sys, time import logging, platform, random, socket, subprocess, sys, time
from collections import deque from collections import deque
from itertools import chain
from . import plib, utils from . import plib, utils
PORT = 326 PORT = 326
RTF_CACHE = 0x01000000 # cache entry
# Be careful the refresh interval should let the routes be established # Be careful the refresh interval should let the routes be established
...@@ -64,6 +62,7 @@ class Connection(object): ...@@ -64,6 +62,7 @@ class Connection(object):
'--tls-remote', '%u/%u' % (int(self._prefix, 2), len(self._prefix)), '--tls-remote', '%u/%u' % (int(self._prefix, 2), len(self._prefix)),
'--resolv-retry', '0', '--resolv-retry', '0',
'--connect-retry-max', '3', '--tls-exit', '--connect-retry-max', '3', '--tls-exit',
'--remap-usr1', 'SIGTERM',
'--ping-exit', str(timeout), '--ping-exit', str(timeout),
'--route-up', '%s %s' % (plib.ovpn_client, utils.get_pipename(write_pipe)), '--route-up', '%s %s' % (plib.ovpn_client, utils.get_pipename(write_pipe)),
*ovpn_args) *ovpn_args)
...@@ -277,8 +276,6 @@ class TunnelManager(object): ...@@ -277,8 +276,6 @@ class TunnelManager(object):
count -= self._makeTunnel(peer, address) count -= self._makeTunnel(peer, address)
else: else:
ip = utils.ipFromBin(self._network + peer) ip = utils.ipFromBin(self._network + peer)
# TODO: Send at least 1 address. This helps the registry
# node filling its cache when building a new network.
try: try:
self.sock.sendto('\2', (ip, PORT)) self.sock.sendto('\2', (ip, PORT))
except socket.error, e: except socket.error, e:
...@@ -316,27 +313,21 @@ class TunnelManager(object): ...@@ -316,27 +313,21 @@ class TunnelManager(object):
del self._distant_peers[:] del self._distant_peers[:]
for conn in self._connection_dict.itervalues(): for conn in self._connection_dict.itervalues():
conn.routes = 0 conn.routes = 0
a = len(self._network)
b = a + len(self._prefix)
other = [] other = []
for iface, ip, prefix_len in self._iterRoutes(): for iface, prefix in utils.iterRoutes(self._network, self._prefix):
if ip[:a] == self._network and ip[a:b] != self._prefix: assert iface != 'lo', (iface, prefix)
prefix = ip[a:prefix_len] nexthop = self._iface_to_prefix.get(iface)
logging.trace('Route on iface %s detected to %s/%u', if nexthop:
iface, utils.ipFromBin(ip), prefix_len) self._connection_dict[nexthop].routes += 1
nexthop = self._iface_to_prefix.get(iface) if prefix in self._served or prefix in self._connection_dict:
if nexthop: continue
self._connection_dict[nexthop].routes += 1 if iface in self._iface_list:
if prefix in self._served or prefix in self._connection_dict: other.append(prefix)
continue else:
if iface in self._iface_list: self._distant_peers.append(prefix)
other.append(prefix) registry = self._peer_db.registry_prefix
else: if registry == self._prefix or any(registry in x for x in (
self._distant_peers.append(prefix) self._distant_peers, other, self._served, self._connection_dict)):
is_registry = self._peer_db.registry_ip[a:].startswith
if is_registry(self._prefix) or any(is_registry(peer)
for peer in chain(self._distant_peers, other,
self._served, self._connection_dict)):
self._disconnected = None self._disconnected = None
# XXX: When there is no new peer to connect when looking at routes # XXX: When there is no new peer to connect when looking at routes
# coming from tunnels, we'd like to consider those discovered # coming from tunnels, we'd like to consider those discovered
...@@ -400,37 +391,34 @@ class TunnelManager(object): ...@@ -400,37 +391,34 @@ class TunnelManager(object):
return return
code = ord(msg[0]) code = ord(msg[0])
if code == 1: # answer if code == 1: # answer
# We parse the message in a way to discard a truncated line. # Old versions may send additional and obsolete addresses.
for peer in msg[1:].split('\n')[:-1]: # Ignore them, as well as truncated lines.
try: try:
prefix, address = peer.split() prefix, address = msg[1:msg.index('\n')].split()
int(prefix, 2) int(prefix, 2)
except ValueError: except ValueError:
break pass
else:
if prefix != self._prefix: if prefix != self._prefix:
self._peer_db.addPeer(prefix, address) self._peer_db.addPeer(prefix, address)
try: try:
self._connecting.remove(prefix) self._connecting.remove(prefix)
except KeyError: except KeyError:
continue pass
self._makeTunnel(prefix, address) else:
self._makeTunnel(prefix, address)
elif code == 2: # request elif code == 2: # request
encode = '%s %s\n'.__mod__
if self._address: if self._address:
msg = [encode((self._prefix, self._address))] msg = '\1%s %s\n' % (self._prefix, self._address)
else: # I don't know my IP yet!
msg = []
# Add an extra random peer, mainly for the registry.
if random.randint(0, self._peer_db.getPeerCount()):
msg.append(encode(self._peer_db.getPeerList().next()))
if msg:
try: try:
self.sock.sendto('\1' + ''.join(msg), address[:2]) self.sock.sendto(msg, address[:2])
except socket.error, e: except socket.error, e:
logging.info('Failed to reply to %s (%s)', address, e) logging.info('Failed to reply to %s (%s)', address, e)
#else: # I don't know my IP yet!
elif code == 255: elif code == 255:
# the registry wants to know the topology for debugging purpose # the registry wants to know the topology for debugging purpose
if utils.binFromIp(address[0]) == self._peer_db.registry_ip: if utils.binFromIp(address[0])[len(self._network):].startswith(
self._peer_db.registry_prefix):
msg = ['\xfe%s%u/%u\n%u\n' % (msg[1:], msg = ['\xfe%s%u/%u\n%u\n' % (msg[1:],
int(self._prefix, 2), len(self._prefix), int(self._prefix, 2), len(self._prefix),
len(self._connection_dict))] len(self._connection_dict))]
......
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