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()
self._u.selectigd() try:
self._u.selectigd()
if 'udp' in protos: except:
while self._u.getspecificportmapping(self.external_port, raise NoUPnPDevice
'UDP') != None: self._external_ip = self._u.externalipaddress()
self.external_port += 1 self.next_refresh = time.time()
if self.external_port == 65536:
raise Exception def AddRule(self, local_port, proto):
if 'tcp-server' in protos: # Init parameters
while self._u.getspecificportmapping(self.external_port, external_port = 1000
'TCP') != None: if proto == 'udp':
self.external_port += 1 upnp_proto = 'UDP'
if self._external_port == 65536: elif proto == 'tcp-server':
raise Exception upnp_proto = 'TCP'
else:
if 'udp' in protos: utils.log('Unknown protocol : %s' % proto, 1)
self._u.addportmapping(self.external_port, 'UDP', raise RuntimeError
self._u.lanaddr, local_port, 'Vifib openvpn server', '')
if 'tcp-server' in protos: # Choose a free port
self._u.addportmapping(self.external_port, 'TCP', while True:
self._u.lanaddr, local_port, 'Vifib openvpn server', '') while self._u.getspecificportmapping(external_port,
upnp_proto) != None:
self.external_ip = self._u.externalipaddress() external_port += 1
utils.log('Forwarding %s:%s to %s:%s' % (self.external_ip, if external_port == 65536:
self.external_port, self._u.lanaddr, local_port), 3) return None
self.next_refresh = time.time() + 3600
# Make the redirection
if self._u.addportmapping(external_port, 'UDP', self._u.lanaddr,
int(local_port), 'Vifib openvpn server', ''):
utils.log('Forwarding %s:%s to %s:%s' % (self._external_ip,
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