aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_sm.erl
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-07-23 01:08:05 +0200
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-07-23 01:08:05 +0200
commit814b80c644fa425990dc63875e1da841d698b0fa (patch)
tree277041ddec51894c69741f6df070b6a50e3ca4c4 /src/ejabberd_sm.erl
parentSupport 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/ejabberd_sm.erl')
-rw-r--r--src/ejabberd_sm.erl42
1 files changed, 24 insertions, 18 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,