From 1bd560f3f25d0a644bac3d06904ca97e20a6f7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Wed, 1 Apr 2020 14:35:49 +0200 Subject: Fix potential message loss in terminating c2s sessions Calling sync version of xmpp_stream_in/out:stop could lead to messages never being processed by c2s process if they were queued in p1_server. This could be reproduced by when having messages in offline storage, starting sessions, enabling stream_mgmt, sending initial presence, and then immediately , messages that mod_offline would send process would not be bounced back by stream_mgmt. --- src/ejabberd_s2s_out.erl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/ejabberd_s2s_out.erl') diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 7bbaf870c..0b44eb132 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -36,7 +36,7 @@ -export([process_auth_result/2, process_closed/2, handle_unexpected_info/2, handle_unexpected_cast/2, process_downgraded/2]). %% API --export([start/3, start_link/3, connect/1, close/1, close/2, stop/1, send/2, +-export([start/3, start_link/3, connect/1, close/1, close/2, stop_async/1, send/2, route/2, establish/1, update_state/2, host_up/1, host_down/1]). -include("xmpp.hrl"). @@ -79,10 +79,9 @@ close(Ref) -> close(Ref, Reason) -> xmpp_stream_out:close(Ref, Reason). --spec stop(pid()) -> ok; - (state()) -> no_return(). -stop(Ref) -> - xmpp_stream_out:stop(Ref). +-spec stop_async(pid()) -> ok. +stop_async(Pid) -> + xmpp_stream_out:stop_async(Pid). -spec send(pid(), xmpp_element()) -> ok; (state(), xmpp_element()) -> state(). @@ -150,7 +149,8 @@ process_closed(#{server := LServer, remote_server := RServer, Reason) -> ?INFO_MSG("Closing outbound s2s connection ~ts -> ~ts: ~ts", [LServer, RServer, format_error(Reason)]), - stop(State); + stop_async(self()), + State; process_closed(#{server := LServer, remote_server := RServer} = State, Reason) -> Delay = get_delay(), @@ -248,7 +248,9 @@ handle_send(El, Pkt, #{server_host := ServerHost} = State) -> handle_timeout(#{on_route := Action, lang := Lang} = State) -> case Action of - bounce -> stop(State); + bounce -> + stop_async(self()), + State; _ -> Txt = ?T("Idle connection"), send(State, xmpp:serr_connection_timeout(Txt, Lang)) -- cgit v1.2.3