diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 7f0fb5e76..0f168f323 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -186,8 +186,6 @@ session_established({xmlstreamelement, El}, StateData) -> presence_update(FromJID, El, StateData); _ -> presence_track(FromJID, ToJID, El, StateData) - %ejabberd_router:route(FrJID, ToJID, El), - %NewSt end; _ -> ejabberd_router:route(FromJID, ToJID, El), @@ -264,14 +262,8 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> process_presence_probe(From, To, StateData), {false, Attrs, StateData}; "error" -> - case ?SETS:is_element(From, StateData#state.pres_a) of - true -> - A = ?SETS:del_element(From, - StateData#state.pres_a), - {true, Attrs, StateData#state{pres_a = A}}; - _ -> - {true, Attrs, StateData} - end; + NewA = remove_element(From, StateData#state.pres_a), + {true, Attrs, StateData#state{pres_a = NewA}}; "invisible" -> Attrs1 = lists:keydelete("type", 1, Attrs), {true, [{"type", "unavailable"} | Attrs1], StateData}; @@ -467,12 +459,12 @@ presence_update(From, Packet, StateData) -> S1 = StateData#state{pres_last = undefined, pres_a = ?SETS:new(), pres_i = ?SETS:new(), - pres_invis = false}, + pres_invis = true}, presence_broadcast_first(From, S1, Packet); true -> StateData end, - StateData; + NewState; "error" -> StateData; "subscribe" -> @@ -495,18 +487,20 @@ presence_update(From, Packet, StateData) -> mod_offline:resend_offline_messages( StateData#state.user), - presence_broadcast_first(From, StateData, Packet); + presence_broadcast_first( + From, StateData#state{pres_last = Packet, + pres_invis = false + }, Packet); true -> presence_broadcast_to_trusted(From, StateData#state.pres_f, StateData#state.pres_a, Packet), - StateData + StateData#state{pres_last = Packet, + pres_invis = false + } end, - - NewState#state{pres_last = Packet, - pres_invis = false - } + NewState end. presence_track(From, To, Packet, StateData) -> diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index bb60b797c..8fda160c0 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -98,40 +98,6 @@ loop() -> loop() end. - -%do_route(From, To, Packet) -> -% ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]), -% {DstNode, DstDomain, DstResourse} = To, -% F = fun() -> -% case mnesia:read({local_route, DstDomain}) of -% [] -> -% case mnesia:read({route, DstDomain}) of -% [] -> -% false; -% [R] -> -% {ok, R#route.node, R#route.pid} -% end; -% [R] -> -% {ok, node(), R#local_route.pid} -% end -% end, -% case mnesia:transaction(F) of -% {atomic, false} -> -% ejabberd_s2s ! {route, From, To, Packet}; -% {atomic, {ok, Node, Pid}} -> -% case node() of -% Node -> -% ?DEBUG("routed to process ~p~n", [Pid]), -% Pid ! {route, From, To, Packet}; -% _ -> -% ?DEBUG("routed to node ~p~n", [Node]), -% {ejabberd_router, Node} ! {route, From, To, Packet} -% end; -% _ -> -% % TODO -% error -% end. - do_route(From, To, Packet) -> ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]), {DstNode, DstDomain, DstResourse} = To, diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 04b941656..725c98c7c 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -165,110 +165,6 @@ clean_table_from_bad_node(Node) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%do_route(From, To, Packet) -> -% ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", -% [From, To, Packet, 8]), -% {User, Server, Resource} = To, -% F = fun() -> -% UR = {User, Resource}, -% Sess = mnesia:read({session, UR}), -% case Sess of -% [] -> -% not_exists; -% [Ses] -> -% case mnesia:read({mysession, UR}) of -% [] -> -% {remote, Ses#session.node}; -% [El] -> -% {local, El#mysession.pid} -% end -% end -% end, -% {xmlelement, Name, Attrs, Els} = Packet, -% case Resource of -% "" -> -% % TODO -% case Name of -% "presence" -> -% {FU, FS, FR} = From, -% Pass = case xml:get_attr_s("type", Attrs) of -% "subscribe" -> -% mod_roster:in_subscription(User, -% {FU, FS, ""}, -% subscribe); -% "subscribed" -> -% mod_roster:in_subscription(User, -% {FU, FS, ""}, -% subscribed); -% "unsubscribe" -> -% mod_roster:in_subscription(User, -% {FU, FS, ""}, -% unsubscribe); -% "unsubscribed" -> -% mod_roster:in_subscription(User, -% {FU, FS, ""}, -% unsubscribed); -% _ -> -% true -% end, -% if Pass -> -% LFrom = jlib:jid_tolower(From), -% LUser = jlib:tolower(User), -% LServer = jlib:tolower(Server), -% lists:foreach( -% fun(R) -> -% if LFrom /= {LUser, LServer, R} -> -% ejabberd_sm ! {route, -% From, -% {User, Server, R}, -% Packet}; -% true -> -% ok -% end -% end, get_user_resources(User)); -% true -> -% ok -% end; -% "message" -> -% route_message(From, To, Packet); -% "iq" -> -% process_iq(From, To, Packet); -% "broadcast" -> -% lists:foreach( -% fun(R) -> -% ejabberd_sm ! {route, -% From, -% {User, Server, R}, -% Packet} -% end, get_user_resources(User)); -% _ -> -% ok -% end; -% _ -> -% case mnesia:transaction(F) of -% {atomic, {local, Pid}} -> -% ?DEBUG("sending to process ~p~n", [Pid]), -% Pid ! {route, From, To, Packet}, -% ok; -% {atomic, {remote, Node}} -> -% ?DEBUG("sending to node ~p~n", [Node]), -% {ejabberd_sm, Node} ! {route, From, To, Packet}, -% ok; -% {atomic, not_exists} -> -% if -% Name == "message" -> -% route_message(From, To, Packet); -% true -> -% ?DEBUG("packet droped~n", []) -% end, -% ok; -% {aborted, Reason} -> -% ?DEBUG("delivery failed: ~p~n", [Reason]), -% false -% end -% end. - - do_route(From, To, Packet) -> ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", @@ -281,41 +177,60 @@ do_route(From, To, Packet) -> case Name of "presence" -> {FU, FS, FR} = From, - Pass = case xml:get_attr_s("type", Attrs) of - "subscribe" -> - mod_roster:in_subscription(User, - {FU, FS, ""}, - subscribe); - "subscribed" -> - mod_roster:in_subscription(User, - {FU, FS, ""}, - subscribed); - "unsubscribe" -> - mod_roster:in_subscription(User, - {FU, FS, ""}, - unsubscribe); - "unsubscribed" -> - mod_roster:in_subscription(User, - {FU, FS, ""}, - unsubscribed); - _ -> - true - end, + {Pass, Subsc} = + case xml:get_attr_s("type", Attrs) of + "subscribe" -> + {mod_roster:in_subscription(User, + {FU, FS, ""}, + subscribe), + true}; + "subscribed" -> + {mod_roster:in_subscription(User, + {FU, FS, ""}, + subscribed), + true}; + "unsubscribe" -> + {mod_roster:in_subscription(User, + {FU, FS, ""}, + unsubscribe), + true}; + "unsubscribed" -> + {mod_roster:in_subscription(User, + {FU, FS, ""}, + unsubscribed), + true}; + _ -> + {true, false} + end, if Pass -> LFrom = jlib:jid_tolower(From), LUser = jlib:tolower(User), LServer = jlib:tolower(Server), - lists:foreach( - fun(R) -> - if LFrom /= {LUser, LServer, R} -> - ejabberd_sm ! {route, - From, - {User, Server, R}, - Packet}; - true -> - ok - end - end, get_user_resources(User)); + Resources = get_user_resources(User), + if + Resources /= [] -> + lists:foreach( + fun(R) -> + if LFrom /= + {LUser, LServer, R} -> + ejabberd_sm ! + {route, + From, + {User, Server, R}, + Packet}; + true -> + ok + end + end, Resources); + true -> + if + Subsc -> + mod_offline:store_packet( + From, To, Packet); + true -> + ok + end + end; true -> ok end; diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 5de590f4b..213c46554 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -139,10 +139,10 @@ item_to_xml(Item) -> process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) -> {User, _, _} = From, {xmlelement, Name, Attrs, Els} = SubEl, - lists:foreach(fun(El) -> process_item_set(User, To, El) end, Els), + lists:foreach(fun(El) -> process_item_set(User, From, To, El) end, Els), {iq, ID, result, XMLNS, []}. -process_item_set(User, To, XItem) -> +process_item_set(User, From, To, XItem) -> {xmlelement, Name, Attrs, Els} = XItem, % TODO: load existing item JID = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), @@ -175,12 +175,43 @@ process_item_set(User, To, XItem) -> _ -> mnesia:write(Item2) end, - Item2 + {Item, Item2} end, case mnesia:transaction(F) of - {atomic, Item} -> + {atomic, {OldItem, Item}} -> push_item(User, To, Item), - ok; + case Item#roster.subscription of + remove -> + IsTo = case OldItem#roster.subscription of + both -> true; + to -> true; + _ -> false + end, + IsFrom = case OldItem#roster.subscription of + both -> true; + from -> true; + _ -> false + end, + if IsTo -> + ejabberd_router:route( + From, OldItem#roster.jid, + {xmlelement, "presence", + [{"type", "unsubscribe"}], + []}); + true -> ok + end, + if IsFrom -> + ejabberd_router:route( + From, OldItem#roster.jid, + {xmlelement, "presence", + [{"type", "unsubscribed"}], + []}); + true -> ok + end, + ok; + _ -> + ok + end; E -> ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok @@ -410,7 +441,6 @@ out_subscription(User, JID, Type) -> none -> from; _ -> S end, - % TODO: update presence {Item#roster{subscription = NS, ask = none}, true}; @@ -421,7 +451,6 @@ out_subscription(User, JID, Type) -> from -> none; _ -> S end, - % TODO: update presence {Item#roster{subscription = NS, ask = none}, true}