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