aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_config.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2013-04-05 18:53:52 +0200
committerAnders Svensson <[email protected]>2013-04-06 02:37:48 +0200
commit38304d7b542e3c592d2234391062b4e74c42f4b5 (patch)
tree3409d2ac3a50b2d5784ed04826b09177f4c30bb6 /lib/diameter/src/base/diameter_config.erl
parentb9ef8bac23fa0421765afe3073f430a1f0d92260 (diff)
downloadotp-38304d7b542e3c592d2234391062b4e74c42f4b5.tar.gz
otp-38304d7b542e3c592d2234391062b4e74c42f4b5.tar.bz2
otp-38304d7b542e3c592d2234391062b4e74c42f4b5.zip
Fix handling of unknown options to diameter:start_service/2
{error, Reason} is now returned, instead of the options being ignored. Note that diameter:add_transport/2 purposely ignores unknown options and that the behaviour is documented. This is historic: some users depend on it in order to store their own options for identifying transport config, instead of using the reference returned by add_transport.
Diffstat (limited to 'lib/diameter/src/base/diameter_config.erl')
-rw-r--r--lib/diameter/src/base/diameter_config.erl40
1 files changed, 23 insertions, 17 deletions
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index 1282930145..2a145c874b 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -614,30 +614,38 @@ stop_transport(SvcName, Refs) ->
%% make_config/2
make_config(SvcName, Opts) ->
- Apps = init_apps(Opts),
+ AppOpts = [T || {application, _} = T <- Opts],
+ Apps = init_apps(AppOpts),
+
[] == Apps andalso ?THROW(no_apps),
%% Use the fact that diameter_caps has the same field names as CER.
Fields = ?BASE:'#info-'(diameter_base_CER) -- ['AVP'],
- COpts = [T || {K,_} = T <- Opts, lists:member(K, Fields)],
- Caps = make_caps(#diameter_caps{}, COpts),
+ CapOpts = [T || {K,_} = T <- Opts, lists:member(K, Fields)],
+ Caps = make_caps(#diameter_caps{}, CapOpts),
- ok = encode_CER(COpts),
+ ok = encode_CER(CapOpts),
- Os = split(Opts, fun opt/2, [{false, share_peers},
- {false, use_shared_peers},
- {false, monitor},
- {?NOMASK, sequence},
- {nodes, restrict_connections}]),
+ SvcOpts = make_opts((Opts -- AppOpts) -- CapOpts,
+ [{false, share_peers},
+ {false, use_shared_peers},
+ {false, monitor},
+ {?NOMASK, sequence},
+ {nodes, restrict_connections}]),
#service{name = SvcName,
rec = #diameter_service{applications = Apps,
capabilities = Caps},
- options = Os}.
+ options = SvcOpts}.
+
+make_opts(Opts, Defs) ->
+ Known = [{K, get_opt(K, Opts, D)} || {D,K} <- Defs],
+ Unknown = Opts -- Known,
+
+ [] == Unknown orelse ?THROW({invalid, hd(Unknown)}),
-split(Opts, F, Defs) ->
- [{K, F(K, get_opt(K, Opts, D))} || {D,K} <- Defs].
+ [{K, opt(K,V)} || {K,V} <- Known].
opt(K, false = B)
when K /= sequence ->
@@ -728,8 +736,8 @@ encode_CER(Opts) ->
init_apps(Opts) ->
lists:foldl(fun app_acc/2, [], lists:reverse(Opts)).
-app_acc({application, Opts}, Acc) ->
- is_list(Opts) orelse ?THROW({application, Opts}),
+app_acc({application, Opts} = T, Acc) ->
+ is_list(Opts) orelse ?THROW(T),
[Dict, Mod] = get_opt([dictionary, module], Opts),
Alias = get_opt(alias, Opts, Dict),
@@ -745,9 +753,7 @@ app_acc({application, Opts}, Acc) ->
mutable = M,
options = [{answer_errors, A},
{request_errors, P}]}
- | Acc];
-app_acc(_, Acc) ->
- Acc.
+ | Acc].
init_mod(#diameter_callback{} = R) ->
init_mod([diameter_callback, R]);