*** empty log message ***

SVN Revision: 10
This commit is contained in:
Alexey Shchepin 2002-11-30 18:46:16 +00:00
parent 9fdf316aab
commit 206b5cd2fb
6 changed files with 240 additions and 17 deletions

View File

@ -25,6 +25,7 @@ init() ->
ejabberd_auth:start(),
ejabberd_router:start(),
ejabberd_sm:start(),
ejabberd_local:start(),
ejabberd_listener:start(),
loop(Port).

View File

@ -13,13 +13,14 @@
-behaviour(gen_fsm).
%% External exports
-export([start/1, receiver/2, sender/1, send_text/2]).
-export([start/1, receiver/2, sender/1, send_text/2, send_element/2]).
%% gen_fsm callbacks
%-export([init/1, state_name/2, state_name/3, handle_event/3,
% handle_sync_event/4, handle_info/3, terminate/3]).
%
-export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2,
handle_info/3,
terminate/3]).
-record(state, {socket, sender, receiver, streamid,
@ -106,6 +107,9 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
case ejabberd_auth:check_password(U, P) of
true ->
% TODO
ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El),
send_element(StateData#state.sender, Res),
{next_state, session_established,
StateData#state{user = U, resource = R}};
_ ->
@ -127,9 +131,24 @@ wait_for_auth(closed, StateData) ->
session_established({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El,
% TODO
FromJID = {StateData#state.user, "localhost", StateData#state.resource},
ToJID = jlib:string_to_jid(xml:get_attr_s("to", Attrs)),
ejabberd_router:route(FromJID, ToJID, El),
FromJID = {StateData#state.user,
StateData#state.server,
StateData#state.resource},
To = xml:get_attr_s("to", Attrs),
ToJID = case To of
"" ->
{"", StateData#state.server, ""};
_ ->
jlib:string_to_jid(To)
end,
case ToJID of
error ->
% TODO
error;
_ ->
%?DEBUG("FromJID=~w, ToJID=~w, El=~w~n", [FromJID, ToJID, El]),
ejabberd_router:route(FromJID, ToJID, El)
end,
{next_state, session_established, StateData};
session_established(closed, StateData) ->
@ -179,7 +198,8 @@ handle_sync_event(Event, From, StateName, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_info(Info, StateName, StateData) ->
handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.sender, Text),
{next_state, StateName, StateData}.
%%----------------------------------------------------------------------
@ -188,6 +208,13 @@ handle_info(Info, StateName, StateData) ->
%% Returns: any
%%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) ->
case StateData#state.user of
"" ->
ok;
_ ->
ejabberd_sm:close_session(StateData#state.user,
StateData#state.resource)
end,
StateData#state.sender ! close,
ok.
@ -212,7 +239,7 @@ receiver(Socket, C2SPid, XMLStreamPid) ->
sender(Socket) ->
receive
{text, Text} ->
{send_text, Text} ->
gen_tcp:send(Socket,Text),
sender(Socket);
close ->
@ -221,7 +248,7 @@ sender(Socket) ->
end.
send_text(Pid, Text) ->
Pid ! {text, Text}.
Pid ! {send_text, Text}.
send_element(Pid, El) ->
send_text(Pid, xml:element_to_string(El)).

45
src/ejabberd_local.erl Normal file
View File

@ -0,0 +1,45 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_local.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose :
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$
%%%----------------------------------------------------------------------
-module(ejabberd_local).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
%%-export([Function/Arity, ...]).
-export([start/0,init/0]).
-include("ejabberd.hrl").
start() ->
spawn(ejabberd_local, init, []).
init() ->
ejabberd_router:register_local_route("localhost"),
loop().
loop() ->
receive
{route, From, To, Packet} ->
do_route(From, To, Packet),
loop()
end.
do_route(From, To, Packet) ->
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
case To of
{"", _, _} ->
ok;
_ ->
ejabberd_sm ! {route, From, To, Packet}
end,
ok.

View File

@ -10,13 +10,14 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([route/3]).
-export([route/3, register_route/1, register_local_route/1]).
-export([start/0, init/0]).
-include("ejabberd.hrl").
-record(route, {domain, node, pid}).
-record(local_route, {domain, pid}).
start() ->
@ -28,6 +29,11 @@ init() ->
[{ram_copies, [node()]},
{attributes,
record_info(fields, route)}]),
mnesia:create_table(local_route,
[{ram_copies, [node()]},
{local_content, true},
{attributes,
record_info(fields, local_route)}]),
loop().
loop() ->
@ -51,6 +57,13 @@ loop() ->
end,
mnesia:transaction(F),
loop();
{register_local_route, Domain, Pid} ->
F = fun() ->
mnesia:write(#local_route{domain = Domain,
pid = Pid})
end,
mnesia:transaction(F),
loop();
{unregister_route, Domain} ->
F = fun() ->
case mnesia:wread({route, Domain}) of
@ -73,11 +86,16 @@ 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({route, DstDomain}) of
case mnesia:read({local_route, DstDomain}) of
[] ->
error;
case mnesia:read({route, DstDomain}) of
[] ->
error;
[R] ->
{ok, R#route.node, R#route.pid}
end;
[R] ->
{ok, R#route.node, R#route.pid}
{ok, node(), R#local_route.pid}
end
end,
case mnesia:transaction(F) of
@ -89,11 +107,18 @@ do_route(From, To, Packet) ->
ok;
_ ->
Err = jlib:make_error_reply(Packet,
502, "Service Unavailable"),
"502", "Service Unavailable"),
ejabberd_router ! {route, To, From, Err}
end;
{atomic, {ok, Node, Pid}} ->
{Pid, Node} ! {packet, From, To, Packet};
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
@ -103,3 +128,9 @@ do_route(From, To, Packet) ->
route(From, To, Packet) ->
ejabberd_router ! {route, From, To, Packet}.
register_route(Domain) ->
ejabberd_router ! {register_route, Domain, self(), node()}.
register_local_route(Domain) ->
ejabberd_router ! {register_local_route, Domain, self()}.

View File

@ -8,10 +8,12 @@
-module(ejabberd_sm).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/0, open_session/2]).
-export([start/0, init/0, open_session/2, close_session/2]).
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("ejabberd.hrl").
-record(user_resource, {id, user, resource}).
-record(user_resource_id_seq, {name = value, id}).
@ -43,6 +45,7 @@ init() ->
{local_content, true},
{attributes, record_info(fields, mysession)}]),
mnesia:subscribe(system),
%ejabberd_router:register_local_route("localhost"),
loop().
loop() ->
@ -51,12 +54,18 @@ loop() ->
replace_and_register_my_connection(User, Resource, From),
replace_alien_connection(User, Resource),
loop();
{close_session, User, Resource} ->
remove_connection(User, Resource),
loop();
{replace, User, Resource} ->
replace_my_connection(User, Resource),
loop();
{mnesia_system_event, {mnesia_down, Node}} ->
clean_table_from_bad_node(Node),
loop();
{route, From, To, Packet} ->
do_route(From, To, Packet),
loop();
_ ->
loop()
end.
@ -65,6 +74,9 @@ loop() ->
open_session(User, Resource) ->
ejabberd_sm ! {open_session, User, Resource, self()}.
close_session(User, Resource) ->
ejabberd_sm ! {close_session, User, Resource}.
replace_alien_connection(User, Resource) ->
F = fun() ->
[ID] = mnemosyne:eval(query [X.id || X <- table(user_resource),
@ -112,6 +124,19 @@ replace_my_connection(User, Resource) ->
false
end.
remove_connection(User, Resource) ->
F = fun() ->
[ID] = mnemosyne:eval(query [X.id || X <- table(user_resource),
X.user = User,
X.resource = Resource]
end),
mnesia:delete({mysession, ID}),
mnesia:delete({session, ID}),
mnesia:delete({user_resource, ID})
end,
mnesia:transaction(F).
replace_and_register_my_connection(User, Resource, Pid) ->
F = fun() ->
IDs = mnemosyne:eval(query [X.id || X <- table(user_resource),
@ -169,3 +194,50 @@ init_seq() ->
end,
mnesia:transaction(F).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
do_route(From, To, Packet) ->
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
{User, _, Resource} = To,
F = fun() ->
IDs = mnemosyne:eval(query [X.id || X <- table(user_resource),
X.user = User,
X.resource = Resource]
end),
case IDs of
[] ->
not_exists;
[ID] ->
case mnesia:read({mysession, ID}) of
[] ->
[Er] = mnesia:read({session, ID}),
{remote, Er#session.node};
[El] ->
{local, (El#mysession.info)#mysession_info.pid}
end
end
end,
case mnesia:transaction(F) of
{atomic, {local, Pid}} ->
?DEBUG("sending to process ~p~n", [Pid]),
% TODO
{xmlelement, Name, Attrs, Els} = Packet,
NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
jlib:jid_to_string(To),
Attrs),
ejabberd_c2s:send_element(Pid, {xmlelement, Name, NewAttrs, Els}),
?DEBUG("sended~n", []),
ok;
{atomic, {remote, Node}} ->
?DEBUG("sending to node ~p~n", [Node]),
{ejabberd_sm, Node} ! {route, From, To, Packet},
ok;
{atomic, not_exists} ->
?DEBUG("packet droped~n", []),
ok;
{aborted, Reason} ->
?DEBUG("delivery failed: ~p~n", [Reason]),
false
end.

View File

@ -10,13 +10,43 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([make_error_reply/3, make_correct_from_to_attrs/3,
replace_from_to_attrs/3, string_to_jid/1, tolower/1]).
-export([make_result_iq_reply/1,
make_error_reply/3,
make_correct_from_to_attrs/3,
replace_from_to_attrs/3,
string_to_jid/1,
jid_to_string/1,
tolower/1]).
%send_iq(From, To, ID, SubTags) ->
% ok.
make_result_iq_reply({xmlelement, Name, Attrs, SubTags}) ->
NewAttrs = make_result_iq_reply_attrs(Attrs),
{xmlelement, Name, NewAttrs, SubTags}.
make_result_iq_reply_attrs(Attrs) ->
To = xml:get_attr("to", Attrs),
From = xml:get_attr("from", Attrs),
Attrs1 = lists:keydelete("to", 1, Attrs),
Attrs2 = lists:keydelete("from", 1, Attrs1),
Attrs3 = case To of
{value, ToVal} ->
[{"from", ToVal} | Attrs2];
_ ->
Attrs2
end,
Attrs4 = case From of
{value, FromVal} ->
[{"to", FromVal} | Attrs3];
_ ->
Attrs3
end,
Attrs5 = lists:keydelete("type", 1, Attrs4),
Attrs6 = [{"type", "result"} | Attrs5],
Attrs6.
make_error_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) ->
NewAttrs = make_error_reply_attrs(Attrs),
{xmlelement, Name, NewAttrs, SubTags ++ [{xmlelement, "error",
@ -56,7 +86,7 @@ make_correct_from_to_attrs(From, To, Attrs) ->
Attrs3.
replace_from_to_attrs(From,To,Attrs) ->
replace_from_to_attrs(From, To, Attrs) ->
Attrs1 = lists:keydelete("to", 1, Attrs),
Attrs2 = lists:keydelete("from", 1, Attrs1),
Attrs3 = [{"to", To} | Attrs2],
@ -98,6 +128,23 @@ string_to_jid3([C | J], N, S, R) ->
string_to_jid3([], N, S, R) ->
{N, S, lists:reverse(R)}.
jid_to_string({Node, Server, Resource}) ->
S1 = case Node of
"" ->
"";
_ ->
Node ++ "@"
end,
S2 = S1 ++ Server,
S3 = case Resource of
"" ->
S2;
_ ->
S2 ++ "/" ++ Resource
end,
S3.
% TODO: UNICODE support
tolower_c(C) when C >= $A, C =< $Z ->