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.
This commit is contained in:
Goffi 2023-12-09 14:30:54 +01:00
commit bbac8b6822
3 changed files with 60 additions and 63 deletions

View file

@ -200,8 +200,7 @@ class IPPlugin(object):
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 @@ class IPPlugin(object):
"""
# 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 @@ class IPPlugin(object):
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 @@ class IPPlugin(object):
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)

View file

@ -784,8 +784,7 @@ class XEP_0065(object):
)
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
"""
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
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 @@ class XEP_0065(object):
# 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 @@ class XEP_0065(object):
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):

View file

@ -134,8 +134,7 @@ class XEP_0260(object):
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 @@ class XEP_0260(object):
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 @@ class XEP_0260(object):
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 @@ class XEP_0260(object):
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 @@ class XEP_0260(object):
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: