mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Fix proxying of ACK requests for 2xx responses
This commit is contained in:
parent
6baf3a24de
commit
8925975c86
@ -12,7 +12,7 @@
|
|||||||
-behaviour(esip).
|
-behaviour(esip).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, prepare_request/1, make_response/2, at_my_host/1]).
|
-export([start/2, stop/1, make_response/2, is_my_host/1, 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,
|
||||||
@ -77,6 +77,13 @@ message_out(_, _) ->
|
|||||||
response(_Resp, _SIPSock) ->
|
response(_Resp, _SIPSock) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
request(#sip{method = <<"ACK">>} = Req, SIPSock) ->
|
||||||
|
case action(Req, SIPSock) of
|
||||||
|
{relay, LServer} ->
|
||||||
|
mod_sip_proxy:route(Req, LServer, []);
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end;
|
||||||
request(_Req, _SIPSock) ->
|
request(_Req, _SIPSock) ->
|
||||||
error.
|
error.
|
||||||
|
|
||||||
@ -251,18 +258,6 @@ process(Req, _) ->
|
|||||||
make_response(Req, #sip{type = response, status = 405,
|
make_response(Req, #sip{type = response, status = 405,
|
||||||
hdrs = [{'allow', allow()}]}).
|
hdrs = [{'allow', allow()}]}).
|
||||||
|
|
||||||
prepare_request(#sip{hdrs = Hdrs1} = Req) ->
|
|
||||||
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 is_my_host(jlib:nameprep(Realm));
|
|
||||||
(_) ->
|
|
||||||
true
|
|
||||||
end, Hdrs2),
|
|
||||||
Req#sip{hdrs = Hdrs3}.
|
|
||||||
|
|
||||||
make_auth_hdr(LServer) ->
|
make_auth_hdr(LServer) ->
|
||||||
Realm = jlib:nameprep(LServer),
|
Realm = jlib:nameprep(LServer),
|
||||||
{<<"Digest">>, [{<<"realm">>, esip:quote(Realm)},
|
{<<"Digest">>, [{<<"realm">>, esip:quote(Realm)},
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
-behaviour(?GEN_FSM).
|
-behaviour(?GEN_FSM).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, start_link/2, route/4]).
|
-export([start/2, start_link/2, route/3, route/4]).
|
||||||
|
|
||||||
%% gen_fsm callbacks
|
%% gen_fsm callbacks
|
||||||
-export([init/1, wait_for_request/2, wait_for_response/2,
|
-export([init/1, wait_for_request/2, wait_for_response/2,
|
||||||
@ -42,6 +42,19 @@ start_link(LServer, Opts) ->
|
|||||||
route(SIPMsg, _SIPSock, TrID, Pid) ->
|
route(SIPMsg, _SIPSock, TrID, Pid) ->
|
||||||
?GEN_FSM:send_event(Pid, {SIPMsg, TrID}).
|
?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
|
%%% gen_fsm callbacks
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -51,7 +64,7 @@ init([Host, Opts]) ->
|
|||||||
|
|
||||||
wait_for_request({#sip{type = request} = Req, TrID}, State) ->
|
wait_for_request({#sip{type = request} = Req, TrID}, State) ->
|
||||||
Opts = State#state.opts,
|
Opts = State#state.opts,
|
||||||
Req1 = mod_sip:prepare_request(Req),
|
Req1 = prepare_request(State#state.host, Req),
|
||||||
case connect(Req1, Opts) of
|
case connect(Req1, Opts) of
|
||||||
{ok, SIPSockets} ->
|
{ok, SIPSockets} ->
|
||||||
NewState =
|
NewState =
|
||||||
@ -59,8 +72,9 @@ wait_for_request({#sip{type = request} = Req, TrID}, State) ->
|
|||||||
fun(_SIPSocket, {error, _} = Err) ->
|
fun(_SIPSocket, {error, _} = Err) ->
|
||||||
Err;
|
Err;
|
||||||
(SIPSocket, #state{tr_ids = TrIDs} = AccState) ->
|
(SIPSocket, #state{tr_ids = TrIDs} = AccState) ->
|
||||||
Req2 = add_via(SIPSocket, State#state.host, Req1),
|
Req2 = add_record_route(SIPSocket, State#state.host, Req1),
|
||||||
case esip:request(SIPSocket, Req2,
|
Req3 = add_via(SIPSocket, State#state.host, Req2),
|
||||||
|
case esip:request(SIPSocket, Req3,
|
||||||
{?MODULE, route, [self()]}) of
|
{?MODULE, route, [self()]}) of
|
||||||
{ok, ClientTrID} ->
|
{ok, ClientTrID} ->
|
||||||
NewTrIDs = [ClientTrID|TrIDs],
|
NewTrIDs = [ClientTrID|TrIDs],
|
||||||
@ -234,6 +248,11 @@ add_via(#sip_socket{type = Transport}, LServer, #sip{hdrs = Hdrs} = Req) ->
|
|||||||
{<<"rport">>, <<"">>}]},
|
{<<"rport">>, <<"">>}]},
|
||||||
Req#sip{hdrs = [{'via', [Via]}|Hdrs]}.
|
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) ->
|
get_configured_vias(LServer) ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, via,
|
LServer, ?MODULE, via,
|
||||||
@ -275,3 +294,30 @@ choose_best_response(#state{responses = Responses} = State) ->
|
|||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
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}.
|
||||||
|
Loading…
Reference in New Issue
Block a user