aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_capx.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-04-12 11:23:23 +0200
committerAnders Svensson <[email protected]>2017-06-13 14:03:58 +0200
commit2013b1c55e2c199e59610cf9bb7e0cb60424f276 (patch)
tree80f6caff80a91efca386f10661ebdaaf9e9a9248 /lib/diameter/src/base/diameter_capx.erl
parent1e5be430c70d95bfde51aa785398127bbb72089d (diff)
downloadotp-2013b1c55e2c199e59610cf9bb7e0cb60424f276.tar.gz
otp-2013b1c55e2c199e59610cf9bb7e0cb60424f276.tar.bz2
otp-2013b1c55e2c199e59610cf9bb7e0cb60424f276.zip
Comment on RFC ambiguity regarding application identifiers
It is tempting to regard remote support for the common application as implicit, but that leads to the problems noted, and a node could never then expect non-intersecting application support to result in 5010. It probably can't anyway given the different ways the RFC's intent can be interpreted, but it's not unreasonable that a node should be able to advertise a single Diameter application and get 5010 if the peer doesn't support it. The problem we have currently is that peer selection is based on the support advertised by the peer. The application id of an outgoing request is used to lookup peers that have advertised support, so if the peer hasn't advertised support for Diameter common messages then the user won't be able to send DPR and more: diameter:call/4 will just return {error, no_connection}. This commit doesn't solve the problem.
Diffstat (limited to 'lib/diameter/src/base/diameter_capx.erl')
-rw-r--r--lib/diameter/src/base/diameter_capx.erl43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/diameter/src/base/diameter_capx.erl b/lib/diameter/src/base/diameter_capx.erl
index 837125339a..62b05644b2 100644
--- a/lib/diameter/src/base/diameter_capx.erl
+++ b/lib/diameter/src/base/diameter_capx.erl
@@ -416,7 +416,48 @@ bcaps(N, Caps) ->
%% common_applications/3
%%
%% Identify the (local) applications to be supported on the connection
-%% in question.
+%% in question. The RFC says this:
+%%
+%% 2.4 Application Identifiers
+%%
+%% Relay and redirect agents MUST advertise the Relay Application ID,
+%% while all other Diameter nodes MUST advertise locally supported
+%% applications.
+%%
+%% Taken literally, every Diameter node should then advertise support
+%% for the Diameter common messages application, with id 0, since no
+%% node can perform capabilities exchange without it. Expecting this,
+%% or regarding the support as implicit, renders the Result-Code 5010
+%% (DIAMETER_NO_COMMON_APPLICATION) meaningless however, since every
+%% node would regard the common application as being in common with
+%% the peer. In practice, nodes may or may not advertise support for
+%% Diameter common messages.
+%%
+%% That only explicitly advertised applications should be considered
+%% when computing the intersection with the peer is supported here:
+%%
+%% 5.3. Capabilities Exchange
+%%
+%% The receiver of the Capabilities-Exchange-Request (CER) MUST
+%% determine common applications by computing the intersection of its
+%% own set of supported Application Ids against all of the
+%% Application-Id AVPs (Auth-Application-Id, Acct-Application-Id, and
+%% Vendor-Specific-Application-Id) present in the CER.
+%%
+%% The same section also has the following about capabilities exchange
+%% messages.
+%%
+%% The receiver only issues commands to its peers that have advertised
+%% support for the Diameter application that defines the command.
+%%
+%% This statement is also difficult to interpret literally since it
+%% would disallow D[WP]R and more when Diameter common messages isn't
+%% advertised. In practice, diameter lets requests be sent as long as
+%% there's a dictionary configured to support it, peer selection by
+%% advertised application being possible to preempt by passing
+%% candidate peers directly to diameter:call/4. The peer can always
+%% answer 3001 (DIAMETER_COMMAND_UNSUPPORTED) or 3007
+%% (DIAMETER_APPLICATION_UNSUPPORTED) if this is objectionable.
common_applications(LCaps, RCaps, #diameter_service{applications = Apps}) ->
LA = app_union(LCaps),