diff options
Diffstat (limited to 'lib/diameter/src/base')
-rw-r--r-- | lib/diameter/src/base/diameter.app.src | 28 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter.appup.src | 51 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter.erl | 4 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_capx.erl | 9 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_codec.erl | 2 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_config.erl | 9 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_peer.erl | 94 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_service.erl | 24 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_traffic.erl | 27 |
9 files changed, 116 insertions, 132 deletions
diff --git a/lib/diameter/src/base/diameter.app.src b/lib/diameter/src/base/diameter.app.src deleted file mode 100644 index ceefb9b398..0000000000 --- a/lib/diameter/src/base/diameter.app.src +++ /dev/null @@ -1,28 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -{application, diameter, - [{description, "Diameter protocol"}, - {vsn, "%VSN%"}, - {modules, [%MODULES%]}, - {registered, [%REGISTERED%]}, - {applications, [stdlib, kernel]}, - {env, []}, - {mod, {diameter_app, []}} - ]}. diff --git a/lib/diameter/src/base/diameter.appup.src b/lib/diameter/src/base/diameter.appup.src deleted file mode 100644 index 359f434941..0000000000 --- a/lib/diameter/src/base/diameter.appup.src +++ /dev/null @@ -1,51 +0,0 @@ -%% This is an -*- erlang -*- file. -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -{"%VSN%", - [ - {"0.9", [{restart_application, diameter}]}, %% R14B03 - {"0.10", [{restart_application, diameter}]}, %% R14B04 - {"1.0", [{restart_application, diameter}]}, %% R15B - {"1.1", [{restart_application, diameter}]}, %% R15B01 - {"1.2", [{restart_application, diameter}]}, %% R15B02 - {"1.2.1", [{restart_application, diameter}]}, - {"1.3", [{restart_application, diameter}]}, %% R15B03 - {"1.3.1", [{restart_application, diameter}]}, - {"1.4", [{restart_application, diameter}]}, %% R16A - {"1.4.1", [{load_module, diameter_reg}, %% R16B - {load_module, diameter_stats}, - {load_module, diameter_service}, - {load_module, diameter_watchdog}, - {load_module, diameter_capx}, - {load_module, diameter}]} - ], - [ - {"0.9", [{restart_application, diameter}]}, - {"0.10", [{restart_application, diameter}]}, - {"1.0", [{restart_application, diameter}]}, - {"1.1", [{restart_application, diameter}]}, - {"1.2", [{restart_application, diameter}]}, - {"1.2.1", [{restart_application, diameter}]}, - {"1.3", [{restart_application, diameter}]}, - {"1.3.1", [{restart_application, diameter}]}, - {"1.4", [{restart_application, diameter}]}, - {"1.4.1", [{restart_application, diameter}]} - ] -}. diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl index 57730cad61..77200cc7d0 100644 --- a/lib/diameter/src/base/diameter.erl +++ b/lib/diameter/src/base/diameter.erl @@ -306,7 +306,8 @@ call(SvcName, App, Message) -> | {restrict_connections, restriction()} | {sequence, sequence() | evaluable()} | {share_peers, remotes()} - | {use_shared_peers, remotes()}. + | {use_shared_peers, remotes()} + | {spawn_opt, list()}. -type application_opt() :: {alias, app_alias()} @@ -345,6 +346,7 @@ call(SvcName, App, Message) -> | {reconnect_timer, 'Unsigned32'()} | {watchdog_timer, 'Unsigned32'() | {module(), atom(), list()}} | {watchdog_config, [{okay|suspect, non_neg_integer()}]} + | {spawn_opt, list()} | {private, any()}. %% Predicate passed to remove_transport/2 diff --git a/lib/diameter/src/base/diameter_capx.erl b/lib/diameter/src/base/diameter_capx.erl index 4b821f5139..1a931a9854 100644 --- a/lib/diameter/src/base/diameter_capx.erl +++ b/lib/diameter/src/base/diameter_capx.erl @@ -419,12 +419,13 @@ app_union(#diameter_caps{auth_application_id = U, vendor_specific_application_id = V}) -> set_list(U ++ C ++ lists:flatmap(fun vsa_apps/1, V)). -vsa_apps([_ | [_,_] = Ids]) -> - lists:append(Ids); +vsa_apps(Vals) + when is_list(Vals) -> + lists:flatmap(fun({'Vendor-Id', _}) -> []; ({_, Ids}) -> Ids end, Vals); vsa_apps(Rec) when is_tuple(Rec) -> - [_|T] = tuple_to_list(Rec), - vsa_apps(T). + [_Name, _VendorId | Idss] = tuple_to_list(Rec), + lists:append(Idss). %% It's a configuration error for a locally advertised application not %% to be represented in Apps. Don't just match on lists:keyfind/3 in diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl index 6c0e73de36..1d647b8c87 100644 --- a/lib/diameter/src/base/diameter_codec.erl +++ b/lib/diameter/src/base/diameter_codec.erl @@ -204,7 +204,7 @@ msg_header(Mod, 'answer-message' = MsgName, Header) -> #diameter_header{application_id = Aid, cmd_code = Code} = Header, - {-1, Flags, ?DIAMETER_APP_ID_COMMON} = Mod:msg_header(MsgName), + {-1, Flags, ?APP_ID_COMMON} = Mod:msg_header(MsgName), {Code, Flags, Aid}; msg_header(Mod, MsgName, _) -> diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl index 2a145c874b..fc5c284bf2 100644 --- a/lib/diameter/src/base/diameter_config.erl +++ b/lib/diameter/src/base/diameter_config.erl @@ -549,6 +549,9 @@ opt({watchdog_timer, Tmo}) -> opt({watchdog_config, L}) -> is_list(L) andalso lists:all(fun wdopt/1, L); +opt({spawn_opt, Opts}) -> + is_list(Opts); + %% Options that we can't validate. opt({K, _}) when K == transport_config; @@ -632,7 +635,8 @@ make_config(SvcName, Opts) -> {false, use_shared_peers}, {false, monitor}, {?NOMASK, sequence}, - {nodes, restrict_connections}]), + {nodes, restrict_connections}, + {[], spawn_opt}]), #service{name = SvcName, rec = #diameter_service{applications = Apps, @@ -647,6 +651,9 @@ make_opts(Opts, Defs) -> [{K, opt(K,V)} || {K,V} <- Known]. +opt(spawn_opt, L) -> + is_list(L); + opt(K, false = B) when K /= sequence -> B; diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl index 0d2efd4d1f..e5d4b28766 100644 --- a/lib/diameter/src/base/diameter_peer.erl +++ b/lib/diameter/src/base/diameter_peer.erl @@ -25,7 +25,8 @@ -export([recv/2, up/1, up/2, - up/3]). + up/3, + match/2]). %% ... and the stack. -export([start/1, @@ -63,16 +64,16 @@ -define(DEFAULT_TCFG, []). -define(DEFAULT_TTMO, infinity). -%%% --------------------------------------------------------------------------- -%%% # notify/3 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # notify/3 +%% --------------------------------------------------------------------------- notify(Nodes, SvcName, T) -> rpc:abcast(Nodes, ?SERVER, {notify, SvcName, T}). -%%% --------------------------------------------------------------------------- -%%% # start/1 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # start/1 +%% --------------------------------------------------------------------------- -spec start({T, [Opt], #diameter_service{}}) -> {TPid, [Addr], Tmo, Data} @@ -180,9 +181,34 @@ start(T, [M|Ms], Cfg, Svc, Tmo, Rest, Errs) -> start(Mod, Args) -> apply(Mod, start, Args). -%%% --------------------------------------------------------------------------- -%%% # up/1-3 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # match/2 +%% --------------------------------------------------------------------------- + +match(Addrs, Matches) + when is_list(Addrs) -> + lists:all(fun(A) -> match1(A, Matches) end, Addrs). + +match1(Addr, Matches) + when not is_integer(hd(Matches)) -> + lists:any(fun(M) -> match1(Addr, M) end, Matches); + +match1(Addr, Match) -> + match(Addr, addr(Match), Match). + +match(Addr, {ok, A}, _) -> + Addr == A; +match(Addr, {error, _}, RE) -> + match == re:run(inet_parse:ntoa(Addr), RE, [{capture, none}]). + +addr([_|_] = A) -> + inet_parse:address(A); +addr(A) -> + {ok, A}. + +%% --------------------------------------------------------------------------- +%% # up/1-3 +%% --------------------------------------------------------------------------- up(Pid) -> %% accepting transport ifc_send(Pid, {self(), connected}). @@ -193,16 +219,16 @@ up(Pid, Remote) -> %% connecting transport up(Pid, Remote, LAddrs) -> %% connecting transport ifc_send(Pid, {self(), connected, Remote, LAddrs}). -%%% --------------------------------------------------------------------------- -%%% # recv/2 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # recv/2 +%% --------------------------------------------------------------------------- recv(Pid, Pkt) -> ifc_send(Pid, {recv, Pkt}). -%%% --------------------------------------------------------------------------- -%%% # send/2 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # send/2 +%% --------------------------------------------------------------------------- send(Pid, #diameter_packet{transport_data = undefined, bin = Bin}) -> @@ -211,16 +237,16 @@ send(Pid, #diameter_packet{transport_data = undefined, send(Pid, Pkt) -> ifc_send(Pid, {send, Pkt}). -%%% --------------------------------------------------------------------------- -%%% # close/1 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # close/1 +%% --------------------------------------------------------------------------- close(Pid) -> ifc_send(Pid, {close, self()}). -%%% --------------------------------------------------------------------------- -%%% # abort/1 -%%% --------------------------------------------------------------------------- +%% --------------------------------------------------------------------------- +%% # abort/1 +%% --------------------------------------------------------------------------- abort(Pid) -> exit(Pid, shutdown). @@ -241,16 +267,16 @@ state() -> uptime() -> call(uptime). -%%% ---------------------------------------------------------- -%%% # init(Role) -%%% ---------------------------------------------------------- +%% ---------------------------------------------------------- +%% # init(Role) +%% ---------------------------------------------------------- init([]) -> {ok, #state{}}. -%%% ---------------------------------------------------------- -%%% # handle_call(Request, From, State) -%%% ---------------------------------------------------------- +%% ---------------------------------------------------------- +%% # handle_call(Request, From, State) +%% ---------------------------------------------------------- handle_call(state, _, State) -> {reply, State, State}; @@ -262,17 +288,17 @@ handle_call(Req, From, State) -> ?UNEXPECTED([Req, From]), {reply, nok, State}. -%%% ---------------------------------------------------------- -%%% # handle_cast(Request, State) -%%% ---------------------------------------------------------- +%% ---------------------------------------------------------- +%% # handle_cast(Request, State) +%% ---------------------------------------------------------- handle_cast(Msg, State) -> ?UNEXPECTED([Msg]), {noreply, State}. -%%% ---------------------------------------------------------- -%%% # handle_info(Request, State) -%%% ---------------------------------------------------------- +%% ---------------------------------------------------------- +%% # handle_info(Request, State) +%% ---------------------------------------------------------- %% Remote service is distributing a message. handle_info({notify, SvcName, T}, S) -> diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index 112e83476d..9dd8aafc61 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -770,10 +770,8 @@ start(Ref, Type, Opts, #state{watchdogT = WatchdogT, = Svc = merge_service(Opts, Svc0), {_,_} = Mask = proplists:get_value(sequence, SvcOpts), - Pid = s(Type, Ref, {diameter_traffic:make_recvdata([SvcName, - PeerT, - Apps, - Mask]), + RecvData = diameter_traffic:make_recvdata([SvcName, PeerT, Apps, Mask]), + Pid = s(Type, Ref, {{spawn_opts([Opts, SvcOpts]), RecvData}, Opts, SvcOpts, Svc}), @@ -787,6 +785,12 @@ start(Ref, Type, Opts, #state{watchdogT = WatchdogT, %% record so that each watchdog may get a different record. This %% record is what is passed back into application callbacks. +spawn_opts(Optss) -> + SpawnOpts = get_value(spawn_opt, Optss, []), + [T || T <- SpawnOpts, + T /= link, + T /= monitor]. + s(Type, Ref, T) -> {_MRef, Pid} = diameter_watchdog:start({Type, Ref}, T), Pid. @@ -986,6 +990,18 @@ keyfind([Key | Rest], Pos, L) -> T end. +%% get_value/3 + +get_value(_, [], Def) -> + Def; +get_value(Key, [L | Rest], Def) -> + case lists:keyfind(Key, 1, L) of + {_,V} -> + V; + _ -> + get_value(Key, Rest, Def) + end. + %% find_outgoing_app/2 find_outgoing_app(Alias, Apps) -> diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index 0b15e68ec7..8b6f026b34 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -48,6 +48,7 @@ -define(BASE, ?DIAMETER_DICT_COMMON). %% Note: the RFC 3588 dictionary -define(DEFAULT_TIMEOUT, 5000). %% for outgoing requests +-define(DEFAULT_SPAWN_OPTS, []). %% Table containing outgoing requests for which a reply has yet to be %% received. @@ -153,13 +154,8 @@ receive_message(TPid, Pkt, Dict0, RecvData) RecvData). %% Incoming request ... -recv(true, false, TPid, Pkt, Dict0, RecvData) -> - try - spawn(fun() -> recv_request(TPid, Pkt, Dict0, RecvData) end) - catch - error: system_limit = E -> %% discard - ?LOG({error, E}, now()) - end; +recv(true, false, TPid, Pkt, Dict0, T) -> + spawn_request(TPid, Pkt, Dict0, T); %% ... answer to known request ... recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) -> @@ -177,6 +173,21 @@ recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) -> recv(false, false, _, _, _, _) -> ok. +%% spawn_request/4 + +spawn_request(TPid, Pkt, Dict0, {Opts, RecvData}) -> + spawn_request(TPid, Pkt, Dict0, Opts, RecvData); +spawn_request(TPid, Pkt, Dict0, RecvData) -> + spawn_request(TPid, Pkt, Dict0, ?DEFAULT_SPAWN_OPTS, RecvData). + +spawn_request(TPid, Pkt, Dict0, Opts, RecvData) -> + try + spawn_opt(fun() -> recv_request(TPid, Pkt, Dict0, RecvData) end, Opts) + catch + error: system_limit = E -> %% discard + ?LOG({error, E}, now()) + end. + %% --------------------------------------------------------------------------- %% recv_request/4 %% --------------------------------------------------------------------------- @@ -780,7 +791,7 @@ failed([MsgName | Values], FailedAvp, Dict) -> %% ... or record. failed(Rec, FailedAvp, Dict) -> try - RecName = element(1, Rec), + RecName = element(1, Rec), Dict:'#info-'(RecName, {index, 'Failed-AVP'}), {'Failed-AVP', [FailedAvp]} catch |