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:
parent
a6fe7425dd
commit
35faffe7da
108
src/mod_sip.erl
108
src/mod_sip.erl
@ -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 ->
|
|
||||||
case esip:connect(NewResp,
|
|
||||||
add_certfile(LServer, Opts)) of
|
|
||||||
{ok, SIPSockOut} ->
|
{ok, SIPSockOut} ->
|
||||||
esip:send(SIPSockOut, NewResp);
|
esip:send(SIPSockOut, NewResp);
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
ok
|
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
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user