Support XEP-0198 pings
If stream management is enabled, let mod_ping trigger XEP-0198 <r/>equests rather than sending XEP-0199 pings. This avoids the overhead of the ping IQ stanzas, which, if stream management is enabled, are accompanied by XEP-0198 elements anyway. Thanks to MoyaApp (<https://moya.app>) for sponsoring this work.
This commit is contained in:
parent
74cb2e054f
commit
6c691a73bd
|
@ -49,14 +49,13 @@
|
|||
-export([init/1, terminate/2, handle_call/3,
|
||||
handle_cast/2, handle_info/2, code_change/3]).
|
||||
|
||||
-export([iq_ping/1, user_online/3, user_offline/3, mod_doc/0,
|
||||
user_send/1, mod_opt_type/1, mod_options/1, depends/2]).
|
||||
-export([iq_ping/1, user_online/3, user_offline/3, mod_doc/0, user_send/1,
|
||||
c2s_handle_cast/2, mod_opt_type/1, mod_options/1, depends/2]).
|
||||
|
||||
-record(state,
|
||||
{host :: binary(),
|
||||
send_pings :: boolean(),
|
||||
ping_interval :: pos_integer(),
|
||||
ping_ack_timeout :: undefined | non_neg_integer(),
|
||||
timeout_action :: none | kill,
|
||||
timers :: timers()}).
|
||||
|
||||
|
@ -167,13 +166,8 @@ handle_info({timeout, _TRef, {ping, JID}}, State) ->
|
|||
JID#jid.lresource) of
|
||||
none ->
|
||||
del_timer(JID, State#state.timers);
|
||||
_ ->
|
||||
Host = State#state.host,
|
||||
From = jid:make(Host),
|
||||
IQ = #iq{from = From, to = JID, type = get, sub_els = [#ping{}]},
|
||||
ejabberd_router:route_iq(IQ, JID,
|
||||
gen_mod:get_module_proc(Host, ?MODULE),
|
||||
State#state.ping_ack_timeout),
|
||||
Pid ->
|
||||
ejabberd_c2s:cast(Pid, send_ping),
|
||||
add_timer(JID, State#state.ping_interval,
|
||||
State#state.timers)
|
||||
end,
|
||||
|
@ -214,19 +208,29 @@ user_send({Packet, #{jid := JID} = C2SState}) ->
|
|||
start_ping(JID#jid.lserver, JID),
|
||||
{Packet, C2SState}.
|
||||
|
||||
-spec c2s_handle_cast(ejabberd_c2s:state(), send_ping | term())
|
||||
-> ejabberd_c2s:state() | {stop, ejabberd_c2s:state()}.
|
||||
c2s_handle_cast(#{lserver := Host, jid := JID} = C2SState, send_ping) ->
|
||||
From = jid:make(Host),
|
||||
IQ = #iq{from = From, to = JID, type = get, sub_els = [#ping{}]},
|
||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||
PingAckTimeout = mod_ping_opt:ping_ack_timeout(Host),
|
||||
ejabberd_router:route_iq(IQ, JID, Proc, PingAckTimeout),
|
||||
{stop, C2SState};
|
||||
c2s_handle_cast(C2SState, _Msg) ->
|
||||
C2SState.
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
%%====================================================================
|
||||
init_state(Host, Opts) ->
|
||||
SendPings = mod_ping_opt:send_pings(Opts),
|
||||
PingInterval = mod_ping_opt:ping_interval(Opts),
|
||||
PingAckTimeout = mod_ping_opt:ping_ack_timeout(Opts),
|
||||
TimeoutAction = mod_ping_opt:timeout_action(Opts),
|
||||
#state{host = Host,
|
||||
send_pings = SendPings,
|
||||
ping_interval = PingInterval,
|
||||
timeout_action = TimeoutAction,
|
||||
ping_ack_timeout = PingAckTimeout,
|
||||
timers = #{}}.
|
||||
|
||||
register_hooks(Host) ->
|
||||
|
@ -235,7 +239,9 @@ register_hooks(Host) ->
|
|||
ejabberd_hooks:add(sm_remove_connection_hook, Host,
|
||||
?MODULE, user_offline, 100),
|
||||
ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
|
||||
user_send, 100).
|
||||
user_send, 100),
|
||||
ejabberd_hooks:add(c2s_handle_cast, Host, ?MODULE,
|
||||
c2s_handle_cast, 99).
|
||||
|
||||
unregister_hooks(Host) ->
|
||||
ejabberd_hooks:delete(sm_remove_connection_hook, Host,
|
||||
|
@ -243,7 +249,9 @@ unregister_hooks(Host) ->
|
|||
ejabberd_hooks:delete(sm_register_connection_hook, Host,
|
||||
?MODULE, user_online, 100),
|
||||
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
|
||||
user_send, 100).
|
||||
user_send, 100),
|
||||
ejabberd_hooks:delete(c2s_handle_cast, Host, ?MODULE,
|
||||
c2s_handle_cast, 99).
|
||||
|
||||
register_iq_handlers(Host) ->
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PING,
|
||||
|
@ -315,7 +323,10 @@ mod_doc() ->
|
|||
#{value => "timeout()",
|
||||
desc =>
|
||||
?T("How long to wait before deeming that a client "
|
||||
"has not answered a given server ping request. "
|
||||
"has not answered a given server ping request. NOTE: when "
|
||||
"_`mod_stream_mgmt`_ is loaded and stream management is "
|
||||
"enabled by a client, this value is ignored, and the "
|
||||
"`ack_timeout` applies instead. "
|
||||
"The default value is 'undefined'.")}},
|
||||
{send_pings,
|
||||
#{value => "true | false",
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
-export([c2s_stream_started/2, c2s_stream_features/2,
|
||||
c2s_authenticated_packet/2, c2s_unauthenticated_packet/2,
|
||||
c2s_unbinded_packet/2, c2s_closed/2, c2s_terminated/2,
|
||||
c2s_handle_send/3, c2s_handle_info/2, c2s_handle_call/3,
|
||||
c2s_handle_recv/3, c2s_inline_features/2,
|
||||
c2s_handle_send/3, c2s_handle_info/2, c2s_handle_cast/2,
|
||||
c2s_handle_call/3, c2s_handle_recv/3, c2s_inline_features/2,
|
||||
c2s_handle_sasl2_inline/1, c2s_handle_sasl2_inline_post/3,
|
||||
c2s_handle_bind2_inline/1]).
|
||||
%% adjust pending session timeout / access queue
|
||||
|
@ -77,6 +77,7 @@ start(_Host, Opts) ->
|
|||
{hook, c2s_handle_send, c2s_handle_send, 50},
|
||||
{hook, c2s_handle_recv, c2s_handle_recv, 50},
|
||||
{hook, c2s_handle_info, c2s_handle_info, 50},
|
||||
{hook, c2s_handle_cast, c2s_handle_cast, 50},
|
||||
{hook, c2s_handle_call, c2s_handle_call, 50},
|
||||
{hook, c2s_handle_sasl2_inline, c2s_handle_sasl2_inline, 50},
|
||||
{hook, c2s_handle_sasl2_inline_post, c2s_handle_sasl2_inline_post, 50},
|
||||
|
@ -258,6 +259,13 @@ c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod,
|
|||
c2s_handle_send(State, _Pkt, _Result) ->
|
||||
State.
|
||||
|
||||
c2s_handle_cast(#{mgmt_state := active} = State, send_ping) ->
|
||||
{stop, send_rack(State)};
|
||||
c2s_handle_cast(#{mgmt_state := pending} = State, send_ping) ->
|
||||
{stop, State};
|
||||
c2s_handle_cast(State, _Msg) ->
|
||||
State.
|
||||
|
||||
c2s_handle_call(#{mgmt_id := MgmtID, mgmt_queue := Queue, mod := Mod} = State,
|
||||
{resume_session, MgmtID}, From) ->
|
||||
State1 = State#{mgmt_queue => p1_queue:file_to_ram(Queue)},
|
||||
|
|
Loading…
Reference in New Issue