]> granicus.if.org Git - ejabberd/commitdiff
*** empty log message ***
authorAlexey Shchepin <alexey@process-one.net>
Sat, 30 Nov 2002 18:46:16 +0000 (18:46 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Sat, 30 Nov 2002 18:46:16 +0000 (18:46 +0000)
SVN Revision: 10

src/ejabberd.erl
src/ejabberd_c2s.erl
src/ejabberd_local.erl [new file with mode: 0644]
src/ejabberd_router.erl
src/ejabberd_sm.erl
src/jlib.erl

index 34cabc42da3acf06c00662a90c4a6ee07f3f3002..c0d164c9fe0738d431bd3b315f25a1f2512e57cf 100644 (file)
@@ -25,6 +25,7 @@ init() ->
     ejabberd_auth:start(),
     ejabberd_router:start(),
     ejabberd_sm:start(),
+    ejabberd_local:start(),
     ejabberd_listener:start(),
     loop(Port).
 
index d8855b1660724207d9c623b56fe2753e3056ffd8..f536fe32c5f5106ec906895ccb3c8a702ffe9e93 100644 (file)
 -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)).
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
new file mode 100644 (file)
index 0000000..4241088
--- /dev/null
@@ -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.
+
index 1706eace579ca51b5b899a2124ae81beb0f517cd..9ab3d1810fec147998eeaf3aab4d1627ea821e4d 100644 (file)
 -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()}.
+
index 16505948cc27e25a713ad65b2a50d1bea57905e6..e9f51f992fb2b2eccccf2cef46170936e7381da8 100644 (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.
+
index b301378c8ffcd06bb620fd5665f2091d199cd5a9..b1262e0ef64adaac47358ad147cb09a30db84492 100644 (file)
 -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 ->