diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2016-07-23 01:08:05 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2016-07-23 01:08:05 +0200 |
commit | 814b80c644fa425990dc63875e1da841d698b0fa (patch) | |
tree | 277041ddec51894c69741f6df070b6a50e3ca4c4 /src | |
parent | Support oauth password grant type (diff) |
Preserve PID for offline sessions
Don't set the PID to 'undefined' when a session goes offline, as this
looses the information which node created the session table entry.
Fixes #1196.
Diffstat (limited to 'src')
-rw-r--r-- | src/ejabberd_sm.erl | 42 | ||||
-rw-r--r-- | src/mod_admin_extra.erl | 19 | ||||
-rw-r--r-- | src/mod_configure.erl | 36 |
3 files changed, 57 insertions, 40 deletions
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 8d94bc6aa..16e0f9114 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -270,25 +270,28 @@ get_session_pid(User, Server, Resource) -> -spec set_offline_info(sid(), binary(), binary(), binary(), info()) -> ok. -set_offline_info({Time, _Pid}, User, Server, Resource, Info) -> - SID = {Time, undefined}, +set_offline_info(SID, User, Server, Resource, Info) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), LResource = jid:resourceprep(Resource), - set_session(SID, LUser, LServer, LResource, undefined, Info). + set_session(SID, LUser, LServer, LResource, undefined, [offline | Info]). -spec get_offline_info(erlang:timestamp(), binary(), binary(), binary()) -> none | info(). get_offline_info(Time, User, Server, Resource) -> - SID = {Time, undefined}, LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), LResource = jid:resourceprep(Resource), Mod = get_sm_backend(LServer), case Mod:get_sessions(LUser, LServer, LResource) of - [#session{sid = SID, info = Info}] -> - Info; + [#session{sid = {Time, _}, info = Info}] -> + case proplists:get_bool(offline, Info) of + true -> + Info; + false -> + none + end; _ -> none end. @@ -425,11 +428,12 @@ set_session(SID, User, Server, Resource, Priority, Info) -> -spec online([#session{}]) -> [#session{}]. online(Sessions) -> - lists:filter(fun(#session{sid = {_, undefined}}) -> - false; - (_) -> - true - end, Sessions). + lists:filter(fun is_online/1, Sessions). + +-spec is_online(#session{}) -> boolean(). + +is_online(#session{info = Info}) -> + not proplists:get_bool(offline, Info). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -678,15 +682,17 @@ check_for_sessions_to_replace(User, Server, Resource) -> check_max_sessions(LUser, LServer). check_existing_resources(LUser, LServer, LResource) -> - SIDs = get_resource_sessions(LUser, LServer, LResource), - if SIDs == [] -> ok; + Mod = get_sm_backend(LServer), + Ss = Mod:get_sessions(LUser, LServer, LResource), + {OnlineSs, OfflineSs} = lists:partition(fun is_online/1, Ss), + lists:foreach(fun(#session{sid = S}) -> + Mod:delete_session(LUser, LServer, LResource, S) + end, OfflineSs), + if OnlineSs == [] -> ok; true -> + SIDs = [SID || #session{sid = SID} <- OnlineSs], MaxSID = lists:max(SIDs), - lists:foreach(fun ({_, undefined} = S) -> - Mod = get_sm_backend(LServer), - Mod:delete_session(LUser, LServer, LResource, - S); - ({_, Pid} = S) when S /= MaxSID -> + lists:foreach(fun ({_, Pid} = S) when S /= MaxSID -> Pid ! replaced; (_) -> ok end, diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 8f6724281..2ad1cc28e 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -863,12 +863,15 @@ connected_users_vhost(Host) -> %% Code copied from ejabberd_sm.erl and customized dirty_get_sessions_list2() -> - mnesia:dirty_select( - session, - [{#session{usr = '$1', sid = {'$2', '$3'}, priority = '$4', info = '$5', - _ = '_'}, - [{is_pid, '$3'}], - [['$1', {{'$2', '$3'}}, '$4', '$5']]}]). + Ss = mnesia:dirty_select( + session, + [{#session{usr = '$1', sid = '$2', priority = '$3', info = '$4', + _ = '_'}, + [], + [['$1', '$2', '$3', '$4']]}]), + lists:filter(fun([_USR, _SID, _Priority, Info]) -> + not proplists:get_bool(offline, Info) + end, Ss). %% Make string more print-friendly stringize(String) -> @@ -903,8 +906,8 @@ user_sessions_info(User, Host) -> {'EXIT', _Reason} -> []; Ss -> - lists:filter(fun(#session{sid = {_, Pid}}) -> - is_pid(Pid) + lists:filter(fun(#session{info = Info}) -> + not proplists:get_bool(offline, Info) end, Ss) end, lists:map( diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 97c944842..d0e0166a4 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -1917,21 +1917,29 @@ set_form(From, Host, ?NS_ADMINL(<<"end-user-session">>), Xmlelement = ?SERRT_POLICY_VIOLATION(Lang, <<"has been kicked">>), case JID#jid.lresource of <<>> -> - SIDs = mnesia:dirty_select(session, - [{#session{sid = {'$1', '$2'}, - usr = {LUser, LServer, '_'}, - _ = '_'}, - [{is_pid, '$2'}], - [{{'$1', '$2'}}]}]), - [Pid ! {kick, kicked_by_admin, Xmlelement} || {_, Pid} <- SIDs]; + SIs = mnesia:dirty_select(session, + [{#session{usr = {LUser, LServer, '_'}, + sid = '$1', + info = '$2', + _ = '_'}, + [], [{{'$1', '$2'}}]}]), + Pids = [P || {{_, P}, Info} <- SIs, + not proplists:get_bool(offline, Info)], + lists:foreach(fun(Pid) -> + Pid ! {kick, kicked_by_admin, Xmlelement} + end, Pids); R -> - [{_, Pid}] = mnesia:dirty_select(session, - [{#session{sid = {'$1', '$2'}, - usr = {LUser, LServer, R}, - _ = '_'}, - [{is_pid, '$2'}], - [{{'$1', '$2'}}]}]), - Pid ! {kick, kicked_by_admin, Xmlelement} + [{{_, Pid}, Info}] = mnesia:dirty_select( + session, + [{#session{usr = {LUser, LServer, R}, + sid = '$1', + info = '$2', + _ = '_'}, + [], [{{'$1', '$2'}}]}]), + case proplists:get_bool(offline, Info) of + true -> ok; + false -> Pid ! {kick, kicked_by_admin, Xmlelement} + end end, {result, []}; set_form(From, Host, |