]> granicus.if.org Git - ejabberd/commitdiff
Locate sessions by proxy processes directly
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Thu, 1 May 2014 09:27:35 +0000 (13:27 +0400)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 2 May 2014 13:31:17 +0000 (17:31 +0400)
src/mod_sip.erl
src/mod_sip_proxy.erl
src/mod_sip_registrar.erl

index cca91a33d57d27da792181337701ae308c7d645a..87608d18e0f20e70898c9833486a6f869f2c7f3b 100644 (file)
@@ -13,7 +13,7 @@
 
 %% API
 -export([start/2, stop/1, prepare_request/1, make_response/2,
-        add_certfile/2, add_via/3]).
+        add_via/3, at_my_host/1]).
 
 %% esip_callbacks
 -export([data_in/2, data_out/2, message_in/2, message_out/2,
 -include("logger.hrl").
 -include("esip.hrl").
 
--record(sip_session, {us = {<<"">>, <<"">>} :: {binary(), binary()},
-                     socket = #sip_socket{},
-                     timestamp = now() :: erlang:timestamp(),
-                     tref = make_ref() :: reference(),
-                     expires = 0 :: non_neg_integer()}).
-
 %%%===================================================================
 %%% API
 %%%===================================================================
@@ -70,7 +64,7 @@ data_out(Data, #sip_socket{type = Transport,
 message_in(#sip{type = request, method = M} = Req, SIPSock)
   when M /= <<"ACK">>, M /= <<"CANCEL">> ->
     case action(Req, SIPSock) of
-        {relay, _LServer, _Opts} ->
+        {relay, _LServer} ->
             ok;
         Action ->
             request(Req, SIPSock, undefined, Action)
@@ -83,66 +77,26 @@ message_out(_, _) ->
 
 response(Resp, SIPSock) ->
     case action(Resp, SIPSock) of
-        {relay, LServer, Opts} ->
+        {relay, LServer} ->
             case esip:split_hdrs('via', Resp#sip.hdrs) of
                 {[_], _} ->
                     ok;
                 {[_MyVia|Vias], TailHdrs} ->
                    %% TODO: check if MyVia is really my Via
                    NewResp = Resp#sip{hdrs = [{'via', Vias}|TailHdrs]},
-                   case proplists:get_value(socket, Opts) of
-                       undefined ->
-                           case esip:connect(NewResp,
-                                             add_certfile(LServer, Opts)) of
-                               {ok, SIPSockOut} ->
-                                   esip:send(SIPSockOut, NewResp);
-                               {error, _} ->
-                                   ok
-                           end;
-                       SIPSockOut ->
-                           esip:send(SIPSockOut, NewResp)
+                   case esip:connect(NewResp, add_certfile(LServer, [])) of
+                       {ok, SIPSockOut} ->
+                           esip:send(SIPSockOut, NewResp);
+                       {error, _} ->
+                           ok
                    end
             end;
         _ ->
             ok
     end.
 
-request(#sip{method = <<"ACK">>} = Req, SIPSock) ->
-    case action(Req, SIPSock) of
-        {relay, LServer, Opts} ->
-           Req1 = prepare_request(Req),
-           case esip:connect(Req1, add_certfile(LServer, Opts)) of
-               {ok, SIPSockOut} ->
-                   Req2 = add_via(SIPSockOut, LServer, Req1),
-                   esip:send(SIPSockOut, Req2);
-               {error, _} = Err ->
-                   Err
-           end;
-        _ ->
-            pass
-    end;
-request(#sip{method = <<"CANCEL">>} = Req, SIPSock) ->
-    case action(Req, SIPSock) of
-        loop ->
-            make_response(Req, #sip{status = 483, type = response});
-        {unsupported, Require} ->
-            make_response(Req, #sip{status = 420,
-                                    type = response,
-                                    hdrs = [{'unsupported',
-                                             Require}]});
-        {relay, LServer, Opts} ->
-           Req1 = prepare_request(Req),
-           case esip:connect(Req1, add_certfile(LServer, Opts)) of
-               {ok, SIPSockOut} ->
-                   Req2 = add_via(SIPSockOut, LServer, Req1),
-                   esip:send(SIPSockOut, Req2);
-               {error, _} = Err ->
-                   Err
-           end,
-            pass;
-        _ ->
-            pass
-    end.
+request(_Req, _SIPSock) ->
+    error.
 
 request(Req, SIPSock, TrID) ->
     request(Req, SIPSock, TrID, action(Req, SIPSock)).
@@ -160,8 +114,8 @@ request(Req, SIPSock, TrID, Action) ->
                                     type = response,
                                     hdrs = [{'unsupported',
                                              Require}]});
-        {relay, LServer, Opts} ->
-            case mod_sip_proxy:start(LServer, Opts) of
+        {relay, LServer} ->
+            case mod_sip_proxy:start(LServer, add_certfile(LServer, [])) of
                 {ok, Pid} ->
                     mod_sip_proxy:route(Req, SIPSock, TrID, Pid),
                     {mod_sip_proxy, route, [Pid]};
@@ -194,17 +148,6 @@ request(Req, SIPSock, TrID, Action) ->
 locate(_SIPMsg) ->
     ok.
 
-find(#uri{user = User, host = Host}) ->
-    LUser = jlib:nodeprep(User),
-    LServer = jlib:nameprep(Host),
-    case mod_sip_registrar:find_session(
-          LUser, LServer) of
-       {ok, #sip_session{socket = Sock}} ->
-           {relay, LServer, [{socket, Sock}]};
-       error ->
-           not_found
-    end.
-
 %%%===================================================================
 %%% Internal functions
 %%%===================================================================
@@ -215,15 +158,24 @@ action(#sip{type = response, hdrs = Hdrs}, _SIPSock) ->
        true ->
            case at_my_host(ToURI) of
                true ->
-                   find(ToURI);
+                   case ToURI#uri.user of
+                       <<"">> ->
+                           to_me;
+                       _ ->
+                           {relay, jlib:nameprep(ToURI#uri.host)}
+                   end;
                false ->
-                   LServer = jlib:nameprep(FromURI#uri.host),
-                   {relay, LServer, []}
+                   {relay, jlib:nameprep(FromURI#uri.host)}
            end;
        false ->
            case at_my_host(ToURI) of
                true ->
-                   find(ToURI);
+                   case ToURI#uri.user of
+                       <<"">> ->
+                           to_me;
+                       _ ->
+                           {relay, jlib:nameprep(ToURI#uri.host)}
+                   end;
                false ->
                    pass
            end
@@ -271,10 +223,16 @@ action(#sip{method = Method, hdrs = Hdrs, type = request} = Req, SIPSock) ->
                                 true ->
                                    case at_my_host(ToURI) of
                                        true ->
-                                           find(ToURI);
+                                           case ToURI#uri.user of
+                                               <<"">> ->
+                                                   to_me;
+                                               _ ->
+                                                   LServer = jlib:nameprep(ToURI#uri.host),
+                                                   {relay, LServer}
+                                           end;
                                        false ->
                                            LServer = jlib:nameprep(FromURI#uri.host),
-                                           {relay, LServer, []}
+                                           {relay, LServer}
                                    end;
                                 false ->
                                     {proxy_auth, FromURI#uri.host}
@@ -282,7 +240,13 @@ action(#sip{method = Method, hdrs = Hdrs, type = request} = Req, SIPSock) ->
                        false ->
                            case at_my_host(ToURI) of
                                true ->
-                                   find(ToURI);
+                                   case ToURI#uri.user of
+                                       <<"">> ->
+                                           to_me;
+                                       _ ->
+                                           LServer = jlib:nameprep(ToURI#uri.host),
+                                           {relay, LServer}
+                                   end;
                                false ->
                                    deny
                            end
index aa749ccf7f029650750cdfcd479da68be436a174..ef2192a207d666bc34ee837df0651f481dcdc4b6 100644 (file)
@@ -23,8 +23,6 @@
 -include("logger.hrl").
 -include("esip.hrl").
 
--define(MAX_REDIRECTS, 5).
-
 -record(state, {host = <<"">> :: binary(),
                opts = []     :: [{certfile, binary()}],
                orig_trid,
@@ -54,7 +52,7 @@ init([Host, Opts]) ->
     {ok, wait_for_request, #state{opts = Opts, host = Host}}.
 
 wait_for_request({#sip{type = request} = Req, TrID}, State) ->
-    Opts = mod_sip:add_certfile(State#state.host, State#state.opts),
+    Opts = State#state.opts,
     Req1 = mod_sip:prepare_request(Req),
     case connect(Req1, Opts) of
        {ok, SIPSocket} ->
@@ -73,6 +71,12 @@ wait_for_request({#sip{type = request} = Req, TrID}, State) ->
                                                 reason = Reason})),
                    {stop, normal, State}
            end;
+       {error, notfound} ->
+           esip:reply(TrID, mod_sip:make_response(
+                              Req, #sip{type = response,
+                                        status = 480,
+                                        reason = esip:reason(480)})),
+           {stop, normal, State};
        Err ->
            {Status, Reason} = esip:error_status(Err),
            esip:reply(TrID, mod_sip:make_response(
@@ -143,10 +147,18 @@ code_change(_OldVsn, StateName, State, _Extra) ->
 %%%===================================================================
 %%% Internal functions
 %%%===================================================================
-connect(Req, Opts) ->
-    case proplists:get_value(socket, Opts) of
-       undefined ->
-           esip:connect(Req, Opts);
-       #sip_socket{} = SIPSock ->
-           {ok, SIPSock}
+connect(#sip{hdrs = Hdrs} = Req, Opts) ->
+    {_, ToURI, _} = esip:get_hdr('to', Hdrs),
+    case mod_sip:at_my_host(ToURI) of
+       true ->
+           LUser = jlib:nodeprep(ToURI#uri.user),
+           LServer = jlib:nameprep(ToURI#uri.host),
+           case mod_sip_registrar:find_socket(LUser, LServer) of
+               {ok, SIPSock} ->
+                   {ok, SIPSock};
+               error ->
+                   {error, notfound}
+           end;
+       false ->
+           esip:connect(Req, Opts)
     end.
index d8f485fef9385afe2f6ff850837c9e62ebb47f1b..6c945e5ec011c4451aed01b980c0ec34ff2d9fdd 100644 (file)
@@ -12,7 +12,7 @@
 -behaviour(?GEN_SERVER).
 
 %% API
--export([start_link/0, request/2, find_session/2]).
+-export([start_link/0, request/2, find_socket/2]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -97,10 +97,10 @@ request(#sip{hdrs = Hdrs} = Req, SIPSock) ->
             mod_sip:make_response(Req, #sip{type = response, status = 400})
     end.
 
-find_session(U, S) ->
+find_socket(U, S) ->
     case mnesia:dirty_read(sip_session, {U, S}) of
-       [Session] ->
-           {ok, Session};
+       [#sip_session{socket = SIPSocket}] ->
+           {ok, SIPSocket};
        [] ->
            error
     end.