Merge branch 'master' of https://git.erp5.org/repos/vifibnet
[re6stnet.git] / upnpigd.py
1 import miniupnpc
2 import time
3 import utils
4
5
6 class NoUPnPDevice(Exception):
7 def __init__(self):
8 pass
9
10 def __str__(self):
11 return 'No upnp device found'
12
13
14 class Forwarder:
15 def __init__(self):
16 self._u = miniupnpc.UPnP()
17 self._u.discoverdelay = 200
18 self._rules = []
19 self._u.discover()
20 try:
21 self._u.selectigd()
22 except:
23 raise NoUPnPDevice
24 self._external_ip = self._u.externalipaddress()
25 self.next_refresh = time.time()
26
27 def AddRule(self, local_port, proto):
28 # Init parameters
29 external_port = 1000
30 if proto == 'udp':
31 upnp_proto = 'UDP'
32 elif proto == 'tcp-server':
33 upnp_proto = 'TCP'
34 else:
35 utils.log('Unknown protocol : %s' % proto, 1)
36 raise RuntimeError
37
38 # Choose a free port
39 while True:
40 while self._u.getspecificportmapping(external_port,
41 upnp_proto) != None:
42 external_port += 1
43 if external_port == 65536:
44 return None
45
46 # Make the redirection
47 if self._u.addportmapping(external_port, 'UDP', self._u.lanaddr,
48 int(local_port), 'Vifib openvpn server', ''):
49 utils.log('Forwarding %s:%s to %s:%s' % (self._external_ip,
50 external_port, self._u.lanaddr, local_port), 3)
51 self._rules.append((external_port, upnp_proto))
52 return (self._external_ip, str(external_port), proto)
53
54 def Refresh(self):
55 for external_port, proto in self._rules:
56 self._u.addportmapping(external_port, proto, self._u.lanaddr,
57 self._local_port, 'Vifib openvpn server', '')
58 self.next_refresh = time.time() + 3600