Commit d4ec57c5 authored by Ulysse Beaugnon's avatar Ulysse Beaugnon

fix in upnpigd and tunnel

parent 0820ffd1
import os, random, traceback, time, struct import os, random, traceback, time, struct, operator
import plib, utils, db import plib, utils, db
log = None log = None
smooth = 0.3 smooth = 0.3 # this is used to smooth the traffic sampling. Lower value
# mean more smooth
# Be carfull the refresh interval should let the routes be established
class Connection: class Connection:
...@@ -17,7 +20,6 @@ class Connection: ...@@ -17,7 +20,6 @@ class Connection:
self.iface = iface self.iface = iface
self.routes = 0 self.routes = 0
self._prefix = prefix self._prefix = prefix
self._creation_date = time.time()
self._bandwidth = None self._bandwidth = None
self._last_trafic = None self._last_trafic = None
...@@ -96,9 +98,12 @@ class TunnelManager: ...@@ -96,9 +98,12 @@ class TunnelManager:
self._peer_db.flagPeer(prefix) self._peer_db.flagPeer(prefix)
def _removeSomeTunnels(self): def _removeSomeTunnels(self):
for i in range(0, max(0, len(self._connection_dict) - # Get the candidates to killing
self._client_count + self._refresh_count)): candidates = sorted(self._connection_dict, key=lambda p:
prefix = random.choice(self._connection_dict.keys()) self._connection_dict[p].routes)
for prefix in candidates[0: max(0, len(self._connection_dict) -
self._client_count + self._refresh_count)]:
self._kill(prefix) self._kill(prefix)
def _kill(self, prefix): def _kill(self, prefix):
......
...@@ -3,47 +3,56 @@ import time ...@@ -3,47 +3,56 @@ import time
import utils import utils
class UpnpForward: class NoUPnPDevice(Exception):
def __init__(self, local_port, protos): def __init__(self):
pass
def __str__(self):
return 'No upnp device found'
class Forwarder:
def __init__(self):
self._u = miniupnpc.UPnP() self._u = miniupnpc.UPnP()
self._u.discoverdelay = 200 self._u.discoverdelay = 200
self.external_port = 1000 self._rules = []
self._local_port = local_port
self._protos = protos
self._u.discover() self._u.discover()
try:
self._u.selectigd() self._u.selectigd()
except:
raise NoUPnPDevice
self._external_ip = self._u.externalipaddress()
self.next_refresh = time.time()
if 'udp' in protos: def AddRule(self, local_port, proto):
while self._u.getspecificportmapping(self.external_port, # Init parameters
'UDP') != None: external_port = 1000
self.external_port += 1 if proto == 'udp':
if self.external_port == 65536: upnp_proto = 'UDP'
raise Exception elif proto == 'tcp-server':
if 'tcp-server' in protos: upnp_proto = 'TCP'
while self._u.getspecificportmapping(self.external_port, else:
'TCP') != None: utils.log('Unknown protocol : %s' % proto, 1)
self.external_port += 1 raise RuntimeError
if self._external_port == 65536:
raise Exception # Choose a free port
while True:
if 'udp' in protos: while self._u.getspecificportmapping(external_port,
self._u.addportmapping(self.external_port, 'UDP', upnp_proto) != None:
self._u.lanaddr, local_port, 'Vifib openvpn server', '') external_port += 1
if 'tcp-server' in protos: if external_port == 65536:
self._u.addportmapping(self.external_port, 'TCP', return None
self._u.lanaddr, local_port, 'Vifib openvpn server', '')
# Make the redirection
self.external_ip = self._u.externalipaddress() if self._u.addportmapping(external_port, 'UDP', self._u.lanaddr,
utils.log('Forwarding %s:%s to %s:%s' % (self.external_ip, int(local_port), 'Vifib openvpn server', ''):
self.external_port, self._u.lanaddr, local_port), 3) utils.log('Forwarding %s:%s to %s:%s' % (self._external_ip,
self.next_refresh = time.time() + 3600 external_port, self._u.lanaddr, local_port), 3)
self._rules.append((external_port, upnp_proto))
return (self._external_ip, str(external_port), proto)
def Refresh(self): def Refresh(self):
if 'udp' in self._protos: for external_port, proto in self._rules:
self._u.addportmapping(self.external_port, 'UDP', self._u.lanaddr, self._u.addportmapping(external_port, proto, self._u.lanaddr,
self._local_port, 'Vifib openvpn server', '')
if 'tcp-server' in self._protos:
self._u.addportmapping(self.external_port, 'TCP', self._u.lanaddr,
self._local_port, 'Vifib openvpn server', '') self._local_port, 'Vifib openvpn server', '')
self.next_refresh = time.time() + 3600 self.next_refresh = time.time() + 3600
...@@ -100,19 +100,20 @@ def main(): ...@@ -100,19 +100,20 @@ def main():
read_pipe = os.fdopen(r_pipe) read_pipe = os.fdopen(r_pipe)
# Init db and tunnels # Init db and tunnels
forwarder = None
if manual: if manual:
utils.log('Manual external configuration', 3) utils.log('Manual external configuration', 3)
forward = None
else: else:
utils.log('Attempting automatic configuration via UPnP', 4) utils.log('Attempting automatic configuration via UPnP', 4)
try: try:
forward = list([upnpigd.UpnpForward(int(port), proto), proto] forwarder = upnpigd.Forwarder()
for port, proto in config.pp) config.address = []
config.address = list([ext.external_ip, str(ext.external_port), for port, proto in config.pp:
proto] for ext, proto in forward) ext = forwarder.AddRule(port, proto)
except Exception: if ext:
forward = None config.address.append(ext)
utils.log('An atempt to forward a port via UPnP failed', 4) except upnpigd.NoUPnPDevice:
utils.log('No upnp device found', 4)
peer_db = db.PeerManager(config.state, config.server, config.server_port, peer_db = db.PeerManager(config.state, config.server, config.server_port,
config.peers_db_refresh, config.address, internal_ip, prefix, config.peers_db_refresh, config.address, internal_ip, prefix,
...@@ -142,8 +143,8 @@ def main(): ...@@ -142,8 +143,8 @@ def main():
try: try:
while True: while True:
nextUpdate = min(tunnel_manager.next_refresh, peer_db.next_refresh) nextUpdate = min(tunnel_manager.next_refresh, peer_db.next_refresh)
if forward != None: if forwarder != None:
nextUpdate = min(nextUpdate, forward.next_refresh) nextUpdate = min(nextUpdate, forwarder.next_refresh)
nextUpdate = max(0, nextUpdate - time.time()) nextUpdate = max(0, nextUpdate - time.time())
ready, tmp1, tmp2 = select.select([read_pipe], [], [], nextUpdate) ready, tmp1, tmp2 = select.select([read_pipe], [], [], nextUpdate)
......
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