mod_multicast changes:

- catch exceptions
- do ets:give_away for multicastp table on init
- don't send multicasts to itself
- don't check user@server for multicast support
- handle empty disco items
- ignore cdata in <addresses/>
- properly check for subdomains
This commit is contained in:
Alexey Shchepin 2015-08-05 19:17:58 +03:00
parent 3a5dd51b42
commit 4125dfd166
1 changed files with 81 additions and 41 deletions

View File

@ -153,24 +153,11 @@ handle_cast(_Msg, State) -> {noreply, State}.
handle_info({route, From, To,
#xmlel{name = <<"iq">>, attrs = Attrs} = Packet},
State) ->
IQ = jlib:iq_query_info(Packet),
case catch process_iq(From, IQ, State) of
Result when is_record(Result, iq) ->
ejabberd_router:route(To, From, jlib:iq_to_xml(Result));
{'EXIT', Reason} ->
?ERROR_MSG("Error when processing IQ stanza: ~p",
[Reason]),
Err = jlib:make_error_reply(Packet,
?ERR_INTERNAL_SERVER_ERROR),
ejabberd_router:route(To, From, Err);
reply ->
LServiceS = jts(To),
case xml:get_attr_s(<<"type">>, Attrs) of
<<"result">> ->
process_iqreply_result(From, LServiceS, Packet, State);
<<"error">> ->
process_iqreply_error(From, LServiceS, Packet)
end
case catch handle_iq(From, To, #xmlel{attrs = Attrs} = Packet, State) of
{'EXIT', Reason} ->
?ERROR_MSG("Error when processing IQ stanza: ~p",
[Reason]);
_ -> ok
end,
{noreply, State};
%% XEP33 allows only 'message' and 'presence' stanza type
@ -188,11 +175,16 @@ handle_info({route, From, To,
handle_info({route_trusted, From, Destinations, Packet},
#state{lservice = LServiceS, lserver = LServerS} =
State) ->
route_trusted(LServiceS, LServerS, From, Destinations,
Packet),
case catch route_trusted(LServiceS, LServerS, From, Destinations,
Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("Error in route_trusted: ~p", [Reason]);
_ -> ok
end,
{noreply, State};
handle_info({get_host, Pid}, State) ->
Pid ! {my_host, State#state.lservice}, {noreply, State};
Pid ! {my_host, State#state.lservice},
{noreply, State};
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, State) ->
@ -210,6 +202,28 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
%%% IQ Request Processing
%%%------------------------
handle_iq(From, To, #xmlel{attrs = Attrs} = Packet, State) ->
IQ = jlib:iq_query_info(Packet),
case catch process_iq(From, IQ, State) of
Result when is_record(Result, iq) ->
ejabberd_router:route(To, From, jlib:iq_to_xml(Result));
{'EXIT', Reason} ->
?ERROR_MSG("Error when processing IQ stanza: ~p",
[Reason]),
Err = jlib:make_error_reply(Packet,
?ERR_INTERNAL_SERVER_ERROR),
ejabberd_router:route(To, From, Err);
reply ->
LServiceS = jts(To),
case xml:get_attr_s(<<"type">>, Attrs) of
<<"result">> ->
process_iqreply_result(From, LServiceS, Packet, State);
<<"error">> ->
process_iqreply_error(From, LServiceS, Packet)
end;
ok -> ok
end.
process_iq(From,
#iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} =
IQ,
@ -377,6 +391,9 @@ perform(From, Packet, AAttrs, LServiceS,
group = Group, renewal = true, sender = From,
packet = Packet, aattrs = AAttrs,
addresses = Group#group.addresses});
perform(_From, _Packet, _AAttrs, LServiceS,
{{ask, LServiceS, _}, _Group}) ->
ok;
perform(From, Packet, AAttrs, LServiceS,
{{ask, Server, not_renewal}, Group}) ->
send_query_info(Server, LServiceS),
@ -411,7 +428,7 @@ strip_addresses_element(Packet) ->
Els_stripped = lists:keydelete(<<"addresses">>, 2, Els),
Packet_stripped = #xmlel{name = Name, attrs = Attrs,
children = Els_stripped},
{ok, Packet_stripped, AAttrs, Addresses};
{ok, Packet_stripped, AAttrs, xml:remove_cdata(Addresses)};
_ -> throw(ewxmlns)
end;
_ -> throw(eadsele)
@ -646,7 +663,8 @@ check_relay(RS, LS, Gs) ->
end.
check_relay_required(RServer, LServerS, Groups) ->
case str:str(RServer, LServerS) > 0 of
case lists:suffix(str:tokens(LServerS, <<".">>),
str:tokens(RServer, <<".">>)) of
true -> false;
false -> check_relay_required(LServerS, Groups)
end.
@ -830,29 +848,44 @@ get_limits_values(Values) ->
%%%-------------------------
process_discoitems_result(From, LServiceS, Els) ->
List = lists:foldl(fun (XML, Res) ->
case XML of
#xmlel{name = <<"item">>, attrs = Attrs} ->
Res ++ [xml:get_attr_s(<<"jid">>, Attrs)];
_ -> Res
end
end,
[], Els),
[send_query_info(Item, LServiceS) || Item <- List],
FromS = jts(From),
{found_waiter, Waiter} = search_waiter(FromS, LServiceS,
items),
delo_waiter(Waiter),
add_waiter(Waiter#waiter{awaiting =
{List, LServiceS, info},
renewal = false}).
case search_waiter(FromS, LServiceS, items) of
{found_waiter, Waiter} ->
List = lists:foldl(
fun(XML, Res) ->
case XML of
#xmlel{name = <<"item">>, attrs = Attrs} ->
SJID = xml:get_attr_s(<<"jid">>, Attrs),
case jlib:string_to_jid(SJID) of
#jid{luser = <<"">>,
lresource = <<"">>} ->
[SJID | Res];
_ -> Res
end;
_ -> Res
end
end,
[], Els),
case List of
[] ->
received_awaiter(FromS, Waiter, LServiceS);
_ ->
[send_query_info(Item, LServiceS) || Item <- List],
delo_waiter(Waiter),
add_waiter(Waiter#waiter{awaiting =
{List, LServiceS, info},
renewal = false})
end;
_ ->
ok
end.
%%%-------------------------
%%% Check protocol support: Receive response: Received awaiter
%%%-------------------------
received_awaiter(JID, Waiter, LServiceS) ->
{JIDs, LServiceS, info} = Waiter#waiter.awaiting,
{JIDs, LServiceS, _} = Waiter#waiter.awaiting,
delo_waiter(Waiter),
Group = Waiter#waiter.group,
RServer = Group#group.server,
@ -984,8 +1017,12 @@ purge_loop(NM) ->
%%%-------------------------
create_pool() ->
catch ets:new(multicastp,
[duplicate_bag, public, named_table, {keypos, 2}]).
catch
begin
ets:new(multicastp,
[duplicate_bag, public, named_table, {keypos, 2}]),
ets:give_away(multicastp, whereis(ejabberd), ok)
end.
add_waiter(Waiter) ->
true = ets:insert(multicastp, Waiter).
@ -993,6 +1030,9 @@ add_waiter(Waiter) ->
delo_waiter(Waiter) ->
true = ets:delete_object(multicastp, Waiter).
-spec search_waiter(binary(), binary(), info | items) ->
{found_waiter, #waiter{}} | waiter_not_found.
search_waiter(JID, LServiceS, Type) ->
Rs = ets:foldl(fun (W, Res) ->
{JIDs, LServiceS1, Type1} = W#waiter.awaiting,