From bc008d40419a94c20498371fac771638a39b84d2 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Wed, 25 Mar 2015 00:13:05 +0100 Subject: [PATCH 1/4] Update routing for unavailable resources As per RFC 6121, don't reroute non-chat messages sent to unavailable resources. --- src/ejabberd_sm.erl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index abe15d9ff..ebcf6fa58 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -525,7 +525,15 @@ do_route(From, To, #xmlel{} = Packet) -> case Mod:get_sessions(LUser, LServer, LResource) of [] -> case Name of - <<"message">> -> route_message(From, To, Packet); + <<"message">> -> + case xml:get_attr_s(<<"type">>, Attrs) of + <<"chat">> -> route_message(From, To, Packet); + <<"error">> -> ok; + _ -> + Err = jlib:make_error_reply(Packet, + ?ERR_SERVICE_UNAVAILABLE), + ejabberd_router:route(To, From, Err) + end; <<"iq">> -> case xml:get_attr_s(<<"type">>, Attrs) of <<"error">> -> ok; From 8f9a2d6df8a79a9d8e348ab0f5219a006131f4c3 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Wed, 25 Mar 2015 00:52:49 +0100 Subject: [PATCH 2/4] Don't route error/groupchat messages to bare JIDs As per RFC 6121, drop error messages that were sent to bare JIDs, and return an error if a groupchat message was sent to a bare JID. --- src/ejabberd_sm.erl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index ebcf6fa58..478de69c0 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -516,7 +516,18 @@ do_route(From, To, #xmlel{} = Packet) -> PResources); true -> ok end; - <<"message">> -> route_message(From, To, Packet); + <<"message">> -> + case xml:get_attr_s(<<"type">>, Attrs) of + <<"chat">> -> route_message(From, To, Packet); + <<"headline">> -> route_message(From, To, Packet); + <<"error">> -> ok; + <<"groupchat">> -> + Err = jlib:make_error_reply(Packet, + ?ERR_SERVICE_UNAVAILABLE), + ejabberd_router:route(To, From, Err); + _ -> + route_message(From, To, Packet) + end; <<"iq">> -> process_iq(From, To, Packet); _ -> ok end; From 1b1878409f7354f9eb2f2c0564d31fb772ab6801 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Wed, 25 Mar 2015 01:17:35 +0100 Subject: [PATCH 3/4] Route headlines sent to bare JIDs to all resources As per RFC 6121, deliver headline messages that were sent to a bare JID to all resources with a non-negative priority, not just to those with the highest priority. If no such resource is available, discard them silently. --- src/ejabberd_sm.erl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 478de69c0..2a508c565 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -518,15 +518,15 @@ do_route(From, To, #xmlel{} = Packet) -> end; <<"message">> -> case xml:get_attr_s(<<"type">>, Attrs) of - <<"chat">> -> route_message(From, To, Packet); - <<"headline">> -> route_message(From, To, Packet); + <<"chat">> -> route_message(From, To, Packet, chat); + <<"headline">> -> route_message(From, To, Packet, headline); <<"error">> -> ok; <<"groupchat">> -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); _ -> - route_message(From, To, Packet) + route_message(From, To, Packet, normal) end; <<"iq">> -> process_iq(From, To, Packet); _ -> ok @@ -538,7 +538,7 @@ do_route(From, To, #xmlel{} = Packet) -> case Name of <<"message">> -> case xml:get_attr_s(<<"type">>, Attrs) of - <<"chat">> -> route_message(From, To, Packet); + <<"chat">> -> route_message(From, To, Packet, chat); <<"error">> -> ok; _ -> Err = jlib:make_error_reply(Packet, @@ -587,14 +587,15 @@ is_privacy_allow(From, To, Packet, PrivacyList) -> [User, Server, PrivacyList, {From, To, Packet}, in]). -route_message(From, To, Packet) -> +route_message(From, To, Packet, Type) -> LUser = To#jid.luser, LServer = To#jid.lserver, PrioRes = get_user_present_resources(LUser, LServer), case catch lists:max(PrioRes) of {Priority, _R} when is_integer(Priority), Priority >= 0 -> - lists:foreach(fun ({P, R}) when P == Priority -> + lists:foreach(fun ({P, R}) when P == Priority; + (P >= 0) and (Type == headline) -> LResource = jlib:resourceprep(R), Mod = get_sm_backend(), case Mod:get_sessions(LUser, LServer, @@ -612,11 +613,10 @@ route_message(From, To, Packet) -> end, PrioRes); _ -> - case xml:get_tag_attr_s(<<"type">>, Packet) of - <<"error">> -> ok; - <<"groupchat">> -> - bounce_offline_message(From, To, Packet); - <<"headline">> -> + case Type of + error -> ok; + headline -> ok; + groupchat -> bounce_offline_message(From, To, Packet); _ -> case ejabberd_auth:is_user_exists(LUser, LServer) of From f40e6a0421f382c52216a47b4ffaf19c95a3cc70 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Wed, 25 Mar 2015 02:02:08 +0100 Subject: [PATCH 4/4] Don't bother with filtering out PEP error messages Now that ejabberd_sm won't deliver error messages that were sent to bare JIDs anymore, PEP error messages should no longer arrive. --- src/ejabberd_c2s.erl | 21 +++++---------------- src/mod_pubsub.erl | 34 +--------------------------------- src/mod_pubsub_odbc.erl | 34 +--------------------------------- 3 files changed, 7 insertions(+), 82 deletions(-) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 0e3f856ca..e739c6789 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1700,23 +1700,12 @@ handle_info({route, From, To, jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), NewAttrs), FixedPacket = #xmlel{name = Name, attrs = Attrs2, children = Els}, - FinalState = - case ejabberd_hooks:run_fold(c2s_filter_packet_in, - NewState#state.server, FixedPacket, - [NewState#state.jid, From, To]) - of - drop -> - NewState; - FinalPacket = #xmlel{} -> - SentState = send_packet(NewState, FinalPacket), - ejabberd_hooks:run(user_receive_packet, - SentState#state.server, - [SentState#state.jid, From, To, - FinalPacket]), - SentState - end, + SentStateData = send_packet(NewState, FixedPacket), + ejabberd_hooks:run(user_receive_packet, + SentStateData#state.server, + [SentStateData#state.jid, From, To, FixedPacket]), ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), - fsm_next_state(StateName, FinalState); + fsm_next_state(StateName, SentStateData); true -> ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), fsm_next_state(StateName, NewState) diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 08e351462..579c47757 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -74,8 +74,7 @@ on_user_offline/3, remove_user/2, disco_local_identity/5, disco_local_features/5, disco_local_items/5, disco_sm_identity/5, - disco_sm_features/5, disco_sm_items/5, - drop_pep_error/4]). + disco_sm_features/5, disco_sm_items/5]). %% exported iq handlers -export([iq_sm/3]). @@ -345,8 +344,6 @@ init([ServerHost, Opts]) -> ?MODULE, disco_sm_features, 75), ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:add(c2s_filter_packet_in, ServerHost, ?MODULE, - drop_pep_error, 75), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB, ?MODULE, iq_sm, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, @@ -1331,33 +1328,6 @@ unsubscribe_user(Entity, Owner) -> plugins(Host)) end). -%% ------- -%% packet receive hook handling function -%% - -drop_pep_error(#xmlel{name = <<"message">>, attrs = Attrs} = Packet, _JID, From, - #jid{lresource = <<"">>} = To) -> - case xml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> - case xml:get_subtag(Packet, <<"event">>) of - #xmlel{attrs = EventAttrs} -> - case xml:get_attr_s(<<"xmlns">>, EventAttrs) of - ?NS_PUBSUB_EVENT -> - ?DEBUG("Dropping PEP error message from ~s to ~s", - [jlib:jid_to_string(From), - jlib:jid_to_string(To)]), - drop; - _ -> - Packet - end; - false -> - Packet - end; - _ -> - Packet - end; -drop_pep_error(Acc, _JID, _From, _To) -> Acc. - %% ------- %% user remove hook handling function %% @@ -1498,8 +1468,6 @@ terminate(_Reason, ?MODULE, disco_sm_features, 75), ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:delete(c2s_filter_packet_in, ServerHost, - ?MODULE, drop_pep_error, 75), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB), gen_iq_handler:remove_iq_handler(ejabberd_sm, diff --git a/src/mod_pubsub_odbc.erl b/src/mod_pubsub_odbc.erl index 4b9787821..8b32b83e2 100644 --- a/src/mod_pubsub_odbc.erl +++ b/src/mod_pubsub_odbc.erl @@ -74,8 +74,7 @@ on_user_offline/3, remove_user/2, disco_local_identity/5, disco_local_features/5, disco_local_items/5, disco_sm_identity/5, - disco_sm_features/5, disco_sm_items/5, - drop_pep_error/4]). + disco_sm_features/5, disco_sm_items/5]). %% exported iq handlers -export([iq_sm/3]). @@ -345,8 +344,6 @@ init([ServerHost, Opts]) -> ?MODULE, disco_sm_features, 75), ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:add(c2s_filter_packet_in, ServerHost, ?MODULE, - drop_pep_error, 75), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB, ?MODULE, iq_sm, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, @@ -941,33 +938,6 @@ unsubscribe_user(Entity, Owner) -> plugins(Host)) end). -%% ------- -%% packet receive hook handling function -%% - -drop_pep_error(#xmlel{name = <<"message">>, attrs = Attrs} = Packet, _JID, From, - #jid{lresource = <<"">>} = To) -> - case xml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> - case xml:get_subtag(Packet, <<"event">>) of - #xmlel{attrs = EventAttrs} -> - case xml:get_attr_s(<<"xmlns">>, EventAttrs) of - ?NS_PUBSUB_EVENT -> - ?DEBUG("Dropping PEP error message from ~s to ~s", - [jlib:jid_to_string(From), - jlib:jid_to_string(To)]), - drop; - _ -> - Packet - end; - false -> - Packet - end; - _ -> - Packet - end; -drop_pep_error(Acc, _JID, _From, _To) -> Acc. - %% ------- %% user remove hook handling function %% @@ -1108,8 +1078,6 @@ terminate(_Reason, ?MODULE, disco_sm_features, 75), ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:delete(c2s_filter_packet_in, ServerHost, - ?MODULE, drop_pep_error, 75), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB), gen_iq_handler:remove_iq_handler(ejabberd_sm,