plugin ip: implemented XEP-0279 for external ip retrieval + fixed bad exception handling
This commit is contained in:
parent
83eef838a6
commit
1a5f1bd144
2 changed files with 44 additions and 13 deletions
|
|
@ -28,6 +28,9 @@ from twisted.internet import reactor
|
|||
from twisted.internet import protocol
|
||||
from twisted.internet import endpoints
|
||||
from twisted.internet import error as internet_error
|
||||
from zope.interface import implements
|
||||
from wokkel import disco, iwokkel
|
||||
from twisted.words.protocols.jabber.xmlstream import XMPPHandler
|
||||
import urlparse
|
||||
try:
|
||||
import netifaces
|
||||
|
|
@ -40,9 +43,10 @@ PLUGIN_INFO = {
|
|||
"name": "IP discovery",
|
||||
"import_name": "IP",
|
||||
"type": C.PLUG_TYPE_MISC,
|
||||
"protocols": ["XEP-0279"],
|
||||
"recommendations": ["NAT-PORT"],
|
||||
"main": "IPPlugin",
|
||||
"handler": "no",
|
||||
"handler": "yes",
|
||||
"description": _("""This plugin help to discover our external IP address.""")
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +66,7 @@ Do you agree to do this request ?
|
|||
page = GET_IP_PAGE,
|
||||
domain = urlparse.urlparse(GET_IP_PAGE).netloc,
|
||||
app_name = C.APP_NAME)
|
||||
NS_IP_CHECK = "urn:xmpp:sic:1"
|
||||
|
||||
PARAMS = """
|
||||
<params>
|
||||
|
|
@ -77,7 +82,6 @@ PARAMS = """
|
|||
class IPPlugin(object):
|
||||
# TODO: refresh IP if a new connection is detected
|
||||
# TODO: manage IPv6 when implemented in SàT
|
||||
# TODO: implement XEP-0279
|
||||
|
||||
def __init__(self, host):
|
||||
log.info(_("plugin IP discovery initialization"))
|
||||
|
|
@ -96,6 +100,9 @@ class IPPlugin(object):
|
|||
self._external_ip_cache = None
|
||||
self._local_ip_cache = None
|
||||
|
||||
def getHandler(self, profile):
|
||||
return IPPlugin_handler()
|
||||
|
||||
def refreshIP(self):
|
||||
# FIXME: use a trigger instead ?
|
||||
self._external_ip_cache = None
|
||||
|
|
@ -174,7 +181,6 @@ class IPPlugin(object):
|
|||
d.addCallback(gotConnection)
|
||||
return d
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def getLocalIPs(self, profile):
|
||||
"""Try do discover local area network IPs
|
||||
|
|
@ -228,13 +234,12 @@ class IPPlugin(object):
|
|||
|
||||
try:
|
||||
ip_tuple = yield self._getIPFromExternal(GET_IP_PAGE)
|
||||
except Exception as internet_error.DNSLookupError:
|
||||
except (internet_error.DNSLookupError, internet_error.TimeoutError):
|
||||
log.warning(u"Can't access Domain Name System")
|
||||
defer.returnValue(addresses)
|
||||
self._insertFirst(addresses, ip_tuple.local)
|
||||
defer.returnValue(addresses)
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def getExternalIP(self, profile):
|
||||
"""Try to discover external IP
|
||||
|
|
@ -245,20 +250,50 @@ class IPPlugin(object):
|
|||
if self._external_ip_cache is not None:
|
||||
defer.returnValue(self._external_ip_cache)
|
||||
|
||||
# we first try with NAT-Port
|
||||
# we first try with XEP-0279
|
||||
if self.host.hasFeature(NS_IP_CHECK, profile=profile):
|
||||
log.debug(u"Server IP Check available, we use it to retrieve our IP")
|
||||
client = self.host.getClient(profile)
|
||||
iq_elt = client.IQ("get")
|
||||
iq_elt.addElement((NS_IP_CHECK, 'address'))
|
||||
result_elt = yield iq_elt.send()
|
||||
try:
|
||||
address_elt = result_elt.elements(NS_IP_CHECK, 'address').next()
|
||||
ip_elt = address_elt.elements(NS_IP_CHECK,'ip').next()
|
||||
except StopIteration:
|
||||
log.warning(u"Server returned invalid result on XEP-0279 request, we ignore it")
|
||||
else:
|
||||
# FIXME: server IP may not be the same as external IP (server can be on local machine or network)
|
||||
# IP should be checked to see if we have a local one, and rejected in this case
|
||||
external_ip = str(ip_elt)
|
||||
log.debug(u"External IP found: {}".format(external_ip))
|
||||
self._external_ip_cache = external_ip
|
||||
defer.returnValue(self._external_ip_cache)
|
||||
|
||||
# then with NAT-Port
|
||||
if self._nat is not None:
|
||||
nat_ip = yield self._nat.getIP()
|
||||
if nat_ip is not None:
|
||||
self._external_ip_cache = nat_ip
|
||||
defer.returnValue(nat_ip)
|
||||
|
||||
# then by requesting external website
|
||||
# and finally by requesting external website
|
||||
allow_get_ip = yield self._externalAllowed(profile)
|
||||
try:
|
||||
ip = (yield webclient.getPage(GET_IP_PAGE)) if allow_get_ip else None
|
||||
except internet_error.DNSLookupError:
|
||||
except (internet_error.DNSLookupError, internet_error.TimeoutError):
|
||||
log.warning(u"Can't access Domain Name System")
|
||||
ip = None
|
||||
else:
|
||||
self._external_ip_cache = ip
|
||||
defer.returnValue(ip)
|
||||
|
||||
|
||||
class IPPlugin_handler(XMPPHandler):
|
||||
implements(iwokkel.IDisco)
|
||||
|
||||
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
|
||||
return [disco.DiscoFeature(NS_IP_CHECK)]
|
||||
|
||||
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -30,11 +30,7 @@ import os.path
|
|||
from twisted.words.xish import domish
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.python import failure
|
||||
|
||||
try:
|
||||
from twisted.words.protocols.xmlstream import XMPPHandler
|
||||
except ImportError:
|
||||
from wokkel.subprotocols import XMPPHandler
|
||||
from twisted.words.protocols.jabber.xmlstream import XMPPHandler
|
||||
|
||||
|
||||
NS_JINGLE_FT = 'urn:xmpp:jingle:apps:file-transfer:4'
|
||||
|
|
|
|||
Loading…
Reference in a new issue