diff --git a/src/mod_sip.erl b/src/mod_sip.erl index cca91a33d..87608d18e 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -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, @@ -23,12 +23,6 @@ -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 diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index aa749ccf7..ef2192a20 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -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. diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index d8f485fef..6c945e5ec 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -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.