aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/diameter/doc/src/notes.xml30
-rw-r--r--lib/diameter/src/base/diameter_codec.erl20
-rw-r--r--lib/diameter/src/base/diameter_types.erl21
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl26
-rw-r--r--lib/diameter/src/diameter.appup.src10
-rw-r--r--lib/diameter/vsn.mk2
6 files changed, 85 insertions, 24 deletions
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index 274a3f594c..1a955a5898 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -42,6 +42,36 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 1.4.4</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Fix setting of End-to-End and Hop-by-Hop Identifiers in
+ outgoing DWA.</p>
+ <p>
+ Broken by OTP-11184, which caused the identifiers to be
+ set anew, discarding the values from the incoming DWR.</p>
+ <p>
+ Own Id: OTP-11367</p>
+ </item>
+ <item>
+ <p>
+ Fix handling of 5014, DIAMETER_INVALID_AVP_LENGTH.</p>
+ <p>
+ The error was detected as 5004,
+ DIAMETER_INVALID_AVP_VALUE, for some Diameter types, in
+ which case an AVP length that pointed past the end of a
+ message resulted in encode failure.</p>
+ <p>
+ Own Id: OTP-11395</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>diameter 1.4.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 1d647b8c87..0de4d53973 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -477,8 +477,11 @@ split_head(<<Code:32, 1:1, M:1, P:1, _:5, Len:24, V:32, _/bitstring>>) ->
split_head(<<Code:32, 0:1, M:1, P:1, _:5, Len:24, _/bitstring>>) ->
{Code, undefined, M, P, Len, 8};
-split_head(Bin) ->
- ?THROW({5014, #diameter_avp{data = Bin}}).
+%% Header is truncated: pack_avp/1 will pad to the minimum header
+%% length.
+split_head(B)
+ when is_bitstring(B) ->
+ ?THROW({5014, #diameter_avp{data = B}}).
%% 3588:
%%
@@ -523,9 +526,8 @@ split_data(_, _, _) ->
%% split_data/4
split_data(Bin, HdrLen, Len, Pad) ->
- <<_:HdrLen/binary, T/bitstring>> = Bin,
- case T of
- <<Data:Len/binary, _:Pad/binary, Rest/bitstring>> ->
+ case Bin of
+ <<_:HdrLen/binary, Data:Len/binary, _:Pad/binary, Rest/bitstring>> ->
{Data, Rest};
_ ->
invalid_avp_length()
@@ -573,15 +575,15 @@ pack_avp(#diameter_avp{data = {Dict, Name, Value}} = A) ->
{Name, Type} = Dict:avp_name(Code, Vid),
pack_avp(A#diameter_avp{data = {Hdr, {Type, Value}}});
-pack_avp(#diameter_avp{code = undefined, data = Bin})
- when is_binary(Bin) ->
+pack_avp(#diameter_avp{code = undefined, data = B})
+ when is_bitstring(B) ->
%% Reset the AVP Length of an AVP Header resulting from a 5014
%% error. The RFC doesn't explicitly say to do this but the
%% receiver can't correctly extract this and following AVP's
%% without a correct length. On the downside, the header doesn't
%% reveal if the received header has been padded.
- Pad = 8*header_length(Bin) - bit_size(Bin),
- Len = size(<<H:5/binary, _:24, T/binary>> = <<Bin/bitstring, 0:Pad>>),
+ Pad = 8*header_length(B) - bit_size(B),
+ Len = size(<<H:5/binary, _:24, T/binary>> = <<B/bitstring, 0:Pad>>),
<<H/binary, Len:24, T/binary>>;
%% ... or as an iolist.
diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl
index 8c07e84777..ca3338be5f 100644
--- a/lib/diameter/src/base/diameter_types.erl
+++ b/lib/diameter/src/base/diameter_types.erl
@@ -92,6 +92,9 @@
when is_binary(Bin) ->
binary_to_list(Bin);
+'OctetString'(decode, B) ->
+ ?INVALID_LENGTH(B);
+
'OctetString'(encode = M, zero) ->
'OctetString'(M, []);
@@ -255,9 +258,7 @@
2 == A, 16 == size(B) ->
list_to_tuple([N || <<N:A/unit:8>> <= B]);
-'Address'(decode, <<A:16, _/binary>> = B)
- when 1 == A;
- 2 == A ->
+'Address'(decode, B) ->
?INVALID_LENGTH(B);
'Address'(encode, T) ->
@@ -278,7 +279,10 @@
<<_,_/binary>> = 'OctetString'(M, X);
'DiameterIdentity'(decode = M, <<_,_/binary>> = X) ->
- 'OctetString'(M, X).
+ 'OctetString'(M, X);
+
+'DiameterIdentity'(decode, X) ->
+ ?INVALID_LENGTH(X).
%% --------------------
@@ -286,6 +290,9 @@
when is_binary(Bin) ->
scan_uri(Bin);
+'DiameterURI'(decode, B) ->
+ ?INVALID_LENGTH(B);
+
%% The minimal DiameterURI is "aaa://x", 7 characters.
'DiameterURI'(encode = M, zero) ->
'OctetString'(M, lists:duplicate(0,7));
@@ -330,9 +337,13 @@
%% --------------------
-'UTF8String'(decode, Bin) ->
+'UTF8String'(decode, Bin)
+ when is_binary(Bin) ->
tl([0|_] = unicode:characters_to_list([0, Bin])); %% assert list return
+'UTF8String'(decode, B) ->
+ ?INVALID_LENGTH(B);
+
'UTF8String'(encode = M, zero) ->
'UTF8String'(M, []);
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index 7e75801718..127a647b89 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -461,15 +461,28 @@ eraser(Key) ->
%% encode/3
-encode(Msg, Mask, Dict) ->
+encode(dwr = M, Dict0, Mask) ->
+ Msg = getr(M),
Seq = diameter_session:sequence(Mask),
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
end_to_end_id = Seq,
hop_by_hop_id = Seq},
Pkt = #diameter_packet{header = Hdr,
msg = Msg},
- #diameter_packet{bin = Bin} = diameter_codec:encode(Dict, Pkt),
- Bin.
+ #diameter_packet{bin = Bin} = diameter_codec:encode(Dict0, Pkt),
+ Bin;
+
+
+encode(dwa, Dict0, #diameter_packet{header = H, transport_data = TD}
+ = ReqPkt) ->
+ AnsPkt = #diameter_packet{header
+ = H#diameter_header{is_request = false,
+ is_error = undefined,
+ is_retransmitted = false},
+ msg = dwa(ReqPkt),
+ transport_data = TD},
+
+ diameter_codec:encode(Dict0, AnsPkt).
%% okay/3
@@ -527,7 +540,7 @@ send_watchdog(#watchdog{pending = false,
dictionary = Dict0,
sequence = Mask}
= S) ->
- send(TPid, {send, encode(getr(dwr), Mask, Dict0)}),
+ send(TPid, {send, encode(dwr, Dict0, Mask)}),
?LOG(send, 'DWR'),
S#watchdog{pending = true}.
@@ -546,9 +559,8 @@ recv(Name, Pkt, S) ->
%% rcv/3
rcv('DWR', Pkt, #watchdog{transport = TPid,
- dictionary = Dict0,
- sequence = Mask}) ->
- send(TPid, {send, encode(dwa(Pkt), Mask, Dict0)}),
+ dictionary = Dict0}) ->
+ send(TPid, {send, encode(dwa, Dict0, Pkt)}),
?LOG(send, 'DWA');
rcv(N, _, _)
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index c6828e6705..76fb54e03a 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -35,7 +35,10 @@
{load_module, diameter_config},
{load_module, diameter_service},
{load_module, diameter_peer_fsm},
- {load_module, diameter_watchdog}]}
+ {load_module, diameter_watchdog}]},
+ {"1.4.3", [{load_module, diameter_watchdog}, %% R16B02
+ {load_module, diameter_codec},
+ {load_module, diameter_types}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -49,6 +52,9 @@
{"1.4", [{restart_application, diameter}]},
{"1.4.1", [{restart_application, diameter}]},
{"1.4.1.1", [{restart_application, diameter}]},
- {"1.4.2", [{restart_application, diameter}]}
+ {"1.4.2", [{restart_application, diameter}]},
+ {"1.4.3", [{load_module, diameter_types},
+ {load_module, diameter_codec},
+ {load_module, diameter_watchdog}]}
]
}.
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index e003fe76b9..023c5307b2 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -18,5 +18,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 1.4.3
+DIAMETER_VSN = 1.4.4
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)