mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
Merge from trunk (r1709 to r1730).
Ejabberd should be usable again. PR: EJABP-1 SVN Revision: 1731
This commit is contained in:
parent
62f9f6e6c5
commit
6a3436b1c4
49
ChangeLog
49
ChangeLog
@ -1,3 +1,9 @@
|
|||||||
|
2008-12-16 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
|
Merge from trunk (r1709 to r1730).
|
||||||
|
|
||||||
|
Ejabberd should be usable again.
|
||||||
|
|
||||||
2008-12-16 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
2008-12-16 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
* src/mod_pubsub/mod_pubsub.erl: Convert to exmpp the parts recently
|
* src/mod_pubsub/mod_pubsub.erl: Convert to exmpp the parts recently
|
||||||
@ -9,6 +15,10 @@
|
|||||||
* src/mod_pubsub/mod_pubsub.erl: Fix get_item_name deadlock on
|
* src/mod_pubsub/mod_pubsub.erl: Fix get_item_name deadlock on
|
||||||
transaction
|
transaction
|
||||||
|
|
||||||
|
2008-12-12 Alexey Shchepin <alexey@process-one.net>
|
||||||
|
|
||||||
|
* src/ejabberd_c2s.erl: Bugfix in "from" attribute checking
|
||||||
|
|
||||||
2008-12-10 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
2008-12-10 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
* src/eldap/eldap_utils.erl (case_insensitive_match/2): Replace
|
* src/eldap/eldap_utils.erl (case_insensitive_match/2): Replace
|
||||||
@ -18,9 +28,46 @@
|
|||||||
|
|
||||||
* src/mod_pubsub: Merge from latest trunk (r1716).
|
* src/mod_pubsub: Merge from latest trunk (r1716).
|
||||||
|
|
||||||
|
2008-12-09 Christophe Romain <christophe.romain@process-one.net>
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: prevent publish items with invalid
|
||||||
|
XML schema bugfix (EJAB-699) (previous commit was uncomplete)
|
||||||
|
and fix bug injected in previous commit
|
||||||
|
|
||||||
|
2008-12-08 Christophe Romain <christophe.romain@process-one.net>
|
||||||
|
|
||||||
|
* src/ejabberd_c2s.erl: Reduce memory consumption due to caps handling
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: Likewise
|
||||||
|
* src/mod_caps.erl: Likewise
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: ignore unknown configuration fields
|
||||||
|
(EJAB-762) (thanks to Jack Moffitt)
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: fix node authorization bug (EJAB-798)
|
||||||
|
send authorization update event (EJAB-799) (thanks to Brian Cully)
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: add nodetree filtering and
|
||||||
|
authorization (EJAB-813) (thanks to Brian Cully)
|
||||||
|
* src/mod_pubsub/nodetree_default.erl: Likewise
|
||||||
|
* src/mod_pubsub/nodetree_virtual.erl: Likewise
|
||||||
|
* src/mod_pubsub/gen_pubsub_nodetree.erl: Likewise
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: prevent publish items with invalid
|
||||||
|
XML schema (EJAB-699)
|
||||||
|
|
||||||
|
* src/mod_pubsub/pubsub.hrl: remove unused pubsub_presence record
|
||||||
|
|
||||||
|
* src/mod_pubsub/node_flat.erl: renamed from node_zoo
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: reply to suscriptions options queries
|
||||||
|
with unsupported feature error (EJAB-713)
|
||||||
|
|
||||||
|
* src/mod_pubsub/node_default.erl: remove pubsub_state record when
|
||||||
|
unsubscribing node without affiliation (EJAB-776)
|
||||||
|
|
||||||
2008-12-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
2008-12-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
* src/mod_pubsub: Merge from trunk (r1692 to r1709).
|
Merge from trunk (r1692 to r1709).
|
||||||
|
|
||||||
2008-12-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
2008-12-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
|
@ -37,8 +37,7 @@
|
|||||||
send_element/2,
|
send_element/2,
|
||||||
socket_type/0,
|
socket_type/0,
|
||||||
get_presence/1,
|
get_presence/1,
|
||||||
get_subscribed/1,
|
get_subscribed/1]).
|
||||||
get_subscribed_and_online/1]).
|
|
||||||
|
|
||||||
%% gen_fsm callbacks
|
%% gen_fsm callbacks
|
||||||
-export([init/1,
|
-export([init/1,
|
||||||
@ -85,7 +84,6 @@
|
|||||||
pres_f = ?SETS:new(),
|
pres_f = ?SETS:new(),
|
||||||
pres_a = ?SETS:new(),
|
pres_a = ?SETS:new(),
|
||||||
pres_i = ?SETS:new(),
|
pres_i = ?SETS:new(),
|
||||||
pres_available = ?DICT:new(),
|
|
||||||
pres_last, pres_pri,
|
pres_last, pres_pri,
|
||||||
pres_timestamp,
|
pres_timestamp,
|
||||||
pres_invis = false,
|
pres_invis = false,
|
||||||
@ -205,14 +203,8 @@ init([{SockMod, Socket}, Opts]) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% Return list of all available resources of contacts,
|
%% Return list of all available resources of contacts,
|
||||||
%% in form [{JID, Caps}].
|
|
||||||
get_subscribed(FsmRef) ->
|
get_subscribed(FsmRef) ->
|
||||||
gen_fsm:sync_send_all_state_event(
|
gen_fsm:sync_send_all_state_event(FsmRef, get_subscribed, 1000).
|
||||||
FsmRef, get_subscribed, 1000).
|
|
||||||
get_subscribed_and_online(FsmRef) ->
|
|
||||||
gen_fsm:sync_send_all_state_event(
|
|
||||||
FsmRef, get_subscribed_and_online, 1000).
|
|
||||||
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
%% Func: StateName/2
|
%% Func: StateName/2
|
||||||
@ -951,29 +943,8 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
|
|||||||
fsm_reply(Reply, StateName, StateData);
|
fsm_reply(Reply, StateName, StateData);
|
||||||
|
|
||||||
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
|
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
|
||||||
Subscribed = StateData#state.pres_f,
|
Subscribed = ?SETS:to_list(StateData#state.pres_f),
|
||||||
Online = StateData#state.pres_available,
|
{reply, Subscribed, StateName, StateData};
|
||||||
Pred = fun({U, S, _} = User, _Caps) ->
|
|
||||||
?SETS:is_element({U, S, undefined},
|
|
||||||
Subscribed) orelse
|
|
||||||
?SETS:is_element(User, Subscribed)
|
|
||||||
end,
|
|
||||||
SubscribedAndOnline = ?DICT:filter(Pred, Online),
|
|
||||||
SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
|
|
||||||
[{User, undefined}|Acc]
|
|
||||||
end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
|
|
||||||
{reply, SubscribedWithCaps, StateName, StateData};
|
|
||||||
|
|
||||||
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
|
|
||||||
Subscribed = StateData#state.pres_f,
|
|
||||||
Online = StateData#state.pres_available,
|
|
||||||
Pred = fun({U, S, _R} = User, _Caps) ->
|
|
||||||
?SETS:is_element({U, S, undefined},
|
|
||||||
Subscribed) orelse
|
|
||||||
?SETS:is_element(User, Subscribed)
|
|
||||||
end,
|
|
||||||
SubscribedAndOnline = ?DICT:filter(Pred, Online),
|
|
||||||
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
|
|
||||||
|
|
||||||
handle_sync_event(_Event, _From, StateName, StateData) ->
|
handle_sync_event(_Event, _From, StateName, StateData) ->
|
||||||
Reply = ok,
|
Reply = ok,
|
||||||
@ -1065,42 +1036,39 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
|||||||
LFrom = jlib:short_prepd_jid(From),
|
LFrom = jlib:short_prepd_jid(From),
|
||||||
LBFrom = jlib:short_prepd_bare_jid(From),
|
LBFrom = jlib:short_prepd_bare_jid(From),
|
||||||
%% Note contact availability
|
%% Note contact availability
|
||||||
Els = Packet#xmlel.children,
|
case exmpp_presence:get_type(Packet) of
|
||||||
Caps = mod_caps:read_caps(Els),
|
'unavailable' ->
|
||||||
mod_caps:note_caps(StateData#state.server, From, Caps),
|
mod_caps:clear_caps(From);
|
||||||
NewAvailable = case exmpp_presence:get_type(Packet) of
|
_ ->
|
||||||
'unavailable' ->
|
Caps = mod_caps:read_caps(Packet#xmlel.children),
|
||||||
?DICT:erase(LFrom, StateData#state.pres_available);
|
mod_caps:note_caps(StateData#state.server, From, Caps)
|
||||||
_ ->
|
end,
|
||||||
?DICT:store(LFrom, Caps, StateData#state.pres_available)
|
|
||||||
end,
|
|
||||||
NewStateData = StateData#state{pres_available = NewAvailable},
|
|
||||||
case ?SETS:is_element(
|
case ?SETS:is_element(
|
||||||
LFrom, NewStateData#state.pres_a) orelse
|
LFrom, StateData#state.pres_a) orelse
|
||||||
?SETS:is_element(
|
?SETS:is_element(
|
||||||
LBFrom, NewStateData#state.pres_a) of
|
LBFrom, StateData#state.pres_a) of
|
||||||
true ->
|
true ->
|
||||||
{true, Attrs, NewStateData};
|
{true, Attrs, StateData};
|
||||||
false ->
|
false ->
|
||||||
case ?SETS:is_element(
|
case ?SETS:is_element(
|
||||||
LFrom, NewStateData#state.pres_f) of
|
LFrom, StateData#state.pres_f) of
|
||||||
true ->
|
true ->
|
||||||
A = ?SETS:add_element(
|
A = ?SETS:add_element(
|
||||||
LFrom,
|
LFrom,
|
||||||
NewStateData#state.pres_a),
|
StateData#state.pres_a),
|
||||||
{true, Attrs,
|
{true, Attrs,
|
||||||
NewStateData#state{pres_a = A}};
|
StateData#state{pres_a = A}};
|
||||||
false ->
|
false ->
|
||||||
case ?SETS:is_element(
|
case ?SETS:is_element(
|
||||||
LBFrom, NewStateData#state.pres_f) of
|
LBFrom, StateData#state.pres_f) of
|
||||||
true ->
|
true ->
|
||||||
A = ?SETS:add_element(
|
A = ?SETS:add_element(
|
||||||
LBFrom,
|
LBFrom,
|
||||||
NewStateData#state.pres_a),
|
StateData#state.pres_a),
|
||||||
{true, Attrs,
|
{true, Attrs,
|
||||||
NewStateData#state{pres_a = A}};
|
StateData#state{pres_a = A}};
|
||||||
false ->
|
false ->
|
||||||
{true, Attrs, NewStateData}
|
{true, Attrs, StateData}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@ -1907,28 +1875,15 @@ is_ip_blacklisted({IP,_Port}) ->
|
|||||||
check_from(El, FromJID) ->
|
check_from(El, FromJID) ->
|
||||||
case exmpp_stanza:get_sender(El) of
|
case exmpp_stanza:get_sender(El) of
|
||||||
undefined ->
|
undefined ->
|
||||||
exmpp_stanza:set_sender(El, FromJID);
|
El;
|
||||||
JIDElString ->
|
SJID ->
|
||||||
try
|
try
|
||||||
JIDEl = exmpp_jid:list_to_jid(JIDElString),
|
JID = exmpp_jid:list_to_jid(SJID),
|
||||||
case JIDEl#jid.lresource of
|
case exmpp_jid:compare_jids(JID, FromJID) of
|
||||||
undefined ->
|
true ->
|
||||||
%% Matching JID: The stanza is ok
|
El;
|
||||||
if JIDEl#jid.lnode == FromJID#jid.lnode andalso
|
false ->
|
||||||
JIDEl#jid.ldomain == FromJID#jid.ldomain ->
|
'invalid-from'
|
||||||
El;
|
|
||||||
true ->
|
|
||||||
'invalid-from'
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
%% Matching JID: The stanza is ok
|
|
||||||
if JIDEl#jid.lnode == FromJID#jid.lnode andalso
|
|
||||||
JIDEl#jid.ldomain == FromJID#jid.ldomain andalso
|
|
||||||
JIDEl#jid.lresource == FromJID#jid.lresource ->
|
|
||||||
El;
|
|
||||||
true ->
|
|
||||||
'invalid-from'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
_:_ ->
|
_:_ ->
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([read_caps/1,
|
-export([read_caps/1,
|
||||||
|
get_caps/1,
|
||||||
note_caps/3,
|
note_caps/3,
|
||||||
|
clear_caps/1,
|
||||||
get_features/2,
|
get_features/2,
|
||||||
handle_disco_response/3]).
|
handle_disco_response/3]).
|
||||||
|
|
||||||
@ -58,6 +60,7 @@
|
|||||||
|
|
||||||
-record(caps, {node, version, exts}).
|
-record(caps, {node, version, exts}).
|
||||||
-record(caps_features, {node_pair, features}).
|
-record(caps_features, {node_pair, features}).
|
||||||
|
-record(user_caps, {jid, caps}).
|
||||||
-record(state, {host,
|
-record(state, {host,
|
||||||
disco_requests = ?DICT:new(),
|
disco_requests = ?DICT:new(),
|
||||||
feature_queries = []}).
|
feature_queries = []}).
|
||||||
@ -80,12 +83,26 @@ read_caps([_ | Tail], Result) ->
|
|||||||
read_caps([], Result) ->
|
read_caps([], Result) ->
|
||||||
Result.
|
Result.
|
||||||
|
|
||||||
|
%% get_caps reads user caps from database
|
||||||
|
get_caps(JID) ->
|
||||||
|
case catch mnesia:dirty_read({user_caps, list_to_binary(exmpp_jid:jid_to_list(JID))}) of
|
||||||
|
[#user_caps{caps=Caps}] ->
|
||||||
|
Caps;
|
||||||
|
_ ->
|
||||||
|
nothing
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% clear_caps removes user caps from database
|
||||||
|
clear_caps(JID) ->
|
||||||
|
catch mnesia:dirty_delete({user_caps, list_to_binary(exmpp_jid:jid_to_list(JID))}).
|
||||||
|
|
||||||
%% note_caps should be called to make the module request disco
|
%% note_caps should be called to make the module request disco
|
||||||
%% information. Host is the host that asks, From is the full JID that
|
%% information. Host is the host that asks, From is the full JID that
|
||||||
%% sent the caps packet, and Caps is what read_caps returned.
|
%% sent the caps packet, and Caps is what read_caps returned.
|
||||||
note_caps(Host, From, Caps) ->
|
note_caps(Host, From, Caps) ->
|
||||||
case Caps of
|
case Caps of
|
||||||
nothing -> ok;
|
nothing ->
|
||||||
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
gen_server:cast(Proc, {note_caps, From, Caps})
|
gen_server:cast(Proc, {note_caps, From, Caps})
|
||||||
@ -129,7 +146,9 @@ init([Host, _Opts]) ->
|
|||||||
mnesia:create_table(caps_features,
|
mnesia:create_table(caps_features,
|
||||||
[{ram_copies, [node()]},
|
[{ram_copies, [node()]},
|
||||||
{attributes, record_info(fields, caps_features)}]),
|
{attributes, record_info(fields, caps_features)}]),
|
||||||
mnesia:add_table_copy(caps_features, node(), ram_copies),
|
mnesia:create_table(user_caps,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes, record_info(fields, user_caps)}]),
|
||||||
{ok, #state{host = Host}}.
|
{ok, #state{host = Host}}.
|
||||||
|
|
||||||
maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
|
maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
|
||||||
@ -177,10 +196,12 @@ handle_call(stop, _From, State) ->
|
|||||||
{stop, normal, ok, State}.
|
{stop, normal, ok, State}.
|
||||||
|
|
||||||
handle_cast({note_caps, From,
|
handle_cast({note_caps, From,
|
||||||
#caps{node = Node, version = Version, exts = Exts}},
|
#caps{node = Node, version = Version, exts = Exts} = Caps},
|
||||||
#state{host = Host, disco_requests = Requests} = State) ->
|
#state{host = Host, disco_requests = Requests} = State) ->
|
||||||
%% XXX: this leads to race conditions where ejabberd will send
|
%% XXX: this leads to race conditions where ejabberd will send
|
||||||
%% lots of caps disco requests.
|
%% lots of caps disco requests.
|
||||||
|
mnesia:dirty_write(#user_caps{jid = list_to_binary(exmpp_jid:jid_to_list(From)),
|
||||||
|
caps = Caps}),
|
||||||
SubNodes = [Version | Exts],
|
SubNodes = [Version | Exts],
|
||||||
%% Now, find which of these are not already in the database.
|
%% Now, find which of these are not already in the database.
|
||||||
Fun = fun() ->
|
Fun = fun() ->
|
||||||
@ -195,11 +216,9 @@ handle_cast({note_caps, From,
|
|||||||
end,
|
end,
|
||||||
case mnesia:transaction(Fun) of
|
case mnesia:transaction(Fun) of
|
||||||
{atomic, Missing} ->
|
{atomic, Missing} ->
|
||||||
%% For each unknown caps "subnode", we send a disco
|
%% For each unknown caps "subnode", we send a disco request.
|
||||||
%% request.
|
NewRequests = lists:foldl(
|
||||||
NewRequests =
|
fun(SubNode, Dict) ->
|
||||||
lists:foldl(
|
|
||||||
fun(SubNode, Dict) ->
|
|
||||||
ID = randoms:get_string(),
|
ID = randoms:get_string(),
|
||||||
Query = exmpp_xml:set_attribute(
|
Query = exmpp_xml:set_attribute(
|
||||||
#xmlel{ns = ?NS_DISCO_INFO, name = 'query'},
|
#xmlel{ns = ?NS_DISCO_INFO, name = 'query'},
|
||||||
|
@ -480,9 +480,9 @@ handle_cast({presence, JID, Pid}, State) ->
|
|||||||
case catch ejabberd_c2s:get_subscribed(Pid) of
|
case catch ejabberd_c2s:get_subscribed(Pid) of
|
||||||
Contacts when is_list(Contacts) ->
|
Contacts when is_list(Contacts) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({{User, Server, _}, _}) ->
|
fun({User, Server, _}) ->
|
||||||
Owner = {User, Server, undefined},
|
Owner = {User, Server, undefined},
|
||||||
lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options} = PN) ->
|
lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) ->
|
||||||
case get_option(Options, send_last_published_item) of
|
case get_option(Options, send_last_published_item) of
|
||||||
on_sub_and_presence ->
|
on_sub_and_presence ->
|
||||||
case is_caps_notify(ServerHost, Node, LJID) of
|
case is_caps_notify(ServerHost, Node, LJID) of
|
||||||
|
Loading…
Reference in New Issue
Block a user