diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 1d594c82b..c1f1e2fa5 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -116,10 +116,10 @@ get_subscribed(Ref) -> close(Ref) -> xmpp_stream_in:close(Ref). --spec close(pid(), boolean()) -> ok; - (state(), boolean()) -> state(). -close(Ref, SendTrailer) -> - xmpp_stream_in:close(Ref, SendTrailer). +-spec close(pid(), atom()) -> ok; + (state(), atom()) -> state(). +close(Ref, Reason) -> + xmpp_stream_in:close(Ref, Reason). -spec stop(pid()) -> ok; (state()) -> no_return(). diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 6300fca4d..ee4e72599 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -42,7 +42,7 @@ -export([handle_unexpected_info/2, handle_unexpected_cast/2, reject_unauthenticated_packet/2, process_closed/2]). %% API --export([stop/1, close/1, send/2, update_state/2, establish/1, +-export([stop/1, close/1, close/2, send/2, update_state/2, establish/1, host_up/1, host_down/1]). -include("ejabberd.hrl"). @@ -71,6 +71,9 @@ start_link(SockData, Opts) -> close(Ref) -> xmpp_stream_in:close(Ref). +close(Ref, Reason) -> + xmpp_stream_in:close(Ref, Reason). + stop(Ref) -> xmpp_stream_in:stop(Ref). diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 803dc4461..3c9e1a1c9 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -39,7 +39,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, stop/1, send/2, +-export([start/3, start_link/3, connect/1, close/1, close/2, stop/1, send/2, route/2, establish/1, update_state/2, host_up/1, host_down/1]). -include("ejabberd.hrl"). @@ -75,6 +75,11 @@ connect(Ref) -> close(Ref) -> xmpp_stream_out:close(Ref). +-spec close(pid(), atom()) -> ok; + (state(), atom()) -> state(). +close(Ref, Reason) -> + xmpp_stream_out:close(Ref, Reason). + -spec stop(pid()) -> ok; (state()) -> no_return(). stop(Ref) -> diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index d2456a1a9..8634dd122 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -27,7 +27,7 @@ -protocol({xep, 114, '1.6'}). %% ejabberd_socket callbacks --export([start/2, start_link/2, socket_type/0]). +-export([start/2, start_link/2, socket_type/0, close/1, close/2]). %% ejabberd_config callbacks -export([opt_type/1, transform_listen_option/2]). %% xmpp_stream_in callbacks @@ -63,6 +63,16 @@ socket_type() -> send(Stream, Pkt) -> xmpp_stream_in:send(Stream, Pkt). +-spec close(pid()) -> ok; + (state()) -> state(). +close(Ref) -> + xmpp_stream_in:close(Ref). + +-spec close(pid(), atom()) -> ok; + (state(), atom()) -> state(). +close(Ref, Reason) -> + xmpp_stream_in:close(Ref, Reason). + %%%=================================================================== %%% xmpp_stream_in callbacks %%%=================================================================== diff --git a/src/mod_ping.erl b/src/mod_ping.erl index 2e39e8834..a16d9b2c4 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -146,7 +146,7 @@ handle_cast({iq_pong, JID, timeout}, State) -> JID, case ejabberd_sm:get_session_pid(User, Server, Resource) of - Pid when is_pid(Pid) -> ejabberd_c2s:close(Pid, _SendTrailer = false); + Pid when is_pid(Pid) -> ejabberd_c2s:close(Pid, ping_timeout); _ -> ok end; _ -> ok diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index 742b69d9d..97875fa81 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -233,9 +233,7 @@ c2s_handle_info(#{mgmt_ack_timer := TRef, jid := JID, mod := Mod} = State, {timeout, TRef, ack_timeout}) -> ?DEBUG("Timed out waiting for stream management acknowledgement of ~s", [jid:encode(JID)]), - State1 = State#{stop_reason => {socket, timeout}}, - State2 = Mod:close(State1, _SendTrailer = false), - {stop, transition_to_pending(State2)}; + {stop, Mod:close(State, ack_timeout)}; c2s_handle_info(#{mgmt_state := pending, jid := JID, mod := Mod} = State, {timeout, _, pending_timeout}) -> ?DEBUG("Timed out waiting for resumption of stream for ~s", diff --git a/src/xmpp_stream_in.erl b/src/xmpp_stream_in.erl index 45e14224f..073ae3d1f 100644 --- a/src/xmpp_stream_in.erl +++ b/src/xmpp_stream_in.erl @@ -46,7 +46,7 @@ -type state() :: map(). -type stop_reason() :: {stream, reset | {in | out, stream_error()}} | {tls, inet:posix() | atom() | binary()} | - {socket, inet:posix() | closed | timeout} | + {socket, inet:posix() | atom()} | internal_failure. -export_type([state/0, stop_reason/0]). -callback init(list()) -> {ok, state()} | {error, term()} | ignore. @@ -152,15 +152,18 @@ send(_, _) -> -spec close(pid()) -> ok; (state()) -> state(). close(Ref) -> - close(Ref, true). + close(Ref, closed). --spec close(pid(), boolean()) -> ok; - (state(), boolean()) -> state(). -close(Pid, SendTrailer) when is_pid(Pid) -> - cast(Pid, {close, SendTrailer}); -close(#{owner := Owner} = State, SendTrailer) when Owner == self() -> - if SendTrailer -> send_trailer(State); - true -> close_socket(State) +-spec close(pid(), atom()) -> ok; + (state(), atom()) -> state(). +close(Pid, Reason) when is_pid(Pid) -> + cast(Pid, {close, Reason}); +close(#{owner := Owner} = State, Reason) when Owner == self() -> + case is_disconnected(State) of + true -> State; + false -> + _IgnoreState = close_socket(State), + process_stream_end({socket, Reason}, State) end; close(_, _) -> erlang:error(badarg). @@ -271,16 +274,8 @@ handle_cast({send, Pkt}, State) -> noreply(send_pkt(State, Pkt)); handle_cast(stop, State) -> {stop, normal, State}; -handle_cast({close, SendTrailer}, #{mod := Mod} = State) -> - noreply( - case is_disconnected(State) of - true -> State; - false -> - State1 = close(State, SendTrailer), - try Mod:handle_stream_end({socket, closed}, State1) - catch _:undef -> stop(State1) - end - end); +handle_cast({close, Reason}, State) -> + noreply(close(State, Reason)); handle_cast(Cast, #{mod := Mod} = State) -> noreply(try Mod:handle_cast(Cast, State) catch _:undef -> State diff --git a/src/xmpp_stream_out.erl b/src/xmpp_stream_out.erl index fd86bd794..c8a2fba1e 100644 --- a/src/xmpp_stream_out.erl +++ b/src/xmpp_stream_out.erl @@ -57,7 +57,7 @@ {tls, inet:posix() | atom() | binary()} | {pkix, binary()} | {auth, atom() | binary() | string()} | - {socket, inet:posix() | closed | timeout} | + {socket, inet:posix() | atom()} | internal_failure. -export_type([state/0, stop_reason/0]). -callback init(list()) -> {ok, state()} | {error, term()} | ignore. @@ -162,15 +162,18 @@ send(_, _) -> -spec close(pid()) -> ok; (state()) -> state(). close(Ref) -> - close(Ref, true). + close(Ref, closed). --spec close(pid(), boolean()) -> ok; - (state(), boolean()) -> state(). -close(Pid, SendTrailer) when is_pid(Pid) -> - cast(Pid, {close, SendTrailer}); -close(#{owner := Owner} = State, SendTrailer) when Owner == self() -> - if SendTrailer -> send_trailer(State); - true -> close_socket(State) +-spec close(pid(), atom()) -> ok; + (state(), atom()) -> state(). +close(Pid, Reason) when is_pid(Pid) -> + cast(Pid, {close, Reason}); +close(#{owner := Owner} = State, Reason) when Owner == self() -> + case is_disconnected(State) of + true -> State; + false -> + _IgnoreState = close_socket(State), + process_stream_end({socket, Reason}, State) end; close(_, _) -> erlang:error(badarg). @@ -302,16 +305,8 @@ handle_cast({send, Pkt}, State) -> noreply(send_pkt(State, Pkt)); handle_cast(stop, State) -> {stop, normal, State}; -handle_cast({close, SendTrailer}, #{mod := Mod} = State) -> - noreply( - case is_disconnected(State) of - true -> State; - false -> - State1 = close(State, SendTrailer), - try Mod:handle_stream_end({socket, closed}, State1) - catch _:undef -> stop(State1) - end - end); +handle_cast({close, Reason}, State) -> + noreply(close(State, Reason)); handle_cast(Cast, #{mod := Mod} = State) -> noreply(try Mod:handle_cast(Cast, State) catch _:undef -> State