Skip to content

Commit

Permalink
Changed behavior of stateless in route/5 callback
Browse files Browse the repository at this point in the history
  • Loading branch information
kalta committed May 10, 2014
1 parent 54b6c81 commit 84f78f5
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 81 deletions.
2 changes: 1 addition & 1 deletion samples/nksip_loadtest/src/nksip_loadtest_sipapp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ init([_AppId]) ->

%% @doc Request routing callback
route(_, <<"stateless">>, _, _, _) ->
{process, [stateless]};
process_stateless;

route(_, <<"stateful">>, _, _, _) ->
process;
Expand Down
25 changes: 3 additions & 22 deletions src/nksip_call_proxy.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

%% @doc Tries to route a request to set of uris, serially and/or in parallel.
-spec route(nksip_call:trans(), nksip:uri_set(), nksip_lib:optslist(), nksip_call:call()) ->
{fork, nksip_call:trans(), nksip:uri_set()} | stateless_proxy |
{fork, nksip_call:trans(), nksip:uri_set()} | noreply |
{reply, nksip:sipreply(), nksip_call:call()}.

route(UAS, UriList, ProxyOpts, Call) ->
Expand Down Expand Up @@ -83,7 +83,7 @@ route(UAS, UriList, ProxyOpts, Call) ->

%% @private
-spec route_stateless(nksip:request(), nksip:uri(), nksip_lib:optslist(), nksip_call:call()) ->
stateless_proxy.
noreply.

route_stateless(Req, Uri, ProxyOpts, _Call) ->
#sipmsg{class={req, Method}} = Req,
Expand All @@ -99,7 +99,7 @@ route_stateless(Req, Uri, ProxyOpts, _Call) ->
?call_notice("Stateless proxy could not route ~p to ~s: ~p",
[Method, nksip_unparse:uri(Uri), Error])
end,
stateless_proxy;
noreply;
{error, {reply, Reply}} ->
throw({reply, Reply});
{error, Error} ->
Expand Down Expand Up @@ -175,25 +175,6 @@ check_request(#sipmsg{class={req, Method}, forwards=Forwards}=Req, Opts) ->
Req#sipmsg{forwards=Forwards-1}.


% %% @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, []) ->
% [];

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


%% @doc Process a UriSet generating a standard `[[nksip:uri()]]'.
%% See test code for examples.
-spec normalize_uriset(nksip:uri_set()) ->
Expand Down
47 changes: 26 additions & 21 deletions src/nksip_call_uas_route.erl
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,20 @@ route_reply(Reply, #trans{status=route}=UAS, Call) ->
Route = case Reply of
{reply, Resp} -> {reply, Resp};
{reply_stateless, Resp} -> {reply_stateless, Resp};
process -> {process, []};
{process, Opts} -> {process, Opts};
process -> process;
process_stateless -> process_stateless;
proxy -> {proxy, RUri, []};
{proxy, Uris} -> {proxy, Uris, []};
{proxy, ruri, Opts} -> {proxy, RUri, Opts};
{proxy, Uris, Opts} -> {proxy, Uris, Opts};
proxy_stateless -> {proxy, RUri, [stateless]};
{proxy_stateless, Uris} -> {proxy, Uris, [stateless]};
{proxy_stateless, ruri, Opts} -> {proxy, RUri, [stateless|Opts]};
{proxy_stateless, Uris, Opts} -> {proxy, Uris, [stateless|Opts]};
strict_proxy -> {strict_proxy, []};
{strict_proxy, Opts} -> {strict_proxy, Opts};
Invalid ->
?call_warning("Invalid reply from route(): ~p", [Invalid]),
?call_warning("Invalid reply from route/5 callback: ~p", [Invalid]),
{reply_stateless, {internal_error, "Invalid SipApp Reply"}}
end,
Status = case Method of
Expand All @@ -249,7 +253,7 @@ route_reply(_Reply, UAS, Call) ->

%% @private
-spec do_route({reply, nksip:sipreply()} | {reply_stateless, nksip:sipreply()} |
{process, nksip_lib:optslist()} |
process | process_stateless |
{proxy, nksip:uri_set(), nksip_lib:optslist()} |
{strict_proxy, nksip_lib:optslist()},
nksip_call:trans(), nksip_call:call()) ->
Expand All @@ -264,30 +268,31 @@ do_route({reply_stateless, Reply}, UAS, Call) ->
reply(Reply, UAS1, update(UAS1, Call));

%% CANCEL should have been processed already
do_route({process, _Opts}, #trans{method='CANCEL'}=UAS, Call) ->
do_route(process, #trans{method='CANCEL'}=UAS, Call) ->
reply(no_transaction, UAS, Call);

do_route({process, Opts}, #trans{request=Req, method=Method}=UAS, Call) ->
Stateless = case Method of
'INVITE' -> false;
_ -> lists:member(stateless, Opts)
end,
UAS1 = UAS#trans{stateless=Stateless},
UAS2 = case nksip_lib:get_value(headers, Opts) of
Headers1 when is_list(Headers1) ->
#sipmsg{headers=Headers} = Req,
Req1 = Req#sipmsg{headers=Headers1++Headers},
UAS1#trans{request=Req1};
_ ->
UAS1
end,
nksip_call_uas_process:process(UAS2, update(UAS2, Call));
do_route(process, UAS, Call) ->
UAS1 = UAS#trans{stateless=false},
nksip_call_uas_process:process(UAS1, update(UAS1, Call));

%% CANCEL should have been processed already
do_route(process_stateless, #trans{method='CANCEL'}=UAS, Call) ->
reply(no_transaction, UAS, Call);

do_route(process_stateless, #trans{method='INVITE'}=UAS, Call) ->
?call_warning("Invalid response 'process_stateless' for INVITE request "
" in route/5 callback", []),
reply({internal_error, "Invalid SipApp Response"}, UAS, Call);

do_route(process_stateless, UAS, Call) ->
UAS1 = UAS#trans{stateless=true},
nksip_call_uas_process:process(UAS1, update(UAS1, Call));

% We want to proxy the request
do_route({proxy, UriList, ProxyOpts}, UAS, Call) ->
#trans{id=Id, opts=Opts, method=Method} = UAS,
case nksip_call_proxy:route(UAS, UriList, ProxyOpts, Call) of
stateless_proxy ->
noreply ->
UAS1 = UAS#trans{status=finished},
update(UAS1, Call);
{fork, _, _, _} when Method=='CANCEL' ->
Expand Down
4 changes: 3 additions & 1 deletion src/nksip_sipapp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ authorize(_AuthList, _Req, _Call) ->
%% You can also add headers to the request if the URI contains a `<<"Route">>' header
%%
%% If we want to <b>act as an endpoint or B2BUA</b> and answer to the request
%% from this SipApp, we must return `process' or `{process, ProcessOpts}'.
%% from this SipApp, we must return `process' or `process'.
%% NkSIP will then make additional checks to the request (like inspecting
%% `Require' header), start a new transaction and call the function corresponding
%% to the method in the request (like `invite/3', `options/3', etc.)
Expand Down Expand Up @@ -367,6 +367,8 @@ authorize(_AuthList, _Req, _Call) ->
-type route_reply() ::
proxy | {proxy, ruri | nksip:uri_set()} |
{proxy, ruri | nksip:uri_set(), nksip_lib:optslist()} |
proxy_stateless | {proxy_stateless, ruri | nksip:uri_set()} |
{proxy_stateless, ruri | nksip:uri_set(), nksip_lib:optslist()} |
process | {process, nksip_lib:optslist()} |
{reply, nksip:sipreply()} |
{reply, nksip:sipreply(), nksip_lib:optslist()}.
Expand Down
2 changes: 1 addition & 1 deletion test/basic_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ route(Scheme, User, Domain, Req, _Call) ->
[<<"force-error">>] ->
error(test_error);
_ ->
{process, Opts}
process
end;
true when Domain =:= <<"nksip">> ->
case nksip_registrar:find(server1, Scheme, User, Domain) of
Expand Down
14 changes: 7 additions & 7 deletions test/fork_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ route(Scheme, User, Domain, Req, _Call) ->
{ok, Domains} = nksip:get(serverR, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
{process, Opts};
process;
true when Domain =:= <<"nksip">> ->
case nksip_registrar:qfind(serverR, Scheme, User, Domain) of
[] -> {reply, temporarily_unavailable};
Expand All @@ -620,15 +620,15 @@ route(Scheme, User, Domain, Req, _Call) ->
% Adds x-nk-id header. serverA is stateless, rest are stateful
% Always Record-Route
% If domain is "nksip" routes to serverR
Opts = lists:flatten([
case App of server1 -> stateless; _ -> [] end,
record_route,
{insert, "x-nk-id", App}
]),
Opts = [record_route, {insert, "x-nk-id", App}],
{ok, Domains} = nksip:get(App, domains),
case lists:member(Domain, Domains) of
true when Domain =:= <<"nksip">> ->
true when Domain==<<"nksip">>, App==server1 ->
{proxy_stateless, ruri, [{route, "<sip:127.0.0.1;lr>"}|Opts]};
true when Domain==<<"nksip">> ->
{proxy, ruri, [{route, "<sip:127.0.0.1;lr>"}|Opts]};
true when App==server1->
{proxy_stateless, ruri, Opts};
true ->
{proxy, ruri, Opts};
false ->
Expand Down
7 changes: 3 additions & 4 deletions test/ipv6_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -538,20 +538,19 @@ route(Scheme, User, Domain, Req, _Call) ->
server1 ->
Opts = [
{insert, "x-nk-id", "server1"},
stateless,
{route, "<sip:[::1]:5061;lr;transport=tcp>"}
],
{ok, Domains} = nksip:get(server1, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
{process, Opts};
process;
true when Domain =:= <<"nksip">> ->
case nksip_registrar:find(server1, Scheme, User, Domain) of
[] -> {reply, temporarily_unavailable};
UriList -> {proxy, UriList, Opts}
UriList -> {proxy_stateless, UriList, Opts}
end;
_ ->
{proxy, ruri, Opts}
{proxy_stateless, ruri, Opts}
end;
server2 ->
Opts = [
Expand Down
23 changes: 14 additions & 9 deletions test/proxy_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -583,37 +583,42 @@ route(Scheme, User, Domain, Req, _Call) ->
case nksip_request:app_name(Req) of
{Test, App}=AppName when App==server1; App==server2 ->
Opts = [
case Test of stateless -> stateless; _ -> ignore end,
{insert, "x-nk-id", App},
case nksip_request:header(<<"x-nk-rr">>, Req) of
[<<"true">>] -> record_route;
_ -> ignore
end
],
Proxy = case Test of
stateful -> proxy;
stateless -> proxy_stateless
end,
{ok, Domains} = nksip:get(AppName, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
{process, Opts};
true when User == <<>>, Test==stateless ->
process_stateless;
true when User == <<>>, Test==stateful ->
process;
true when User =:= <<"client2_op">>, Domain =:= <<"nksip">> ->
UriList = nksip_registrar:find(AppName, sip, <<"client2">>, Domain),
Body = nksip_request:body(Req),
ServerOpts = binary_to_term(base64:decode(Body)),
{proxy, UriList, ServerOpts++Opts};
{Proxy, UriList, ServerOpts++Opts};
true when Domain =:= <<"nksip">>; Domain =:= <<"nksip2">> ->
case nksip_registrar:find(AppName, Scheme, User, Domain) of
[] ->
% ?P("FIND ~p: []", [{AppName, Scheme, User, Domain}]),
{reply, temporarily_unavailable};
UriList -> {proxy, UriList, Opts}
UriList -> {Proxy, UriList, Opts}
end;
true ->
{proxy, ruri, Opts};
{Proxy, ruri, Opts};
false when Domain =:= <<"nksip">> ->
{proxy, ruri, [{route, "<sip:127.0.0.1;lr>"}|Opts]};
{Proxy, ruri, [{route, "<sip:127.0.0.1;lr>"}|Opts]};
false when Domain =:= <<"nksip2">> ->
{proxy, ruri, [{route, "<sips:127.0.0.1:5081;lr>"}|Opts]};
{Proxy, ruri, [{route, "<sips:127.0.0.1:5081;lr>"}|Opts]};
false ->
{proxy, ruri, Opts}
{Proxy, ruri, Opts}
end;
_ ->
process
Expand Down
7 changes: 2 additions & 5 deletions test/register_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -297,14 +297,11 @@ init(Id) ->
route(Scheme, User, Domain, Req, _Call) ->
case nksip_request:app_name(Req) of
server1 ->
Opts = [
record_route,
{insert, "x-nk-server", server1}
],
Opts = [record_route, {insert, "x-nk-server", server1}],
{ok, Domains} = nksip:get(server1, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
{process, Opts};
process;
true when Domain =:= <<"nksip">> ->
case nksip_registrar:find(server1, Scheme, User, Domain) of
[] -> {reply, temporarily_unavailable};
Expand Down
7 changes: 2 additions & 5 deletions test/uas_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,7 @@ init(Id) ->
route(Scheme, User, Domain, Req, _Call) ->
case nksip_request:app_name(Req) of
server1 ->
Opts = [
record_route,
{insert, "x-nk-server", server1}
],
Opts = [record_route, {insert, "x-nk-server", server1}],
{ok, Domains} = nksip:get(server1, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
Expand All @@ -224,7 +221,7 @@ route(Scheme, User, Domain, Req, _Call) ->
[<<"force-error">>] ->
error(test_error);
_ ->
{process, Opts}
process
end;
true when Domain =:= <<"nksip">> ->
case nksip_registrar:find(server1, Scheme, User, Domain) of
Expand Down
7 changes: 2 additions & 5 deletions test/websocket_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,11 @@ init(Id) ->
route(_Scheme, User, Domain, Req, _Call) ->
case nksip_request:app_name(Req) of
server1 ->
Opts = [
record_route,
{insert, "x-nk-server", "server1"}
],
Opts = [record_route, {insert, "x-nk-server", "server1"}],
{ok, Domains} = nksip:get(server1, domains),
case lists:member(Domain, Domains) of
true when User =:= <<>> ->
{process, Opts};
process;
true when Domain =:= <<"nksip">> ->
RUri = nksip_request:meta(ruri, Req),
case nksip_registrar:find(server1, RUri) of
Expand Down

0 comments on commit 84f78f5

Please sign in to comment.