aboutsummaryrefslogtreecommitdiff
path: root/src/mod_sip_proxy.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_sip_proxy.erl')
-rw-r--r--src/mod_sip_proxy.erl54
1 files changed, 50 insertions, 4 deletions
diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl
index cae75bff8..b05c49061 100644
--- a/src/mod_sip_proxy.erl
+++ b/src/mod_sip_proxy.erl
@@ -12,7 +12,7 @@
-behaviour(?GEN_FSM).
%% API
--export([start/2, start_link/2, route/4]).
+-export([start/2, start_link/2, route/3, route/4]).
%% gen_fsm callbacks
-export([init/1, wait_for_request/2, wait_for_response/2,
@@ -42,6 +42,19 @@ start_link(LServer, Opts) ->
route(SIPMsg, _SIPSock, TrID, Pid) ->
?GEN_FSM:send_event(Pid, {SIPMsg, TrID}).
+route(Req, LServer, Opts) ->
+ Req1 = prepare_request(LServer, Req),
+ case connect(Req1, add_certfile(LServer, Opts)) of
+ {ok, SIPSockets} ->
+ lists:foreach(
+ fun(SIPSocket) ->
+ Req2 = add_via(SIPSocket, LServer, Req1),
+ esip:send(SIPSocket, Req2)
+ end, SIPSockets);
+ _ ->
+ error
+ end.
+
%%%===================================================================
%%% gen_fsm callbacks
%%%===================================================================
@@ -51,7 +64,7 @@ init([Host, Opts]) ->
wait_for_request({#sip{type = request} = Req, TrID}, State) ->
Opts = State#state.opts,
- Req1 = mod_sip:prepare_request(Req),
+ Req1 = prepare_request(State#state.host, Req),
case connect(Req1, Opts) of
{ok, SIPSockets} ->
NewState =
@@ -59,8 +72,9 @@ wait_for_request({#sip{type = request} = Req, TrID}, State) ->
fun(_SIPSocket, {error, _} = Err) ->
Err;
(SIPSocket, #state{tr_ids = TrIDs} = AccState) ->
- Req2 = add_via(SIPSocket, State#state.host, Req1),
- case esip:request(SIPSocket, Req2,
+ Req2 = add_record_route(SIPSocket, State#state.host, Req1),
+ Req3 = add_via(SIPSocket, State#state.host, Req2),
+ case esip:request(SIPSocket, Req3,
{?MODULE, route, [self()]}) of
{ok, ClientTrID} ->
NewTrIDs = [ClientTrID|TrIDs],
@@ -234,6 +248,11 @@ add_via(#sip_socket{type = Transport}, LServer, #sip{hdrs = Hdrs} = Req) ->
{<<"rport">>, <<"">>}]},
Req#sip{hdrs = [{'via', [Via]}|Hdrs]}.
+add_record_route(_SIPSocket, LServer, #sip{hdrs = Hdrs} = Req) ->
+ URI = #uri{host = LServer, params = [{<<"lr">>, <<"">>}]},
+ Hdrs1 = [{'record-route', [{<<>>, URI, []}]}|Hdrs],
+ Req#sip{hdrs = Hdrs1}.
+
get_configured_vias(LServer) ->
gen_mod:get_module_opt(
LServer, ?MODULE, via,
@@ -275,3 +294,30 @@ choose_best_response(#state{responses = Responses} = State) ->
ok
end
end.
+
+prepare_request(Host, #sip{hdrs = Hdrs} = Req) ->
+ Hdrs1 = lists:flatmap(
+ fun({Hdr, HdrList}) when Hdr == 'route';
+ Hdr == 'record-route' ->
+ case lists:filter(
+ fun({_, #uri{user = <<"">>, host = Host1}, _}) ->
+ Host1 /= Host
+ end, HdrList) of
+ [] ->
+ [];
+ HdrList1 ->
+ [{Hdr, HdrList1}]
+ end;
+ (Hdr) ->
+ [Hdr]
+ end, Hdrs),
+ MF = esip:get_hdr('max-forwards', Hdrs1),
+ Hdrs2 = esip:set_hdr('max-forwards', MF-1, Hdrs1),
+ Hdrs3 = lists:filter(
+ fun({'proxy-authorization', {_, Params}}) ->
+ Realm = esip:unquote(esip:get_param(<<"realm">>, Params)),
+ not mod_sip:is_my_host(jlib:nameprep(Realm));
+ (_) ->
+ true
+ end, Hdrs2),
+ Req#sip{hdrs = Hdrs3}.