Skip to content

Commit 2393861

Browse files
committed
mod_pubsub_serverinfo: add option pubsub_host
Also when choosing a pubsub host were now acknowledgin mod_pubsub's `hosts` option, especially since `host` is deprecated.
1 parent b1b8003 commit 2393861

File tree

2 files changed

+73
-19
lines changed

2 files changed

+73
-19
lines changed

mod_pubsub_serverinfo/README.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@ mod_pubsub_serverinfo - Exposes server information over Pub/Sub
22
==============================================================
33

44
* Author: Guus der Kinderen <[email protected]>
5+
* Author: Stefan Strigler <[email protected]>
56

67
Description
78
-----------
89

910
Announces support for the ProtoXEP PubSub Server Information, by adding
1011
its Service Discovery feature.
1112

12-
Future versions of this plugin are expected to publish data describing
13-
the local XMPP domain(s).
13+
Active S2S connections are published to a local pubsub node as advertised by
14+
Service Discovery. Only those connections that support this feature as well are
15+
exposed with their domain names, otherwise they are shown as anonymous nodes. At
16+
startup a list of well known public servers is being fetched. Those are not
17+
shown as anonymous even if they don't support this feature.
18+
19+
Currently the name of the node is hardcoded as "serverinfo". The local service
20+
to be used can be configured as `pubsub_host`. Otherwise a good guess is taken.
21+
22+
This module has a hard dependency on `mod_pubsub` for this reason. Also
23+
`mod_disco` must be configured for this feature to work.
1424

1525
> [!NOTE]
1626
> The module only shows S2S connections established while the module is running:
@@ -20,9 +30,12 @@ the local XMPP domain(s).
2030
Configuration
2131
-------------
2232

23-
This module does not have any configurable settings for now.
33+
Configurable options for `mod_pubsub_serverinfo`:
34+
35+
- `pubsub_host` (default: undefined)
2436

25-
> [!NOTE]
26-
> As of now your pubsub component must be reachable at `pubsub.<yourhost>` (the
27-
> default), otherwise this module would advertise the wrong address.
28-
> See: https://github.com/processone/ejabberd-contrib/issues/343
37+
This option specifies which pubsub host to use to advertise S2S connections.
38+
This must be a vhost local to this service and handled by `mod_pubsub`. This
39+
is only needed if your configuration has more than one vhost in mod_pubsub's
40+
`hosts` option. If there's more than one and this option is not given, we just
41+
pick the first one.

mod_pubsub_serverinfo/src/mod_pubsub_serverinfo.erl

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
-include_lib("xmpp/include/xmpp.hrl").
3434

3535
%% gen_mod callbacks.
36-
-export([start/2, stop/1, depends/2, mod_options/1, get_local_features/5, mod_doc/0]).
36+
-export([start/2, stop/1, depends/2, mod_options/1, mod_opt_type/1, get_local_features/5, mod_doc/0]).
3737
-export([init/1, handle_cast/2, handle_call/3, handle_info/2, terminate/2]).
3838
-export([in_auth_result/3, out_auth_result/2, get_info/5]).
3939

@@ -43,12 +43,17 @@
4343
-record(state, {host, pubsub_host, node, monitors = #{}, timer = undefined, public_hosts = []}).
4444

4545
start(Host, Opts) ->
46-
xmpp:register_codec(pubsub_serverinfo_codec),
47-
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
48-
ejabberd_hooks:add(disco_info, Host, ?MODULE, get_info, 50),
49-
ejabberd_hooks:add(s2s_out_auth_result, Host, ?MODULE, out_auth_result, 50),
50-
ejabberd_hooks:add(s2s_in_auth_result, Host, ?MODULE, in_auth_result, 50),
51-
gen_mod:start_child(?MODULE, Host, Opts).
46+
case pubsub_host(Host, Opts) of
47+
{error, _Reason} = Error ->
48+
Error;
49+
PubsubHost ->
50+
xmpp:register_codec(pubsub_serverinfo_codec),
51+
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
52+
ejabberd_hooks:add(disco_info, Host, ?MODULE, get_info, 50),
53+
ejabberd_hooks:add(s2s_out_auth_result, Host, ?MODULE, out_auth_result, 50),
54+
ejabberd_hooks:add(s2s_in_auth_result, Host, ?MODULE, in_auth_result, 50),
55+
gen_mod:start_child(?MODULE, Host, PubsubHost)
56+
end.
5257

5358
stop(Host) ->
5459
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
@@ -57,11 +62,10 @@ stop(Host) ->
5762
ejabberd_hooks:delete(s2s_in_auth_result, Host, ?MODULE, in_auth_result, 50),
5863
gen_mod:stop_child(?MODULE, Host).
5964

60-
init([Host, _Opts]) ->
65+
init([Host, PubsubHost]) ->
6166
TRef = timer:send_interval(timer:minutes(5), self(), update_pubsub),
6267
Monitors = init_monitors(Host),
6368
PublicHosts = fetch_public_hosts(),
64-
PubsubHost = gen_mod:get_module_opt(Host, mod_pubsub, host),
6569
State = #state{host = Host,
6670
pubsub_host = PubsubHost,
6771
node = <<"serverinfo">>,
@@ -171,7 +175,10 @@ depends(_Host, _Opts) ->
171175
[{mod_pubsub, hard}].
172176

173177
mod_options(_Host) ->
174-
[].
178+
[{pubsub_host, undefined}].
179+
180+
mod_opt_type(pubsub_host) ->
181+
econf:either(undefined, econf:host()).
175182

176183
mod_doc() -> #{}.
177184

@@ -251,15 +258,15 @@ get_local_features(Acc, _From, _To, _Node, _Lang) ->
251258
get_info(Acc, Host, Mod, Node, Lang) when (Mod == undefined orelse Mod == mod_disco), Node == <<"">> ->
252259
case mod_disco:get_info(Acc, Host, Mod, Node, Lang) of
253260
[#xdata{fields = Fields} = XD | Rest] ->
254-
PubsubHost = gen_mod:get_module_opt(Host, mod_pubsub, host),
261+
PubsubHost = pubsub_host(Host),
255262
NodeField = #xdata_field{var = <<"serverinfo-pubsub-node">>,
256263
values = [<<"xmpp:", PubsubHost/binary, "?;node=serverinfo">>]},
257264
{stop, [XD#xdata{fields = Fields ++ [NodeField]} | Rest]};
258265
_ ->
259266
Acc
260267
end;
261268
get_info(Acc, Host, Mod, Node, _Lang) when Node == <<"">>, is_atom(Mod) ->
262-
PubsubHost = gen_mod:get_module_opt(Host, mod_pubsub, host),
269+
PubsubHost = pubsub_host(Host),
263270
[#xdata{type = result,
264271
fields = [
265272
#xdata_field{type = hidden,
@@ -269,3 +276,37 @@ get_info(Acc, Host, Mod, Node, _Lang) when Node == <<"">>, is_atom(Mod) ->
269276
values = [<<"xmpp:", PubsubHost/binary, "?;node=serverinfo">>]}]} | Acc];
270277
get_info(Acc, _Host, _Mod, _Node, _Lang) ->
271278
Acc.
279+
280+
pubsub_host(Host) ->
281+
case pubsub_host(Host, gen_mod:get_module_opts(Host, mod_pubsub)) of
282+
{error, _Reason} = Error ->
283+
throw(Error);
284+
PubsubHost ->
285+
PubsubHost
286+
end.
287+
288+
pubsub_host(Host, Opts) ->
289+
case gen_mod:get_opt(pubsub_host, Opts) of
290+
undefined ->
291+
PubsubHost = hd(get_mod_pubsub_hosts(Host)),
292+
?INFO_MSG("No pubsub_host in configuration for ~p, choosing ~s", [?MODULE, PubsubHost]),
293+
PubsubHost;
294+
PubsubHost ->
295+
case check_pubsub_host_exists(Host, PubsubHost) of
296+
true ->
297+
PubsubHost;
298+
false ->
299+
{error, {pubsub_host_does_not_exist, PubsubHost}}
300+
end
301+
end.
302+
303+
check_pubsub_host_exists(Host, PubsubHost) ->
304+
lists:member(PubsubHost, get_mod_pubsub_hosts(Host)).
305+
306+
get_mod_pubsub_hosts(Host) ->
307+
case gen_mod:get_module_opt(Host, mod_pubsub, hosts) of
308+
[] ->
309+
[gen_mod:get_module_opt(Host, mod_pubsub, host)];
310+
PubsubHosts ->
311+
PubsubHosts
312+
end.

0 commit comments

Comments
 (0)