26
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-26 17:38:45 +01:00

Locate sessions by proxy processes directly

This commit is contained in:
Evgeniy Khramtsov 2014-05-01 13:27:35 +04:00
parent a6fe7425dd
commit 35faffe7da
3 changed files with 65 additions and 89 deletions

View File

@ -13,7 +13,7 @@
%% API %% API
-export([start/2, stop/1, prepare_request/1, make_response/2, -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 %% esip_callbacks
-export([data_in/2, data_out/2, message_in/2, message_out/2, -export([data_in/2, data_out/2, message_in/2, message_out/2,
@ -23,12 +23,6 @@
-include("logger.hrl"). -include("logger.hrl").
-include("esip.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 %%% API
%%%=================================================================== %%%===================================================================
@ -70,7 +64,7 @@ data_out(Data, #sip_socket{type = Transport,
message_in(#sip{type = request, method = M} = Req, SIPSock) message_in(#sip{type = request, method = M} = Req, SIPSock)
when M /= <<"ACK">>, M /= <<"CANCEL">> -> when M /= <<"ACK">>, M /= <<"CANCEL">> ->
case action(Req, SIPSock) of case action(Req, SIPSock) of
{relay, _LServer, _Opts} -> {relay, _LServer} ->
ok; ok;
Action -> Action ->
request(Req, SIPSock, undefined, Action) request(Req, SIPSock, undefined, Action)
@ -83,66 +77,26 @@ message_out(_, _) ->
response(Resp, SIPSock) -> response(Resp, SIPSock) ->
case action(Resp, SIPSock) of case action(Resp, SIPSock) of
{relay, LServer, Opts} -> {relay, LServer} ->
case esip:split_hdrs('via', Resp#sip.hdrs) of case esip:split_hdrs('via', Resp#sip.hdrs) of
{[_], _} -> {[_], _} ->
ok; ok;
{[_MyVia|Vias], TailHdrs} -> {[_MyVia|Vias], TailHdrs} ->
%% TODO: check if MyVia is really my Via %% TODO: check if MyVia is really my Via
NewResp = Resp#sip{hdrs = [{'via', Vias}|TailHdrs]}, NewResp = Resp#sip{hdrs = [{'via', Vias}|TailHdrs]},
case proplists:get_value(socket, Opts) of case esip:connect(NewResp, add_certfile(LServer, [])) of
undefined -> {ok, SIPSockOut} ->
case esip:connect(NewResp, esip:send(SIPSockOut, NewResp);
add_certfile(LServer, Opts)) of {error, _} ->
{ok, SIPSockOut} -> ok
esip:send(SIPSockOut, NewResp);
{error, _} ->
ok
end;
SIPSockOut ->
esip:send(SIPSockOut, NewResp)
end end
end; end;
_ -> _ ->
ok ok
end. end.
request(#sip{method = <<"ACK">>} = Req, SIPSock) -> request(_Req, _SIPSock) ->
case action(Req, SIPSock) of error.
{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, TrID) -> request(Req, SIPSock, TrID) ->
request(Req, SIPSock, TrID, action(Req, SIPSock)). request(Req, SIPSock, TrID, action(Req, SIPSock)).
@ -160,8 +114,8 @@ request(Req, SIPSock, TrID, Action) ->
type = response, type = response,
hdrs = [{'unsupported', hdrs = [{'unsupported',
Require}]}); Require}]});
{relay, LServer, Opts} -> {relay, LServer} ->
case mod_sip_proxy:start(LServer, Opts) of case mod_sip_proxy:start(LServer, add_certfile(LServer, [])) of
{ok, Pid} -> {ok, Pid} ->
mod_sip_proxy:route(Req, SIPSock, TrID, Pid), mod_sip_proxy:route(Req, SIPSock, TrID, Pid),
{mod_sip_proxy, route, [Pid]}; {mod_sip_proxy, route, [Pid]};
@ -194,17 +148,6 @@ request(Req, SIPSock, TrID, Action) ->
locate(_SIPMsg) -> locate(_SIPMsg) ->
ok. 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 %%% Internal functions
%%%=================================================================== %%%===================================================================
@ -215,15 +158,24 @@ action(#sip{type = response, hdrs = Hdrs}, _SIPSock) ->
true -> true ->
case at_my_host(ToURI) of case at_my_host(ToURI) of
true -> true ->
find(ToURI); case ToURI#uri.user of
<<"">> ->
to_me;
_ ->
{relay, jlib:nameprep(ToURI#uri.host)}
end;
false -> false ->
LServer = jlib:nameprep(FromURI#uri.host), {relay, jlib:nameprep(FromURI#uri.host)}
{relay, LServer, []}
end; end;
false -> false ->
case at_my_host(ToURI) of case at_my_host(ToURI) of
true -> true ->
find(ToURI); case ToURI#uri.user of
<<"">> ->
to_me;
_ ->
{relay, jlib:nameprep(ToURI#uri.host)}
end;
false -> false ->
pass pass
end end
@ -271,10 +223,16 @@ action(#sip{method = Method, hdrs = Hdrs, type = request} = Req, SIPSock) ->
true -> true ->
case at_my_host(ToURI) of case at_my_host(ToURI) of
true -> true ->
find(ToURI); case ToURI#uri.user of
<<"">> ->
to_me;
_ ->
LServer = jlib:nameprep(ToURI#uri.host),
{relay, LServer}
end;
false -> false ->
LServer = jlib:nameprep(FromURI#uri.host), LServer = jlib:nameprep(FromURI#uri.host),
{relay, LServer, []} {relay, LServer}
end; end;
false -> false ->
{proxy_auth, FromURI#uri.host} {proxy_auth, FromURI#uri.host}
@ -282,7 +240,13 @@ action(#sip{method = Method, hdrs = Hdrs, type = request} = Req, SIPSock) ->
false -> false ->
case at_my_host(ToURI) of case at_my_host(ToURI) of
true -> true ->
find(ToURI); case ToURI#uri.user of
<<"">> ->
to_me;
_ ->
LServer = jlib:nameprep(ToURI#uri.host),
{relay, LServer}
end;
false -> false ->
deny deny
end end

View File

@ -23,8 +23,6 @@
-include("logger.hrl"). -include("logger.hrl").
-include("esip.hrl"). -include("esip.hrl").
-define(MAX_REDIRECTS, 5).
-record(state, {host = <<"">> :: binary(), -record(state, {host = <<"">> :: binary(),
opts = [] :: [{certfile, binary()}], opts = [] :: [{certfile, binary()}],
orig_trid, orig_trid,
@ -54,7 +52,7 @@ init([Host, Opts]) ->
{ok, wait_for_request, #state{opts = Opts, host = Host}}. {ok, wait_for_request, #state{opts = Opts, host = Host}}.
wait_for_request({#sip{type = request} = Req, TrID}, State) -> 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), Req1 = mod_sip:prepare_request(Req),
case connect(Req1, Opts) of case connect(Req1, Opts) of
{ok, SIPSocket} -> {ok, SIPSocket} ->
@ -73,6 +71,12 @@ wait_for_request({#sip{type = request} = Req, TrID}, State) ->
reason = Reason})), reason = Reason})),
{stop, normal, State} {stop, normal, State}
end; end;
{error, notfound} ->
esip:reply(TrID, mod_sip:make_response(
Req, #sip{type = response,
status = 480,
reason = esip:reason(480)})),
{stop, normal, State};
Err -> Err ->
{Status, Reason} = esip:error_status(Err), {Status, Reason} = esip:error_status(Err),
esip:reply(TrID, mod_sip:make_response( esip:reply(TrID, mod_sip:make_response(
@ -143,10 +147,18 @@ code_change(_OldVsn, StateName, State, _Extra) ->
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% Internal functions
%%%=================================================================== %%%===================================================================
connect(Req, Opts) -> connect(#sip{hdrs = Hdrs} = Req, Opts) ->
case proplists:get_value(socket, Opts) of {_, ToURI, _} = esip:get_hdr('to', Hdrs),
undefined -> case mod_sip:at_my_host(ToURI) of
esip:connect(Req, Opts); true ->
#sip_socket{} = SIPSock -> LUser = jlib:nodeprep(ToURI#uri.user),
{ok, SIPSock} 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. end.

View File

@ -12,7 +12,7 @@
-behaviour(?GEN_SERVER). -behaviour(?GEN_SERVER).
%% API %% API
-export([start_link/0, request/2, find_session/2]). -export([start_link/0, request/2, find_socket/2]).
%% gen_server callbacks %% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, -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}) mod_sip:make_response(Req, #sip{type = response, status = 400})
end. end.
find_session(U, S) -> find_socket(U, S) ->
case mnesia:dirty_read(sip_session, {U, S}) of case mnesia:dirty_read(sip_session, {U, S}) of
[Session] -> [#sip_session{socket = SIPSocket}] ->
{ok, Session}; {ok, SIPSocket};
[] -> [] ->
error error
end. end.