mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
*** empty log message ***
SVN Revision: 10
This commit is contained in:
parent
9fdf316aab
commit
206b5cd2fb
@ -25,6 +25,7 @@ init() ->
|
||||
ejabberd_auth:start(),
|
||||
ejabberd_router:start(),
|
||||
ejabberd_sm:start(),
|
||||
ejabberd_local:start(),
|
||||
ejabberd_listener:start(),
|
||||
loop(Port).
|
||||
|
||||
|
@ -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
45
src/ejabberd_local.erl
Normal 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.
|
||||
|
@ -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()}.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
53
src/jlib.erl
53
src/jlib.erl
@ -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 ->
|
||||
|
Loading…
Reference in New Issue
Block a user