Mercurial > libervia-backend
comparison src/plugins/plugin_misc_nat-port.py @ 1536:04a13d9ae265
plugin nat-port: NAT port first draft:
- this plugin use UPnP-IGD (and maybe later NAT-PMP) to open a port or get local/external IP
- for now, only IP retrieval is implemented
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 29 Sep 2015 17:54:24 +0200 |
parents | |
children | e281ed2c21db |
comparison
equal
deleted
inserted
replaced
1535:c9ef16de3f13 | 1536:04a13d9ae265 |
---|---|
1 #!/usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # SAT plugin for NAT port mapping | |
5 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Jérôme Poisson (goffi@goffi.org) | |
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 | |
27 | |
28 try: | |
29 import miniupnpc | |
30 except ImportError: | |
31 raise exceptions.MissingModule(u"Missing module MiniUPnPc, please download/install it (and its Python binding) at http://miniupnp.free.fr/") | |
32 | |
33 | |
34 PLUGIN_INFO = { | |
35 "name": "NAT port mapping", | |
36 "import_name": "NAT-PORT", | |
37 "type": C.PLUG_TYPE_MISC, | |
38 "main": "NatPort", | |
39 "handler": "no", | |
40 "description": _("""Automatic NAT port mapping using UPnP"""), | |
41 } | |
42 | |
43 | |
44 class NatPort(object): | |
45 # TODO: refresh data if a new connection is detected (see plugin_misc_ip) | |
46 | |
47 def __init__(self, host): | |
48 log.info(_("plugin NAT Port initialization")) | |
49 self.host = host | |
50 self._external_ip = None | |
51 self._initialised = defer.Deferred() | |
52 self._upnp = miniupnpc.UPnP() # will be None if no device is available | |
53 self._upnp.discoverdelay=200 | |
54 discover_d = threads.deferToThread(self._discover) | |
55 discover_d.chainDeferred(self._initialised) | |
56 self._initialised.addErrback(self._init_failed) | |
57 | |
58 def _init_failed(self, failure): | |
59 log.info(u"UPnP-GID not available") | |
60 self._upnp = None | |
61 | |
62 def _discover(self): | |
63 devices = self._upnp.discover() | |
64 if devices: | |
65 log.info(u"{nb} UPnP-IGD device(s) found".format(nb=devices)) | |
66 else: | |
67 log.info(u"Can't find UPnP-IGD device on the local network") | |
68 raise exceptions.NotFound | |
69 self._upnp.selectigd() | |
70 self._external_ip = self._upnp.externalipaddress() | |
71 | |
72 def getIP(self, local=False): | |
73 """Return IP address found with UPnP-IGD | |
74 | |
75 @param local(bool): True to get external IP address, False to get local network one | |
76 @return (None, str): found IP address, or None of something got wrong | |
77 """ | |
78 def getIP(dummy): | |
79 if self._upnp is None: | |
80 return None | |
81 # lanaddr can be the empty string if not found, | |
82 # we need to return None in this case | |
83 return (self._upnp.lanaddr or None) if local else self._external_ip | |
84 return self._initialised.addCallback(getIP) |