comparison libervia/backend/plugins/plugin_xep_0065.py @ 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
parents 4b842c1fb686
children 0d7bb4df2343
comparison
equal deleted inserted replaced
4179:3b95704ab777 4180:b86912d3fd33
782 self._server_factory_port 782 self._server_factory_port
783 ) 783 )
784 ) 784 )
785 return self._server_factory 785 return self._server_factory
786 786
787 @defer.inlineCallbacks 787 async def get_proxy(self, client, local_jid):
788 def get_proxy(self, client, local_jid):
789 """Return the proxy available for this profile 788 """Return the proxy available for this profile
790 789
791 cache is used between clients using the same server 790 cache is used between clients using the same server
792 @param local_jid(jid.JID): same as for [get_candidates] 791 @param local_jid(jid.JID): same as for [get_candidates]
793 @return ((D)(ProxyInfos, None)): Found proxy infos, 792 @return ((D)(ProxyInfos, None)): Found proxy infos,
800 self._cache_proxies[server] = None 799 self._cache_proxies[server] = None
801 raise exceptions.NotFound 800 raise exceptions.NotFound
802 801
803 server = client.host if client.is_component else client.jid.host 802 server = client.host if client.is_component else client.jid.host
804 try: 803 try:
805 defer.returnValue(self._cache_proxies[server]) 804 return self._cache_proxies[server]
806 except KeyError: 805 except KeyError:
807 pass 806 pass
808 try: 807 try:
809 proxy = ( 808 proxy = (
810 yield self.host.find_service_entities(client, "proxy", "bytestreams") 809 await self.host.find_service_entities(client, "proxy", "bytestreams")
811 ).pop() 810 ).pop()
812 except (defer.CancelledError, StopIteration, KeyError): 811 except (defer.CancelledError, StopIteration, KeyError):
813 notFound(server) 812 notFound(server)
814 iq_elt = client.IQ("get") 813 iq_elt = client.IQ("get")
815 iq_elt["from"] = local_jid.full() 814 iq_elt["from"] = local_jid.full()
816 iq_elt["to"] = proxy.full() 815 iq_elt["to"] = proxy.full()
817 iq_elt.addElement((NS_BS, "query")) 816 iq_elt.addElement((NS_BS, "query"))
818 817
819 try: 818 try:
820 result_elt = yield iq_elt.send() 819 result_elt = await iq_elt.send()
821 except jabber_error.StanzaError as failure: 820 except jabber_error.StanzaError as failure:
822 log.warning( 821 log.warning(
823 "Error while requesting proxy info on {jid}: {error}".format( 822 "Error while requesting proxy info on {jid}: {error}".format(
824 jid=proxy.full(), error=failure 823 jid=proxy.full(), error=failure
825 ) 824 )
839 log.warning("Invalid proxy data received from {}".format(proxy.full())) 838 log.warning("Invalid proxy data received from {}".format(proxy.full()))
840 notFound(server) 839 notFound(server)
841 840
842 proxy_infos = self._cache_proxies[server] = ProxyInfos(host, jid_, port) 841 proxy_infos = self._cache_proxies[server] = ProxyInfos(host, jid_, port)
843 log.info("Proxy found: {}".format(proxy_infos)) 842 log.info("Proxy found: {}".format(proxy_infos))
844 defer.returnValue(proxy_infos) 843 return proxy_infos
845 844
846 @defer.inlineCallbacks 845 async def _get_network_data(self, client):
847 def _get_network_data(self, client):
848 """Retrieve information about network 846 """Retrieve information about network
849 847
850 @param client: %(doc_client)s 848 @param client: %(doc_client)s
851 @return (D(tuple[local_port, external_port, local_ips, external_ip])): network data 849 @return (D(tuple[local_port, external_port, local_ips, external_ip])): network data
852 """ 850 """
853 self.get_socks_5_server_factory() 851 self.get_socks_5_server_factory()
854 local_port = self._server_factory_port 852 local_port = self._server_factory_port
855 external_ip = yield self._ip.get_external_ip(client) 853 external_ip = await self._ip.get_external_ip(client)
856 local_ips = yield self._ip.get_local_i_ps(client) 854 local_ips = await self._ip.get_local_ips(client)
857 855
858 if external_ip is not None and self._external_port is None: 856 if external_ip is not None and self._external_port is None:
859 if external_ip != local_ips[0]: 857 if external_ip != local_ips[0]:
860 log.info("We are probably behind a NAT") 858 log.info("We are probably behind a NAT")
861 if self._np is None: 859 if self._np is None:
862 log.warning("NAT port plugin not available, we can't map port") 860 log.warning("NAT port plugin not available, we can't map port")
863 else: 861 else:
864 ext_port = yield self._np.map_port( 862 ext_port = await self._np.map_port(
865 local_port, desc="SaT socks5 stream" 863 local_port, desc="SaT socks5 stream"
866 ) 864 )
867 if ext_port is None: 865 if ext_port is None:
868 log.warning("Can't map NAT port") 866 log.warning("Can't map NAT port")
869 else: 867 else:
870 self._external_port = ext_port 868 self._external_port = ext_port
871 869
872 defer.returnValue((local_port, self._external_port, local_ips, external_ip)) 870 return (local_port, self._external_port, local_ips, external_ip)
873 871
874 @defer.inlineCallbacks 872 async def get_candidates(self, client, local_jid):
875 def get_candidates(self, client, local_jid):
876 """Return a list of our stream candidates 873 """Return a list of our stream candidates
877 874
878 @param local_jid(jid.JID): jid to use as local jid 875 @param local_jid(jid.JID): jid to use as local jid
879 This is needed for client which can be addressed with a different jid than 876 This is needed for client which can be addressed with a different jid than
880 client.jid if a local part is used (e.g. piotr@file.example.net where 877 client.jid if a local part is used (e.g. piotr@file.example.net where
881 client.jid would be file.example.net) 878 client.jid would be file.example.net)
882 @return (D(list[Candidate])): list of candidates, ordered by priority 879 @return (D(list[Candidate])): list of candidates, ordered by priority
883 """ 880 """
884 server_factory = yield self.get_socks_5_server_factory() 881 server_factory = self.get_socks_5_server_factory()
885 local_port, ext_port, local_ips, external_ip = yield self._get_network_data(client) 882 local_port, ext_port, local_ips, external_ip = await self._get_network_data(client)
886 try: 883 try:
887 proxy = yield self.get_proxy(client, local_jid) 884 proxy = await self.get_proxy(client, local_jid)
888 except exceptions.NotFound: 885 except exceptions.NotFound:
889 proxy = None 886 proxy = None
890 887
891 # its time to gather the candidates 888 # its time to gather the candidates
892 candidates = [] 889 candidates = []
946 ) 943 )
947 ) 944 )
948 945
949 # should be already sorted, but just in case the priorities get weird 946 # should be already sorted, but just in case the priorities get weird
950 candidates.sort(key=lambda c: c.priority, reverse=True) 947 candidates.sort(key=lambda c: c.priority, reverse=True)
951 defer.returnValue(candidates) 948 return candidates
952 949
953 def _add_connector(self, connector, candidate): 950 def _add_connector(self, connector, candidate):
954 """Add connector used to connect to candidate, and return client factory's connection Deferred 951 """Add connector used to connect to candidate, and return client factory's connection Deferred
955 952
956 the connector can be used to disconnect the candidate, and returning the factory's connection Deferred allow to wait for connection completion 953 the connector can be used to disconnect the candidate, and returning the factory's connection Deferred allow to wait for connection completion
1162 1159
1163 d = iq_elt.send() 1160 d = iq_elt.send()
1164 args = [client, session_data, local_jid] 1161 args = [client, session_data, local_jid]
1165 d.addCallbacks(self._iq_negotiation_cb, self._iq_negotiation_eb, args, None, args) 1162 d.addCallbacks(self._iq_negotiation_cb, self._iq_negotiation_eb, args, None, args)
1166 1163
1167 self.get_candidates(client, local_jid).addCallback(got_candidates) 1164 defer.ensureDeferred(self.get_candidates(client, local_jid)).addCallback(got_candidates)
1168 return session_data[DEFER_KEY] 1165 return session_data[DEFER_KEY]
1169 1166
1170 def _iq_negotiation_cb(self, iq_elt, client, session_data, local_jid): 1167 def _iq_negotiation_cb(self, iq_elt, client, session_data, local_jid):
1171 """Called when the result of open iq is received 1168 """Called when the result of open iq is received
1172 1169