Mercurial > libervia-backend
diff src/plugins/plugin_misc_ip.py @ 1566:ec3848916ee8
plugin ip: implemented XEP-0279 for external ip retrieval + fixed bad exception handling
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 08 Nov 2015 14:44:30 +0100 |
parents | eb8aae35085b |
children | d5f59ba166fe |
line wrap: on
line diff
--- a/src/plugins/plugin_misc_ip.py Fri Nov 06 17:09:45 2015 +0100 +++ b/src/plugins/plugin_misc_ip.py Sun Nov 08 14:44:30 2015 +0100 @@ -28,6 +28,9 @@ 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ d.addCallback(gotConnection) return d - @defer.inlineCallbacks def getLocalIPs(self, profile): """Try do discover local area network IPs @@ -228,13 +234,12 @@ 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 @@ 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 []