aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-04-15 08:30:41 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-04-15 08:30:41 +0300
commit5774edfe7950f1b12cacd41dd05c8533f36e5f3d (patch)
tree8004ccc071d67e7743721b67f348c59fdee517f7 /src
parentMake sure stream trailer is sent in the very end (diff)
Improve ejabberd_c2s:close()
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_c2s.erl8
-rw-r--r--src/ejabberd_s2s_in.erl5
-rw-r--r--src/ejabberd_s2s_out.erl7
-rw-r--r--src/ejabberd_service.erl12
-rw-r--r--src/mod_ping.erl2
-rw-r--r--src/mod_stream_mgmt.erl4
-rw-r--r--src/xmpp_stream_in.erl35
-rw-r--r--src/xmpp_stream_out.erl35
8 files changed, 57 insertions, 51 deletions
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).
-
--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)
+ close(Ref, closed).
+
+-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).
-
--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)
+ close(Ref, closed).
+
+-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