aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_types.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2015-03-20 02:18:06 +0100
committerAnders Svensson <[email protected]>2015-03-24 11:02:05 +0100
commitb8a7df45c9e57a832f7db9b9b875b31d0ab7d29c (patch)
tree31c582bcb62cdfa0a1fbf51b47741af4eb94b521 /lib/diameter/src/base/diameter_types.erl
parent35f564094033ea2eb4c5b01d0d0b1c0d629ea5b1 (diff)
downloadotp-b8a7df45c9e57a832f7db9b9b875b31d0ab7d29c.tar.gz
otp-b8a7df45c9e57a832f7db9b9b875b31d0ab7d29c.tar.bz2
otp-b8a7df45c9e57a832f7db9b9b875b31d0ab7d29c.zip
Adapt to changed DiameterURI defaults in RFC 6733
Despite claims of full backwards compatibility, the text of RFC 6733 changes the interpretation of unspecified values in a DiameterURI. In particular, 3588 says that the default port and transport are 3868 and sctp respectively, while 6733 says it's either 3868/tcp (aaa) or 5658/tcp (aaas). The 3588 defaults were used regardless, but now use them only if the common dictionary is diameter_gen_base_rfc3588. The 6733 defaults are used otherwise. This kind of change in the standard can lead to interop problems, since a node has to know which RFC its peer is following to know that it will properly interpret missing URI components. Encode of a URI includes all components to avoid such confusion. That said, note that the defaults in the diameter_uri record have *not* been changed. This avoids breaking code that depends on them, but the risk is that such code sends inappropriate values. The record defaults may be changed in a future release, to force values to be explicitly specified.
Diffstat (limited to 'lib/diameter/src/base/diameter_types.erl')
-rw-r--r--lib/diameter/src/base/diameter_types.erl68
1 files changed, 57 insertions, 11 deletions
diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl
index 8497329c20..fe7613541c 100644
--- a/lib/diameter/src/base/diameter_types.erl
+++ b/lib/diameter/src/base/diameter_types.erl
@@ -313,18 +313,19 @@
(T == tcp orelse T == sctp orelse T == udp),
(P == diameter orelse P == radius orelse P == 'tacacs+'),
(P /= diameter orelse T /= udp) ->
- #diameter_uri{port = PN0,
- transport = T0,
- protocol = P0}
- = #diameter_uri{},
iolist_to_binary([atom_to_list(Type), "://", DN,
":", integer_to_list(PN),
";transport=", atom_to_list(T),
";protocol=", atom_to_list(P)]);
+%% Don't omit defaults since they're dependent on whether RFC 3588 or
+%% 6733 is being followed. For one, we don't know this at encode; for
+%% two (more importantly), we don't know how the peer will interpret
+%% defaults, so it's best to be explicit. Interpret defaults on decode
+%% since there's no choice.
'DiameterURI'(encode, Str) ->
Bin = iolist_to_binary(Str),
- #diameter_uri{} = scan_uri(Bin), %% type check
+ #diameter_uri{} = scan_uri(Bin), %% assert
Bin.
%% --------------------
@@ -523,6 +524,45 @@ msb(false) -> ?TIME_2036.
%%
%% aaa-protocol = ( "diameter" / "radius" / "tacacs+" )
+%% RFC 6733, 4.3.1, changes the defaults:
+%%
+%% "aaa://" FQDN [ port ] [ transport ] [ protocol ]
+%%
+%% ; No transport security
+%%
+%% "aaas://" FQDN [ port ] [ transport ] [ protocol ]
+%%
+%% ; Transport security used
+%%
+%% FQDN = < Fully Qualified Domain Name >
+%%
+%% port = ":" 1*DIGIT
+%%
+%% ; One of the ports used to listen for
+%% ; incoming connections.
+%% ; If absent, the default Diameter port
+%% ; (3868) is assumed if no transport
+%% ; security is used and port 5658 when
+%% ; transport security (TLS/TCP and DTLS/SCTP)
+%% ; is used.
+%%
+%% transport = ";transport=" transport-protocol
+%%
+%% ; One of the transports used to listen
+%% ; for incoming connections. If absent,
+%% ; the default protocol is assumed to be TCP.
+%% ; UDP MUST NOT be used when the aaa-protocol
+%% ; field is set to diameter.
+%%
+%% transport-protocol = ( "tcp" / "sctp" / "udp" )
+%%
+%% protocol = ";protocol=" aaa-protocol
+%%
+%% ; If absent, the default AAA protocol
+%% ; is Diameter.
+%%
+%% aaa-protocol = ( "diameter" / "radius" / "tacacs+" )
+
scan_uri(Bin) ->
RE = "^(aaas?)://"
"([-a-zA-Z0-9.]+)"
@@ -532,15 +572,21 @@ scan_uri(Bin) ->
{match, [A, DN, PN, T, P]} = re:run(Bin,
RE,
[{capture, [1,2,4,6,8], binary}]),
- #diameter_uri{port = PN0,
- transport = T0,
- protocol = P0}
- = #diameter_uri{},
- #diameter_uri{type = to_atom(A),
+ Type = to_atom(A),
+ {PN0, T0} = defaults(diameter_codec:getopt(rfc), Type),
+ #diameter_uri{type = Type,
fqdn = from_bin(DN),
port = to_int(PN, PN0),
transport = to_atom(T, T0),
- protocol = to_atom(P, P0)}.
+ protocol = to_atom(P, diameter)}.
+
+%% Choose defaults based on the RFC, since 6733 has changed them.
+defaults(3588, _) ->
+ {3868, sctp};
+defaults(6733, aaa) ->
+ {3868, tcp};
+defaults(6733, aaas) ->
+ {5658, tcp}.
from_bin(B) ->
case diameter_codec:getopt(string_decode) of