Skip to content

Commit

Permalink
Big outbound refactorization
Browse files Browse the repository at this point in the history
  • Loading branch information
kalta committed Mar 13, 2014
1 parent e94c484 commit c82c4da
Show file tree
Hide file tree
Showing 12 changed files with 588 additions and 353 deletions.
11 changes: 7 additions & 4 deletions samples/nksip_pbx/src/nksip_pbx_sipapp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
-define(DOMAINS, [<<"nksip">>, <<"127.0.0.1">>]).
-define(TIME_CHECK, 10000).

-include("../../../include/nksip.hrl").


%% @doc Starts a new SipApp, listening on port 5060 for udp and tcp and 5061 for tls,
%% and acting as a registrar.
start() ->
Expand Down Expand Up @@ -259,8 +262,8 @@ test_speed([Uri|Rest], Acc) ->
%% @doc Gets all registered contacts
find_all() ->
All = [
[Uri || {_AppId, Uri, _Time, _Q} <- List]
|| {_, List} <- nksip_registrar:internal_get_all()
[Uri || #reg_contact{contact=Uri} <- List]
|| {_, _, List} <- nksip_registrar:internal_get_all()
],
lists:flatten(All).

Expand All @@ -271,8 +274,8 @@ find_all_except_me(ReqId) ->
[{Scheme, User, Domain}] = nksip_parse:aors(From),
AOR = {Scheme, User, Domain},
All = [
[Uri || {_AppId, Uri, _Time, _Q} <- List]
|| {R_AOR, List} <- nksip_registrar:internal_get_all(), R_AOR /= AOR
[Uri || #reg_contact{contact=Uri} <- List]
|| {_, R_AOR, List} <- nksip_registrar:internal_get_all(), R_AOR /= AOR
],
lists:flatten(All).

Expand Down
2 changes: 1 addition & 1 deletion src/nksip_call_fork.erl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ launch([Uri|Rest], Id, Call) ->
Call1 = update(Fork1, Call),
?call_debug("Fork ~p starting UAC ~p", [Id, Next], Call1),
UACOpts = nksip_lib:extract(Opts,
[record_route, make_path, no_dialog, update_dialog]),
[record_route, make_path, record_flow, route_flow, no_dialog, update_dialog]),
%% CAUTION: This call can update the fork's state, can even delete it!
Call2 = nksip_call_uac_req:request(Req1, UACOpts, {fork, Id}, Call1),
launch(Rest, Id, Call2#call{next=Next+1}).
Expand Down
72 changes: 43 additions & 29 deletions src/nksip_call_proxy.erl
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,20 @@ route(UAS, UriList, ProxyOpts, Call) ->
{reply, ReplyTimer, CallTimer} -> throw({reply, ReplyTimer, CallTimer});
{update, ReqTimer, CallTimer} -> {ReqTimer, CallTimer}
end,
Req2 = preprocess(Req1, ProxyOpts),
% % Note: pass original request with original routes
% ProxyOpts1 = check_path(Req1, ProxyOpts, Call),
Stateless = lists:member(stateless, ProxyOpts),
ProxyOpts1 = case nksip_outbound:proxy_route(Req1, ProxyOpts) of
{ok, OutProxyOpts} -> OutProxyOpts;
{error, OutError} -> throw({reply, OutError})
end,
#call{app_id=AppId} = Call,
Req2 = remove_local_routes(AppId, Req1),
Req3 = preprocess(Req2, ProxyOpts1),
Stateless = lists:member(stateless, ProxyOpts1),
case Method of
'ACK' when Stateless ->
[[First|_]|_] = UriSet,
route_stateless(Req2, First, ProxyOpts, Call1);
route_stateless(Req3, First, ProxyOpts1, Call1);
'ACK' ->
{fork, UAS#trans{request=Req2}, UriSet, ProxyOpts};
{fork, UAS#trans{request=Req3}, UriSet, ProxyOpts1};
_ ->
case nksip_sipmsg:header(Req, <<"Proxy-Require">>, tokens) of
[] ->
Expand All @@ -79,9 +83,9 @@ route(UAS, UriList, ProxyOpts, Call) ->
case Stateless of
true ->
[[First|_]|_] = UriSet,
route_stateless(Req2, First, ProxyOpts, Call1);
route_stateless(Req3, First, ProxyOpts1, Call1);
false ->
{fork, UAS#trans{request=Req2}, UriSet, ProxyOpts}
{fork, UAS#trans{request=Req3}, UriSet, ProxyOpts1}
end
end
catch
Expand Down Expand Up @@ -177,16 +181,30 @@ check_request(#sipmsg{class={req, Method}, forwards=Forwards}=Req, Opts) ->
end.



%% @private
-spec preprocess(nksip:request(), [opt()]) ->
nksip:request().

preprocess(Req, ProxyOpts) ->
#sipmsg{app_id=AppId, forwards=Forwards, routes=Routes, headers=Headers} = Req,
Routes1 = case lists:member(remove_routes, ProxyOpts) of
#sipmsg{ruri=RUri, forwards=Forwards, routes=Routes, headers=Headers} = Req,
case nksip_parse:extract_uri_routes(RUri) of
{UriRoutes, RUri1} ->
Routes1 = Routes ++ UriRoutes;
error ->
RUri1 = Routes1 = throw({internal_error, "Bad Uri"})
end,
Routes2 = case lists:member(remove_routes, ProxyOpts) of
true -> [];
false -> Routes
false -> Routes1
end,
Routes3 = case proplists:get_all_values(route, ProxyOpts) of
[] ->
Routes2;
ProxyRoutes1 ->
case nksip_parse:uris(ProxyRoutes1) of
error -> throw({internal_error, "Invalid proxy option"});
ProxyRoutes2 -> ProxyRoutes2 ++ Routes2
end
end,
Headers1 = case lists:member(remove_headers, ProxyOpts) of
true -> [];
Expand All @@ -196,28 +214,24 @@ preprocess(Req, ProxyOpts) ->
[] -> Headers1;
ProxyHeaders -> ProxyHeaders++Headers1
end,
Routes2 = case proplists:get_all_values(route, ProxyOpts) of
[] ->
Routes1;
ProxyRoutes1 ->
case nksip_parse:uris(ProxyRoutes1) of
error ->
throw({internal_error, "Invalid proxy option"});
ProxyRoutes2 ->
% If we add routes, remove local routes now before inserting
% (Existing flow token in first route would be lost)
ProxyRoutes2 ++ remove_local_routes(AppId, Routes1)
end
end,
Req#sipmsg{forwards=Forwards-1, headers=Headers2, routes=Routes2}.
Req#sipmsg{ruri=RUri1, forwards=Forwards-1, headers=Headers2, routes=Routes3}.


remove_local_routes(_AppId, []) ->
%% @private
remove_local_routes(AppId, #sipmsg{routes=Routes}=Req) ->
case do_remove_local_routes(AppId, Routes) of
Routes -> Req;
Routes1 -> Req#sipmsg{routes=Routes1}
end.


%% @private
do_remove_local_routes(_AppId, []) ->
[];

remove_local_routes(AppId, [Route|RestRoutes]) ->
do_remove_local_routes(AppId, [Route|RestRoutes]) ->
case nksip_transport:is_local(AppId, Route) of
true -> remove_local_routes(AppId, RestRoutes);
true -> do_remove_local_routes(AppId, RestRoutes);
false -> [Route|RestRoutes]
end.

Expand Down
10 changes: 8 additions & 2 deletions src/nksip_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

-export([start_listener/5, connect/6, send/2, async_send/2, stop/2]).
-export([start_refresh/3, stop_refresh/1, set_timeout/2, get_transport/1, get_refresh/1]).
-export([incoming/2]).
-export([incoming/2, stop_all/0]).
-export([start_link/4, init/1, terminate/2, code_change/3, handle_call/3,
handle_cast/2, handle_info/2]).

Expand Down Expand Up @@ -137,7 +137,7 @@ stop(Pid, Reason) ->

%% @doc Start a time-alive series, with result notify
%% If `Ref' is not `undefined', a message will be sent to self() using `Ref'
%% after the fist successful ping response
%% (self() ! Ref) after the fist successful ping response
-spec start_refresh(pid(), pos_integer(), term()) ->
ok | error.

Expand Down Expand Up @@ -208,6 +208,12 @@ incoming(Pid, Packet) when is_binary(Packet) ->



%% @private
stop_all() ->
[stop(Pid, normal) || {_, _, Pid} <- nksip_transport:get_all_connected()].



%% ===================================================================
%% gen_server
%% ===================================================================
Expand Down
Loading

0 comments on commit c82c4da

Please sign in to comment.