aboutsummaryrefslogtreecommitdiff
path: root/src/mod_stream_mgmt.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_stream_mgmt.erl')
-rw-r--r--src/mod_stream_mgmt.erl38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl
index 1a4308c58..34ce4e53d 100644
--- a/src/mod_stream_mgmt.erl
+++ b/src/mod_stream_mgmt.erl
@@ -591,22 +591,25 @@ route_unacked_stanzas(#{mgmt_state := MgmtState,
end,
?DEBUG("Re-routing ~B unacknowledged stanza(s) to ~s",
[p1_queue:len(Queue), jid:encode(JID)]),
- p1_queue:foreach(
- fun({_, _Time, #presence{from = From}}) ->
- ?DEBUG("Dropping presence stanza from ~s", [jid:encode(From)]);
- ({_, _Time, #iq{} = El}) ->
+ p1_queue:foldl(
+ fun({_, _Time, #presence{from = From}}, Acc) ->
+ ?DEBUG("Dropping presence stanza from ~s", [jid:encode(From)]),
+ Acc;
+ ({_, _Time, #iq{} = El}, Acc) ->
Txt = <<"User session terminated">>,
ejabberd_router:route_error(
- El, xmpp:err_service_unavailable(Txt, Lang));
- ({_, _Time, #message{from = From, meta = #{carbon_copy := true}}}) ->
+ El, xmpp:err_service_unavailable(Txt, Lang)),
+ Acc;
+ ({_, _Time, #message{from = From, meta = #{carbon_copy := true}}}, Acc) ->
%% XEP-0280 says: "When a receiving server attempts to deliver a
%% forked message, and that message bounces with an error for
%% any reason, the receiving server MUST NOT forward that error
%% back to the original sender." Resending such a stanza could
%% easily lead to unexpected results as well.
?DEBUG("Dropping forwarded message stanza from ~s",
- [jid:encode(From)]);
- ({_, Time, #message{} = Msg}) ->
+ [jid:encode(From)]),
+ Acc;
+ ({_, Time, #message{} = Msg}, Acc) ->
case ejabberd_hooks:run_fold(message_is_archived,
LServer, false,
[State, Msg]) of
@@ -615,17 +618,26 @@ route_unacked_stanzas(#{mgmt_state := MgmtState,
[jid:encode(xmpp:get_from(Msg))]);
false when ResendOnTimeout ->
NewEl = add_resent_delay_info(State, Msg, Time),
- ejabberd_router:route(NewEl);
+ NewEl2 = case Acc of
+ first_resend ->
+ xmpp:put_meta(NewEl, first_from_queue, true);
+ _ ->
+ NewEl
+ end,
+ ejabberd_router:route(NewEl2),
+ false;
false ->
Txt = <<"User session terminated">>,
ejabberd_router:route_error(
- Msg, xmpp:err_service_unavailable(Txt, Lang))
+ Msg, xmpp:err_service_unavailable(Txt, Lang)),
+ Acc
end;
- ({_, _Time, El}) ->
+ ({_, _Time, El}, Acc) ->
%% Raw element of type 'error' resulting from a validation error
%% We cannot pass it to the router, it will generate an error
- ?DEBUG("Do not route raw element from ack queue: ~p", [El])
- end, Queue);
+ ?DEBUG("Do not route raw element from ack queue: ~p", [El]),
+ Acc
+ end, first_resend, Queue);
route_unacked_stanzas(_State) ->
ok.