Mercurial > libervia-backend
annotate sat/plugins/plugin_misc_nat-port.py @ 2589:282d1314d574
plugin XEP-0329: new methods/signals to handle shares:
2 new methods:
- FISLocalSharesGet retrieve paths shared locally
- FISUnsharePath stop sharing a file or directory
2 new signals:
- FISSharedPathNew triggered when a new path is shared
- FISSharedPathRemoved triggered when a path is not shared anymore
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 22 May 2018 10:06:07 +0200 |
parents | 26edcf3a30eb |
children | 56f94936df1e |
rev | line source |
---|---|
1934
2daf7b4c6756
use of /usr/bin/env instead of /usr/bin/python in shebang
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1 #!/usr/bin/env python2 |
1536 | 2 # -*- coding: utf-8 -*- |
3 | |
4 # SAT plugin for NAT port mapping | |
2483 | 5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org) |
1536 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from sat.core.i18n import _ | |
21 from sat.core.constants import Const as C | |
22 from sat.core.log import getLogger | |
23 log = getLogger(__name__) | |
24 from sat.core import exceptions | |
25 from twisted.internet import threads | |
26 from twisted.internet import defer | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
27 from twisted.python import failure |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
28 import threading |
1536 | 29 |
30 try: | |
31 import miniupnpc | |
32 except ImportError: | |
1562
7d91dff71067
plugin NAT Port: added instruction with pip when miniupnpc is missing
Goffi <goffi@goffi.org>
parents:
1554
diff
changeset
|
33 raise exceptions.MissingModule(u"Missing module MiniUPnPc, please download/install it (and its Python binding) at http://miniupnp.free.fr/ (or use pip install miniupnpc)") |
1536 | 34 |
35 | |
36 PLUGIN_INFO = { | |
2145
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
37 C.PI_NAME: "NAT port mapping", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
38 C.PI_IMPORT_NAME: "NAT-PORT", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
39 C.PI_TYPE: C.PLUG_TYPE_MISC, |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
40 C.PI_MAIN: "NatPort", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
41 C.PI_HANDLER: "no", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
42 C.PI_DESCRIPTION: _("""Automatic NAT port mapping using UPnP"""), |
1536 | 43 } |
44 | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
45 STARTING_PORT = 6000 # starting point to automatically find a port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
46 DEFAULT_DESC = u'SaT port mapping' # we don't use "à" here as some bugged NAT don't manage charset correctly |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
47 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
48 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
49 class MappingError(Exception): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
50 pass |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
51 |
1536 | 52 |
53 class NatPort(object): | |
54 # TODO: refresh data if a new connection is detected (see plugin_misc_ip) | |
55 | |
56 def __init__(self, host): | |
57 log.info(_("plugin NAT Port initialization")) | |
58 self.host = host | |
59 self._external_ip = None | |
60 self._initialised = defer.Deferred() | |
61 self._upnp = miniupnpc.UPnP() # will be None if no device is available | |
62 self._upnp.discoverdelay=200 | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
63 self._mutex = threading.Lock() # used to protect access to self._upnp |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
64 self._starting_port_cache = None # used to cache the first available port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
65 self._to_unmap = [] # list of tuples (ext_port, protocol) of ports to unmap on unload |
1536 | 66 discover_d = threads.deferToThread(self._discover) |
67 discover_d.chainDeferred(self._initialised) | |
68 self._initialised.addErrback(self._init_failed) | |
69 | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
70 def unload(self): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
71 if self._to_unmap: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
72 log.info(u"Cleaning mapped ports") |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
73 return threads.deferToThread(self._unmapPortsBlocking) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
74 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
75 def _init_failed(self, failure_): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
76 e = failure_.trap(exceptions.NotFound, exceptions.FeatureNotFound) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
77 if e == exceptions.FeatureNotFound: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
78 log.info(u"UPnP-IGD seems to be not activated on the device") |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
79 else: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
80 log.info(u"UPnP-IGD not available") |
1536 | 81 self._upnp = None |
82 | |
83 def _discover(self): | |
84 devices = self._upnp.discover() | |
85 if devices: | |
86 log.info(u"{nb} UPnP-IGD device(s) found".format(nb=devices)) | |
87 else: | |
88 log.info(u"Can't find UPnP-IGD device on the local network") | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
89 raise failure.Failure(exceptions.NotFound()) |
1536 | 90 self._upnp.selectigd() |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
91 try: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
92 self._external_ip = self._upnp.externalipaddress() |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
93 except Exception: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
94 raise failure.Failure(exceptions.FeatureNotFound()) |
1536 | 95 |
96 def getIP(self, local=False): | |
97 """Return IP address found with UPnP-IGD | |
98 | |
99 @param local(bool): True to get external IP address, False to get local network one | |
100 @return (None, str): found IP address, or None of something got wrong | |
101 """ | |
102 def getIP(dummy): | |
103 if self._upnp is None: | |
104 return None | |
105 # lanaddr can be the empty string if not found, | |
106 # we need to return None in this case | |
107 return (self._upnp.lanaddr or None) if local else self._external_ip | |
108 return self._initialised.addCallback(getIP) | |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
109 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
110 def _unmapPortsBlocking(self): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
111 """Unmap ports mapped in this session""" |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
112 self._mutex.acquire() |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
113 try: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
114 for port, protocol in self._to_unmap: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
115 log.info(u"Unmapping port {}".format(port)) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
116 unmapping = self._upnp.deleteportmapping( |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
117 # the last parameter is remoteHost, we don't use it |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
118 port, protocol, '') |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
119 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
120 if not unmapping: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
121 log.error(u"Can't unmap port {port} ({protocol})".format( |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
122 port=port, protocol=protocol)) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
123 del self._to_unmap[:] |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
124 finally: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
125 self._mutex.release() |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
126 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
127 def _mapPortBlocking(self, int_port, ext_port, protocol, desc): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
128 """Internal blocking method to map port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
129 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
130 @param int_port(int): internal port to use |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
131 @param ext_port(int): external port to use, or None to find one automatically |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
132 @param protocol(str): 'TCP' or 'UDP' |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
133 @param desc(str): description of the mapping |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
134 @param return(int, None): external port used in case of success, otherwise None |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
135 """ |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
136 # we use mutex to avoid race condition if 2 threads |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
137 # try to acquire a port at the same time |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
138 self._mutex.acquire() |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
139 try: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
140 if ext_port is None: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
141 # find a free port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
142 starting_port = self._starting_port_cache |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
143 ext_port = STARTING_PORT if starting_port is None else starting_port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
144 ret = self._upnp.getspecificportmapping(ext_port, protocol) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
145 while ret != None and ext_port < 65536: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
146 ext_port += 1 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
147 ret = self._upnp.getspecificportmapping(ext_port, protocol) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
148 if starting_port is None: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
149 # XXX: we cache the first successfuly found external port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
150 # to avoid testing again the first series the next time |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
151 self._starting_port_cache = ext_port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
152 |
2488
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
153 try: |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
154 mapping = self._upnp.addportmapping( |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
155 # the last parameter is remoteHost, we don't use it |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
156 ext_port, protocol, self._upnp.lanaddr, int_port, desc, '') |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
157 except Exception as e: |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
158 log.error(_(u"addportmapping error: {msg}").format(msg=e)) |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
159 raise failure.Failure(MappingError()) |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
160 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
161 if not mapping: |
2488
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
162 raise failure.Failure(MappingError()) |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
163 else: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
164 self._to_unmap.append((ext_port, protocol)) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
165 finally: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
166 self._mutex.release() |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
167 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
168 return ext_port |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
169 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
170 def mapPort(self, int_port, ext_port=None, protocol='TCP', desc=DEFAULT_DESC): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
171 """Add a port mapping |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
172 |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
173 @param int_port(int): internal port to use |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
174 @param ext_port(int,None): external port to use, or None to find one automatically |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
175 @param protocol(str): 'TCP' or 'UDP' |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
176 @param desc(unicode): description of the mapping |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
177 Some UPnP IGD devices have broken encoding. It's probably a good idea to avoid non-ascii chars here |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
178 @return (D(int, None)): external port used in case of success, otherwise None |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
179 """ |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
180 if self._upnp is None: |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
181 return defer.succeed(None) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
182 def mappingCb(ext_port): |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
183 log.info(u"{protocol} mapping from {int_port} to {ext_port} successful".format( |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
184 protocol = protocol, |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
185 int_port = int_port, |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
186 ext_port = ext_port, |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
187 )) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
188 return ext_port |
2488
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
189 def mappingEb(failure_): |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
190 failure_.trap(MappingError) |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
191 log.warning(u"Can't map internal {int_port}".format(int_port=int_port)) |
2488
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
192 def mappingUnknownEb(failure_): |
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
193 log.error(_(u"error while trying to map ports: {msg}").format(msg=failure_)) |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
194 d = threads.deferToThread(self._mapPortBlocking, int_port, ext_port, protocol, desc) |
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
195 d.addCallbacks(mappingCb, mappingEb) |
2488
78c7992a26ed
plugin NAT-port: raise MappingError if something get wrong during "addportmapping" + log unexpected errors (i.e. everything else than MappingError)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
196 d.addErrback(mappingUnknownEb) |
1554
e281ed2c21db
plugin NAT port: added UPnP IGD mapping + automatic unmapping on backend shut down
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
197 return d |