mirror of
https://github.com/processone/ejabberd.git
synced 2024-06-30 23:02:00 +02:00
Only migrate C2S processes with remote sockets
Conflicts: src/ejabberd_c2s.erl src/ejabberd_sm.erl
This commit is contained in:
parent
ff2050b301
commit
8f3f74a6d7
|
@ -38,7 +38,8 @@
|
||||||
-export([start/2, stop_or_detach/1, start_link/3, send_text/2,
|
-export([start/2, stop_or_detach/1, start_link/3, send_text/2,
|
||||||
send_element/2, socket_type/0, get_presence/1,
|
send_element/2, socket_type/0, get_presence/1,
|
||||||
get_aux_field/2, set_aux_field/3, del_aux_field/2,
|
get_aux_field/2, set_aux_field/3, del_aux_field/2,
|
||||||
get_subscription/2, broadcast/4, get_subscribed/1]).
|
get_subscription/2, broadcast/4, is_remote_socket/1,
|
||||||
|
get_subscribed/1]).
|
||||||
|
|
||||||
%% API:
|
%% API:
|
||||||
-export([add_rosteritem/3, del_rosteritem/2]).
|
-export([add_rosteritem/3, del_rosteritem/2]).
|
||||||
|
@ -229,6 +230,19 @@ migrate(_FsmRef, _Node, _After) ->
|
||||||
migrate_shutdown(FsmRef, Node, After) ->
|
migrate_shutdown(FsmRef, Node, After) ->
|
||||||
FsmRef ! {migrate_shutdown, Node, After}.
|
FsmRef ! {migrate_shutdown, Node, After}.
|
||||||
|
|
||||||
|
is_remote_socket(Pid) when node(Pid) == node() ->
|
||||||
|
case catch process_info(Pid, dictionary) of
|
||||||
|
{dictionary, Dict} ->
|
||||||
|
SockMod = proplists:get_value(c2s_sockmod, Dict),
|
||||||
|
XMLSocket = proplists:get_value(c2s_xml_socket, Dict),
|
||||||
|
Socket = proplists:get_value(c2s_socket, Dict),
|
||||||
|
is_remote_socket(SockMod, XMLSocket, Socket);
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end;
|
||||||
|
is_remote_socket(_) ->
|
||||||
|
false.
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
@ -292,6 +306,7 @@ init([{SockMod, Socket}, Opts, FSMLimitOpts]) ->
|
||||||
fsm_limit_opts = FSMLimitOpts},
|
fsm_limit_opts = FSMLimitOpts},
|
||||||
erlang:send_after(?C2S_OPEN_TIMEOUT, self(),
|
erlang:send_after(?C2S_OPEN_TIMEOUT, self(),
|
||||||
open_timeout),
|
open_timeout),
|
||||||
|
update_internal_dict(StateData),
|
||||||
case get_jid_from_opts(Opts) of
|
case get_jid_from_opts(Opts) of
|
||||||
{ok,
|
{ok,
|
||||||
#jid{user = U, server = Server, resource = R} = JID} ->
|
#jid{user = U, server = Server, resource = R} = JID} ->
|
||||||
|
@ -305,6 +320,7 @@ init([{SockMod, Socket}, Opts, FSMLimitOpts]) ->
|
||||||
init([StateName, StateData, _FSMLimitOpts]) ->
|
init([StateName, StateData, _FSMLimitOpts]) ->
|
||||||
MRef =
|
MRef =
|
||||||
(StateData#state.sockmod):monitor(StateData#state.socket),
|
(StateData#state.sockmod):monitor(StateData#state.socket),
|
||||||
|
update_internal_dict(StateData),
|
||||||
if StateName == session_established ->
|
if StateName == session_established ->
|
||||||
Conn = (StateData#state.sockmod):get_conn_type(
|
Conn = (StateData#state.sockmod):get_conn_type(
|
||||||
StateData#state.socket),
|
StateData#state.socket),
|
||||||
|
@ -894,9 +910,10 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||||
=
|
=
|
||||||
[]})),
|
[]})),
|
||||||
fsm_next_state(wait_for_stream,
|
fsm_next_state(wait_for_stream,
|
||||||
StateData#state{socket = TLSSocket,
|
update_internal_dict(
|
||||||
streamid = new_id(),
|
StateData#state{socket = TLSSocket,
|
||||||
tls_enabled = true});
|
streamid = new_id(),
|
||||||
|
tls_enabled = true}));
|
||||||
{?NS_COMPRESS, <<"compress">>}
|
{?NS_COMPRESS, <<"compress">>}
|
||||||
when Zlib == true,
|
when Zlib == true,
|
||||||
(SockMod == gen_tcp) or (SockMod == tls) ->
|
(SockMod == gen_tcp) or (SockMod == tls) ->
|
||||||
|
@ -925,8 +942,9 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||||
=
|
=
|
||||||
[]})),
|
[]})),
|
||||||
fsm_next_state(wait_for_stream,
|
fsm_next_state(wait_for_stream,
|
||||||
StateData#state{socket = ZlibSocket,
|
update_internal_dict(
|
||||||
streamid = new_id()});
|
StateData#state{socket = ZlibSocket,
|
||||||
|
streamid = new_id()}));
|
||||||
_ ->
|
_ ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
#xmlel{name = <<"failure">>,
|
#xmlel{name = <<"failure">>,
|
||||||
|
@ -1889,12 +1907,9 @@ handle_info({migrate, Node}, StateName, StateData) ->
|
||||||
end;
|
end;
|
||||||
handle_info({migrate_shutdown, Node, After}, StateName,
|
handle_info({migrate_shutdown, Node, After}, StateName,
|
||||||
StateData) ->
|
StateData) ->
|
||||||
case StateData#state.sockmod == ejabberd_frontend_socket
|
case is_remote_socket(StateData#state.sockmod,
|
||||||
orelse
|
StateData#state.xml_socket,
|
||||||
StateData#state.xml_socket == true orelse
|
StateData#state.socket) of
|
||||||
(StateData#state.sockmod):is_remote_receiver(
|
|
||||||
StateData#state.socket)
|
|
||||||
of
|
|
||||||
true -> migrate(self(), Node, After);
|
true -> migrate(self(), Node, After);
|
||||||
false -> self() ! system_shutdown
|
false -> self() ! system_shutdown
|
||||||
end,
|
end,
|
||||||
|
@ -1920,8 +1935,9 @@ handle_info({change_socket, Socket}, StateName,
|
||||||
Socket),
|
Socket),
|
||||||
MRef = (StateData#state.sockmod):monitor(NewSocket),
|
MRef = (StateData#state.sockmod):monitor(NewSocket),
|
||||||
fsm_next_state(StateName,
|
fsm_next_state(StateName,
|
||||||
|
update_internal_dict(
|
||||||
StateData#state{socket = NewSocket,
|
StateData#state{socket = NewSocket,
|
||||||
socket_monitor = MRef});
|
socket_monitor = MRef}));
|
||||||
handle_info(Info, StateName, StateData) ->
|
handle_info(Info, StateName, StateData) ->
|
||||||
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
||||||
fsm_next_state(StateName, StateData).
|
fsm_next_state(StateName, StateData).
|
||||||
|
@ -3111,6 +3127,7 @@ rebind(StateData, JID, StreamID) ->
|
||||||
keepalive_timer =
|
keepalive_timer =
|
||||||
StateData#state.keepalive_timer,
|
StateData#state.keepalive_timer,
|
||||||
ack_timer = undefined},
|
ack_timer = undefined},
|
||||||
|
update_internal_dict(StateData2),
|
||||||
send_element(StateData2,
|
send_element(StateData2,
|
||||||
#xmlel{name = <<"rebind">>,
|
#xmlel{name = <<"rebind">>,
|
||||||
attrs = [{<<"xmlns">>, ?NS_P1_REBIND}],
|
attrs = [{<<"xmlns">>, ?NS_P1_REBIND}],
|
||||||
|
@ -3474,3 +3491,16 @@ get_jid_from_opts(Opts) ->
|
||||||
{ok, JID};
|
{ok, JID};
|
||||||
_ -> error
|
_ -> error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
update_internal_dict(#state{sockmod = SockMod,
|
||||||
|
xml_socket = XMLSocket,
|
||||||
|
socket = Socket} = StateData) ->
|
||||||
|
put(c2s_sockmod, SockMod),
|
||||||
|
put(c2s_xml_socket, XMLSocket),
|
||||||
|
put(c2s_socket, Socket),
|
||||||
|
StateData.
|
||||||
|
|
||||||
|
is_remote_socket(SockMod, XMLSocket, Socket) ->
|
||||||
|
SockMod == ejabberd_frontend_socket orelse
|
||||||
|
XMLSocket == true orelse
|
||||||
|
SockMod:is_remote_receiver(Socket).
|
||||||
|
|
|
@ -389,12 +389,13 @@ migrate(InitiatorNode, UpOrDown, After) ->
|
||||||
-spec node_up(atom()) -> ok.
|
-spec node_up(atom()) -> ok.
|
||||||
|
|
||||||
node_up(_Node) ->
|
node_up(_Node) ->
|
||||||
copy_sessions(mnesia:dirty_first(session)).
|
copy_sessions(mnesia:dirty_first(session), fun(_) -> true end).
|
||||||
|
|
||||||
-spec node_down(atom()) -> ok.
|
-spec node_down(atom()) -> ok.
|
||||||
|
|
||||||
node_down(Node) when Node == node() ->
|
node_down(Node) when Node == node() ->
|
||||||
copy_sessions(mnesia:dirty_first(session));
|
copy_sessions(mnesia:dirty_first(session),
|
||||||
|
fun ejabberd_c2s:is_remote_socket/1);
|
||||||
node_down(Node) ->
|
node_down(Node) ->
|
||||||
ets:select_delete(
|
ets:select_delete(
|
||||||
session,
|
session,
|
||||||
|
@ -402,18 +403,23 @@ node_down(Node) ->
|
||||||
[{'==', {'node', '$1'}, Node}],
|
[{'==', {'node', '$1'}, Node}],
|
||||||
[true]}]).
|
[true]}]).
|
||||||
|
|
||||||
copy_sessions('$end_of_table') -> ok;
|
copy_sessions('$end_of_table', _CheckFun) -> ok;
|
||||||
copy_sessions(Key) ->
|
copy_sessions(Key, CheckFun) ->
|
||||||
case mnesia:dirty_read(session, Key) of
|
case mnesia:dirty_read(session, Key) of
|
||||||
[#session{us = US} = Session] ->
|
[#session{us = US, sid = {_, Pid}} = Session] ->
|
||||||
case ejabberd_cluster:get_node_new(US) of
|
case ejabberd_cluster:get_node_new(US) of
|
||||||
Node when node() /= Node ->
|
Node when node() /= Node ->
|
||||||
rpc:cast(Node, mnesia, dirty_write, [Session]);
|
case CheckFun(Pid) of
|
||||||
|
true ->
|
||||||
|
rpc:cast(Node, mnesia, dirty_write, [Session]);
|
||||||
|
false ->
|
||||||
|
ok
|
||||||
|
end;
|
||||||
_ -> ok
|
_ -> ok
|
||||||
end;
|
end;
|
||||||
_ -> ok
|
_ -> ok
|
||||||
end,
|
end,
|
||||||
copy_sessions(mnesia:dirty_next(session, Key)).
|
copy_sessions(mnesia:dirty_next(session, Key), CheckFun).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
|
|
Loading…
Reference in New Issue
Block a user