mod_pubsub_serverinfo: Consider sibling vhosts 'connected'
Prosody does not have s2s connections between vhosts. Multiple domains will therefor not show up as each-other 'remote domains'.
With this commit, the module considers vhosts permanently s2s-connected.
Additional debug logging has been added.
--- a/mod_pubsub_serverinfo/README.markdown Thu Jan 04 12:33:34 2024 +0100
+++ b/mod_pubsub_serverinfo/README.markdown Thu Jan 04 15:14:19 2024 +0100
@@ -49,5 +49,6 @@
Known Issues / TODOs
====================
-This module will not report connections between domains that are served by the same instance of Prosody (since they're not s2s connections, but are
-routed internally).
+The reported data does not contain the optional 'connection' child elements. These can be used to describe the direction of a connection.
+
+More generic server information (eg: user counts, software version) should be included in the data that is published.
--- a/mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua Thu Jan 04 12:33:34 2024 +0100
+++ b/mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua Thu Jan 04 15:14:19 2024 +0100
@@ -122,6 +122,7 @@
local domains_by_host = {}
for session, _ in pairs(prosody.incoming_s2s) do
if session ~= nil and session.from_host ~= nil and local_domain == session.to_host then
+ module:log("debug", "Local host '%s' has remote '%s' (inbound)", session.to_host, session.from_host);
local sessions = domains_by_host[session.to_host]
if sessions == nil then sessions = {} end; -- instantiate a new entry if none existed
sessions[session.from_host] = true
@@ -129,7 +130,10 @@
end
end
- -- At an earlier stage, the code iterated voer all prosody.hosts - but that turned out to be to noisy.
+ -- At an earlier stage, the code iterated over all prosody.hosts, trying to generate one pubsub item for all local hosts. That turned out to be
+ -- to noisy. Instead, this code now creates an item that includes the local vhost only. It is assumed that this module will also be loaded for
+ -- other vhosts. Their data should then be published to distinct pub/sub services and nodes.
+
-- for host, data in pairs(prosody.hosts) do
local host = local_domain
local data = prosody.hosts[host]
@@ -139,11 +143,21 @@
if data.s2sout ~= nil then
for _, session in pairs(data.s2sout) do
if session.to_host ~= nil then
+ module:log("debug", "Local host '%s' has remote '%s' (outbound)", host, session.to_host);
sessions[session.to_host] = true
domains_by_host[host] = sessions
end
end
end
+
+ -- When the instance of Prosody hosts more than one host, the other hosts can be thought of as having a 'permanent' s2s connection.
+ for host_name, host_info in pairs(prosody.hosts) do
+ if host ~= host_name and host_info.type ~= "component" then
+ module:log("debug", "Local host '%s' has remote '%s' (vhost)", host, host_name);
+ sessions[host_name] = true;
+ domains_by_host[host] = sessions
+ end
+ end
end
-- Build the publication stanza.
@@ -196,12 +210,14 @@
-- try to read answer from cache.
local cached_value = opt_in_cache[remoteDomain]
if cached_value ~= nil and os.difftime(cached_value.expires, os.time()) > 0 then
+ module:log("debug", "Opt-in status (from cache) for '%s': %s", remoteDomain, cached_value.opt_in)
return cached_value.opt_in;
end
-- TODO worry about not having multiple requests in flight to the same domain.cached_value
-- Cache could not provide an answer. Perform service discovery.
+ module:log("debug", "No cached opt-in status for '%s': performing disco/info to determine opt-in.", remoteDomain)
local discoRequest = st.iq({ type = "get", to = remoteDomain, from = actor, id = new_id() })
:tag("query", { xmlns = "http://jabber.org/protocol/disco#info" })
@@ -211,7 +227,9 @@
local query = response.stanza:get_child("query", "http://jabber.org/protocol/disco#info")
if query ~= nil then
for feature in query:childtags("feature", "http://jabber.org/protocol/disco#info") do
+ module:log("debug", "Disco/info feature for '%s': %s", remoteDomain, feature)
if feature.attr.var == 'urn:xmpp:serverinfo:0' then
+ module:log("debug", "Disco/info response included opt-in for '%s'", remoteDomain)
opt_in_cache[remoteDomain] = {
opt_in = true;
expires = os.time() + cache_ttl;
@@ -221,12 +239,14 @@
end
end
end
+ module:log("debug", "Disco/info response did not include opt-in for '%s'", remoteDomain)
opt_in_cache[remoteDomain] = {
opt_in = false;
expires = os.time() + cache_ttl;
}
end,
function(response)
+ module:log("debug", "An error occurred while performing a disco/info request to determine opt-in for '%s'", remoteDomain, response)
opt_in_cache[remoteDomain] = {
opt_in = false;
expires = os.time() + cache_ttl;