diff --git a/src/ejabberd.erl b/src/ejabberd.erl index eb4459d15..c2845cebe 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -19,6 +19,7 @@ start() -> init() -> register(ejabberd, self()), + erlang:system_flag(fullsweep_after, 0), error_logger:logfile({open, ?ERROR_LOG_PATH}), randoms:start(), ok = erl_ddll:load_driver(".", expat_erl), diff --git a/src/ejabberd.hrl b/src/ejabberd.hrl index 4df15d6e8..13dd063bd 100644 --- a/src/ejabberd.hrl +++ b/src/ejabberd.hrl @@ -16,6 +16,10 @@ -define(DEBUG(F,A),[]). -endif. +-define(ERROR_MSG(Format, Args), + error_logger:format("D(~p:~p:~p) : "++Format++"~n", + [self(),?MODULE,?LINE]++Args)). + %-define(MYNAME,"e.localhost"). -define(MYNAME, ejabberd_config:get_option(host)). diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index c2e75b16a..54c94889d 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -111,9 +111,12 @@ wait_for_stream(closed, StateData) -> wait_for_auth({xmlstreamelement, El}, StateData) -> case is_auth_packet(El) of + {auth, ID, {U, P, D, ""}} -> + Err = jlib:make_error_reply(El, "406", "Not Acceptable"), + send_element(StateData#state.sender, Err), + {next_state, wait_for_auth, StateData}; {auth, ID, {U, P, D, R}} -> io:format("AUTH: ~p~n", [{U, P, D, R}]), - % TODO: digested password case ejabberd_auth:check_password(U, P, StateData#state.streamid, D) of true -> diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index a03209e87..b7e949eef 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -26,6 +26,7 @@ start() -> mod_stats:start(), mod_vcard:start(), mod_offline:start(), + mod_echo:start(), ok. init() -> diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 1eb72773b..1dfab8562 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -46,8 +46,12 @@ init() -> loop() -> receive {route, From, To, Packet} -> - % TODO - do_route(From, To, Packet), + case catch do_route(From, To, Packet) of + {'EXIT', Reason} -> + ?ERROR_MSG("~p", [Reason]); + _ -> + ok + end, loop(); {register_route, Domain, Pid, Node} -> F = fun() -> @@ -95,37 +99,56 @@ 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, - 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}; - _ -> + case mnesia:dirty_read({local_route, DstDomain}) of + [] -> + case mnesia:dirty_read({route, DstDomain}) of + [] -> + ejabberd_s2s ! {route, From, To, Packet}; + [R] -> + Node = R#route.node, ?DEBUG("routed to node ~p~n", [Node]), {ejabberd_router, Node} ! {route, From, To, Packet} end; - _ -> - % TODO - error + [R] -> + Pid = R#local_route.pid, + ?DEBUG("routed to process ~p~n", [Pid]), + Pid ! {route, From, To, Packet} end. diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 95166445b..04b941656 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -47,6 +47,14 @@ init() -> loop() -> receive + {route, From, To, Packet} -> + case catch do_route(From, To, Packet) of + {'EXIT', Reason} -> + ?ERROR_MSG("~p", [Reason]); + _ -> + ok + end, + loop(); {open_session, User, Resource, From} -> replace_and_register_my_connection(User, Resource, From), replace_alien_connection(User, Resource), @@ -60,9 +68,6 @@ loop() -> {mnesia_system_event, {mnesia_down, Node}} -> clean_table_from_bad_node(Node), loop(); - {route, From, To, Packet} -> - do_route(From, To, Packet), - loop(); {register_iq_handler, XMLNS, Module, Function} -> ets:insert(sm_iqtable, {XMLNS, Module, Function}), loop(); @@ -160,25 +165,115 @@ 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", [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 "" -> @@ -240,26 +335,27 @@ do_route(From, To, Packet) -> 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} -> + UR = {User, Resource}, + Sess = mnesia:dirty_read({session, UR}), + case Sess of + [] -> 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; + [Ses] -> + case mnesia:dirty_read({mysession, UR}) of + [] -> + Node = Ses#session.node, + ?DEBUG("sending to node ~p~n", [Node]), + {ejabberd_sm, Node} ! {route, From, To, Packet}; + [El] -> + Pid = El#mysession.pid, + ?DEBUG("sending to process ~p~n", [Pid]), + Pid ! {route, From, To, Packet} + end end end. diff --git a/src/mod_echo.erl b/src/mod_echo.erl new file mode 100644 index 000000000..06266dd0c --- /dev/null +++ b/src/mod_echo.erl @@ -0,0 +1,35 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_echo.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 15 Jan 2003 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_echo). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([start/0, init/0]). + +-include("ejabberd.hrl"). +-include("namespaces.hrl"). + + + +start() -> + spawn(?MODULE, init, []). + +init() -> + ejabberd_router:register_local_route("echo." ++ ?MYNAME), + loop(). + +loop() -> + receive + {route, From, To, Packet} -> + ejabberd_router:route(To, From, Packet), + loop(); + _ -> + loop() + end. + diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index ff341a99b..0b2c8d443 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -370,16 +370,25 @@ record_to_item(R) -> search(Data) -> MatchSpec = make_matchspec(Data), - F = fun() -> - mnesia:select(vcard_search, [{MatchSpec, [], ['$_']}]) - end, - case mnesia:transaction(F) of - {atomic, Rs} -> - Rs; - _ -> - [] + case catch mnesia:dirty_select(vcard_search, [{MatchSpec, [], ['$_']}]) of + {'EXIT', Reason} -> + ?ERROR_MSG("~p", [Reason]), + []; + Rs -> + Rs end. +% TODO: remove +% F = fun() -> +% mnesia:select(vcard_search, [{MatchSpec, [], ['$_']}]) +% end, +% case mnesia:transaction(F) of +% {atomic, Rs} -> +% Rs; +% _ -> +% [] +% end. + make_matchspec(Data) -> GlobMatch = #vcard_search{_ = '_'},