changeset 4180:b86912d3fd33

plugin IP: fix use of legacy URL + coroutine use: An https:/salut-a-toi.org URL was used to retrieve external IP, but it's not valid anymore, resulting in an exception. This feature is currently disabled. Also moved several methods from legacy inline callbacks to coroutines.
author Goffi <goffi@goffi.org>
date Sat, 09 Dec 2023 14:30:54 +0100 (12 months ago)
parents 3b95704ab777
children bc898879af34
files libervia/backend/plugins/plugin_misc_ip.py libervia/backend/plugins/plugin_xep_0065.py libervia/backend/plugins/plugin_xep_0260.py
diffstat 3 files changed, 60 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_misc_ip.py	Sat Dec 09 14:05:02 2023 +0100
+++ b/libervia/backend/plugins/plugin_misc_ip.py	Sat Dec 09 14:30:54 2023 +0100
@@ -200,8 +200,7 @@
         p.transport.loseConnection()
         return local_ip
 
-    @defer.inlineCallbacks
-    def get_local_i_ps(self, client):
+    async def get_local_ips(self, client):
         """Try do discover local area network IPs
 
         @return (deferred): list of lan IP addresses
@@ -210,7 +209,7 @@
         """
         # TODO: manage permission requesting (e.g. for UMTS link)
         if self._local_ip_cache is not None:
-            defer.returnValue(self._local_ip_cache)
+            return self._local_ip_cache
         addresses = []
         localhost = ["127.0.0.1"]
 
@@ -232,51 +231,50 @@
         ip = client.xmlstream.transport.getHost().host
         if self._filter_addresse(ip):
             self._insert_first(addresses, ip)
-            defer.returnValue(addresses)
+            return addresses
 
         # if server is local, we try with NAT-Port
         if self._nat is not None:
-            nat_ip = yield self._nat.get_ip(local=True)
+            nat_ip = await self._nat.get_ip(local=True)
             if nat_ip is not None:
                 self._insert_first(addresses, nat_ip)
-                defer.returnValue(addresses)
+                return addresses
 
             if addresses:
-                defer.returnValue(addresses)
+                return addresses
 
         # still not luck, we need to contact external website
-        allow_get_ip = yield self._external_allowed(client)
+        allow_get_ip = await self._external_allowed(client)
 
         if not allow_get_ip:
-            defer.returnValue(addresses or localhost)
+            return addresses or localhost
 
         try:
-            local_ip = yield defer.ensureDeferred(self._get_ip_from_external(GET_IP_PAGE))
+            local_ip = await defer.ensureDeferred(self._get_ip_from_external(GET_IP_PAGE))
         except (internet_error.DNSLookupError, internet_error.TimeoutError):
             log.warning("Can't access Domain Name System")
         else:
             if local_ip is not None:
                 self._insert_first(addresses, local_ip)
 
-        defer.returnValue(addresses or localhost)
+        return addresses or localhost
 
-    @defer.inlineCallbacks
-    def get_external_ip(self, client):
+    async def get_external_ip(self, client):
         """Try to discover external IP
 
         @return (deferred): external IP address or None if it can't be discovered
         """
         if self._external_ip_cache is not None:
-            defer.returnValue(self._external_ip_cache)
+            return self._external_ip_cache
 
         # we first try with XEP-0279
-        ip_check = yield self.host.hasFeature(client, NS_IP_CHECK)
+        ip_check = await self.host.hasFeature(client, NS_IP_CHECK)
         if ip_check:
             log.debug("Server IP Check available, we use it to retrieve our IP")
             iq_elt = client.IQ("get")
             iq_elt.addElement((NS_IP_CHECK, "address"))
             try:
-                result_elt = yield iq_elt.send()
+                result_elt = await iq_elt.send()
                 address_elt = next(result_elt.elements(NS_IP_CHECK, "address"))
                 ip_elt = next(address_elt.elements(NS_IP_CHECK, "ip"))
             except StopIteration:
@@ -291,33 +289,37 @@
                 external_ip = str(ip_elt)
                 log.debug("External IP found: {}".format(external_ip))
                 self._external_ip_cache = external_ip
-                defer.returnValue(self._external_ip_cache)
+                return self._external_ip_cache
 
         # then with NAT-Port
         if self._nat is not None:
-            nat_ip = yield self._nat.get_ip()
+            nat_ip = await self._nat.get_ip()
             if nat_ip is not None:
                 self._external_ip_cache = nat_ip
-                defer.returnValue(nat_ip)
+                return nat_ip
 
         # and finally by requesting external website
-        allow_get_ip = yield self._external_allowed(client)
-        try:
-            ip = ((yield webclient.getPage(GET_IP_PAGE.encode('utf-8')))
-                  if allow_get_ip else None)
-        except (internet_error.DNSLookupError, internet_error.TimeoutError):
-            log.warning("Can't access Domain Name System")
-            ip = None
-        except web_error.Error as e:
-            log.warning(
-                "Error while retrieving IP on {url}: {message}".format(
-                    url=GET_IP_PAGE, message=e
-                )
-            )
-            ip = None
-        else:
-            self._external_ip_cache = ip
-        defer.returnValue(ip)
+        allow_get_ip = await self._external_allowed(client)
+
+        ip = None
+
+        # FIXME: following code is deprecated, check it
+        # try:
+        #     ip = ((await webclient.getPage(GET_IP_PAGE.encode('utf-8')))
+        #           if allow_get_ip else None)
+        # except (internet_error.DNSLookupError, internet_error.TimeoutError):
+        #     log.warning("Can't access Domain Name System")
+        #     ip = None
+        # except web_error.Error as e:
+        #     log.warning(
+        #         "Error while retrieving IP on {url}: {message}".format(
+        #             url=GET_IP_PAGE, message=e
+        #         )
+        #     )
+        #     ip = None
+        # else:
+        #     self._external_ip_cache = ip
+        return ip
 
 
 @implementer(iwokkel.IDisco)
--- a/libervia/backend/plugins/plugin_xep_0065.py	Sat Dec 09 14:05:02 2023 +0100
+++ b/libervia/backend/plugins/plugin_xep_0065.py	Sat Dec 09 14:30:54 2023 +0100
@@ -784,8 +784,7 @@
             )
         return self._server_factory
 
-    @defer.inlineCallbacks
-    def get_proxy(self, client, local_jid):
+    async def get_proxy(self, client, local_jid):
         """Return the proxy available for this profile
 
         cache is used between clients using the same server
@@ -802,12 +801,12 @@
 
         server = client.host if client.is_component else client.jid.host
         try:
-            defer.returnValue(self._cache_proxies[server])
+            return self._cache_proxies[server]
         except KeyError:
             pass
         try:
             proxy = (
-                yield self.host.find_service_entities(client, "proxy", "bytestreams")
+                await self.host.find_service_entities(client, "proxy", "bytestreams")
             ).pop()
         except (defer.CancelledError, StopIteration, KeyError):
             notFound(server)
@@ -817,7 +816,7 @@
         iq_elt.addElement((NS_BS, "query"))
 
         try:
-            result_elt = yield iq_elt.send()
+            result_elt = await iq_elt.send()
         except jabber_error.StanzaError as failure:
             log.warning(
                 "Error while requesting proxy info on {jid}: {error}".format(
@@ -841,10 +840,9 @@
 
         proxy_infos = self._cache_proxies[server] = ProxyInfos(host, jid_, port)
         log.info("Proxy found: {}".format(proxy_infos))
-        defer.returnValue(proxy_infos)
+        return proxy_infos
 
-    @defer.inlineCallbacks
-    def _get_network_data(self, client):
+    async def _get_network_data(self, client):
         """Retrieve information about network
 
         @param client: %(doc_client)s
@@ -852,8 +850,8 @@
         """
         self.get_socks_5_server_factory()
         local_port = self._server_factory_port
-        external_ip = yield self._ip.get_external_ip(client)
-        local_ips = yield self._ip.get_local_i_ps(client)
+        external_ip = await self._ip.get_external_ip(client)
+        local_ips = await self._ip.get_local_ips(client)
 
         if external_ip is not None and self._external_port is None:
             if external_ip != local_ips[0]:
@@ -861,7 +859,7 @@
                 if self._np is None:
                     log.warning("NAT port plugin not available, we can't map port")
                 else:
-                    ext_port = yield self._np.map_port(
+                    ext_port = await self._np.map_port(
                         local_port, desc="SaT socks5 stream"
                     )
                     if ext_port is None:
@@ -869,10 +867,9 @@
                     else:
                         self._external_port = ext_port
 
-        defer.returnValue((local_port, self._external_port, local_ips, external_ip))
+        return (local_port, self._external_port, local_ips, external_ip)
 
-    @defer.inlineCallbacks
-    def get_candidates(self, client, local_jid):
+    async def get_candidates(self, client, local_jid):
         """Return a list of our stream candidates
 
         @param local_jid(jid.JID): jid to use as local jid
@@ -881,10 +878,10 @@
             client.jid would be file.example.net)
         @return (D(list[Candidate])): list of candidates, ordered by priority
         """
-        server_factory = yield self.get_socks_5_server_factory()
-        local_port, ext_port, local_ips, external_ip = yield self._get_network_data(client)
+        server_factory = self.get_socks_5_server_factory()
+        local_port, ext_port, local_ips, external_ip = await self._get_network_data(client)
         try:
-            proxy = yield self.get_proxy(client, local_jid)
+            proxy = await self.get_proxy(client, local_jid)
         except exceptions.NotFound:
             proxy = None
 
@@ -948,7 +945,7 @@
 
         # should be already sorted, but just in case the priorities get weird
         candidates.sort(key=lambda c: c.priority, reverse=True)
-        defer.returnValue(candidates)
+        return candidates
 
     def _add_connector(self, connector, candidate):
         """Add connector used to connect to candidate, and return client factory's connection Deferred
@@ -1164,7 +1161,7 @@
             args = [client, session_data, local_jid]
             d.addCallbacks(self._iq_negotiation_cb, self._iq_negotiation_eb, args, None, args)
 
-        self.get_candidates(client, local_jid).addCallback(got_candidates)
+        defer.ensureDeferred(self.get_candidates(client, local_jid)).addCallback(got_candidates)
         return session_data[DEFER_KEY]
 
     def _iq_negotiation_cb(self, iq_elt, client, session_data, local_jid):
--- a/libervia/backend/plugins/plugin_xep_0260.py	Sat Dec 09 14:05:02 2023 +0100
+++ b/libervia/backend/plugins/plugin_xep_0260.py	Sat Dec 09 14:30:54 2023 +0100
@@ -134,8 +134,7 @@
             candidate_elt["type"] = candidate.type
         return transport_elt
 
-    @defer.inlineCallbacks
-    def jingle_session_init(self, client, session, content_name):
+    async def jingle_session_init(self, client, session, content_name):
         content_data = session["contents"][content_name]
         transport_data = content_data["transport_data"]
         sid = transport_data["sid"] = str(uuid.uuid4())
@@ -146,14 +145,14 @@
             session["peer_jid"], session["local_jid"], sid
         )  # requester and target are inversed for peer candidates
         transport_data["stream_d"] = self._s5b.register_hash(client, session_hash, None)
-        candidates = transport_data["candidates"] = yield self._s5b.get_candidates(
+        candidates = transport_data["candidates"] = await self._s5b.get_candidates(
             client, session["local_jid"])
         mode = "tcp"  # XXX: we only manage tcp for now
         transport_elt = self._build_candidates(
             session, candidates, sid, session_hash, client, mode
         )
 
-        defer.returnValue(transport_elt)
+        return transport_elt
 
     def _proxy_activated_cb(self, iq_result_elt, client, candidate, session, content_name):
         """Called when activation confirmation has been received from proxy
@@ -398,8 +397,7 @@
         else:
             activation_d.errback(ProxyError())
 
-    @defer.inlineCallbacks
-    def jingle_handler(self, client, action, session, content_name, transport_elt):
+    async def jingle_handler(self, client, action, session, content_name, transport_elt):
         content_data = session["contents"][content_name]
         transport_data = content_data["transport_data"]
 
@@ -451,7 +449,7 @@
             d.addCallback(
                 self._found_peer_candidate, session, transport_data, content_name, client
             )
-            candidates = yield self._s5b.get_candidates(client, session["local_jid"])
+            candidates = await self._s5b.get_candidates(client, session["local_jid"])
             # we remove duplicate candidates
             candidates = [
                 candidate for candidate in candidates if candidate not in peer_candidates
@@ -493,7 +491,7 @@
         else:
             log.warning("FIXME: unmanaged action {}".format(action))
 
-        defer.returnValue(transport_elt)
+        return transport_elt
 
     def jingle_terminate(self, client, action, session, content_name, reason_elt):
         if reason_elt.decline: