Skip to content

Commit

Permalink
Simple dns resolution cache
Browse files Browse the repository at this point in the history
  • Loading branch information
fholzhauser authored and mgumz committed Oct 1, 2020
1 parent b382857 commit 99219a1
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
6 changes: 2 additions & 4 deletions src/ergw_node_selection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ lookup_host(Name, dns, NameServers) ->
_ ->
[]
end,
%% 3GPP DNS answers are almost always large, use TCP by default....
case inet_res:resolve(Name, in, any, [{usevc, true} | NsOpts]) of
case ergw_node_selection_cache:resolve(Name, any, NsOpts) of
{ok, Msg} ->
lists:foldl(
fun(RR, R) ->
Expand Down Expand Up @@ -400,8 +399,7 @@ naptr(Name, NameServers) ->
_ ->
[]
end,
%% 3GPP DNS answers are almost always large, use TCP by default....
inet_res:resolve(Name, in, naptr, [{usevc, true} | NsOpts]).
ergw_node_selection_cache:resolve(Name, naptr, NsOpts).

naptr_service_filter({Order, Pref, Flag, Services, _RegExp, Host}, OrdSPSet, Acc) ->
[Service | Protocols] = string:tokens(Services, ":"),
Expand Down
35 changes: 35 additions & 0 deletions src/ergw_node_selection_cache.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-module(ergw_node_selection_cache).
-export([
init/0,
resolve/3
]).

init() ->
?MODULE = ets:new(?MODULE, [named_table, public, ordered_set, {read_concurrency, true}]),
ok.

resolve(Name, Type, NsOpts) ->
Now = erlang:system_time(second),
case ets:lookup(?MODULE, {Name, Type}) of
[{_, Update, Result}] when Update == Now orelse Update == updating ->
Result;
[{_, _, Result}] ->
ets:update_element(?MODULE, {Name, Type}, {2, updating}),
% optimistic async update, won't hold up queries
spawn(fun() ->
do_update(Name, Type, NsOpts, Now)
end),
Result;
[] ->
do_update(Name, Type, NsOpts, Now)
end.

do_update(Name, Type, NsOpts, Now) ->
%% 3GPP DNS answers are almost always large, use TCP by default....
case inet_res:resolve(Name, in, Type, [{usevc, true} | NsOpts]) of
{error, _} = Error ->
Error;
{ok, Msg} ->
ets:insert(?MODULE, {{Name, Type}, Now, {ok, Msg}}),
{ok, Msg}
end.
1 change: 1 addition & 0 deletions src/ergw_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ start_link() ->
%% ===================================================================

init([]) ->
ok = ergw_node_selection_cache:init(),
{ok, {{one_for_one, 5, 10}, [?CHILD(gtp_path_reg, worker, []),
?CHILD(ergw_tei_mngr, worker, []),
?CHILD(gtp_path_sup, supervisor, []),
Expand Down
22 changes: 20 additions & 2 deletions test/pgw_proxy_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2464,8 +2464,26 @@ dns_node_selection(Config) ->
meck:passthrough([Name, Class, Type, Opts])
end),

{GtpC1, _, _} = create_session(Config),
delete_session(GtpC1),
lists:foreach(
fun(_) ->
{GtpC, _, _} = create_session(Config),
delete_session(GtpC)
end,
lists:seq(1,10)
),

timer:sleep(1100),

{GtpC3, _, _} = create_session(Config),
delete_session(GtpC3),

% 4 DNS requests to start with (it'll remember Sx node name then)
% then 3 for each time it needs to resolve further
% since the cache time check is on exact second, it can be
% total 7 or 10 if the test is done just before change
% of second
NCalls = meck:num_calls(inet_res, resolve, '_'),
?equal(true, NCalls == 7 orelse NCalls == 10),

ok = meck:wait(?HUT, terminate, '_', ?TIMEOUT),
meck_validate(Config),
Expand Down

0 comments on commit 99219a1

Please sign in to comment.