summaryrefslogtreecommitdiff
path: root/lib/diameter/include
diff options
context:
space:
mode:
authorAnders Svensson <anders@erlang.org>2014-05-23 18:28:19 +0200
committerAnders Svensson <anders@erlang.org>2014-05-26 17:14:59 +0200
commit58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b (patch)
tree1291a8c77203567708bf5f0857016241b3503a98 /lib/diameter/include
parentda356f2e79b2cf5e767cb11cc643beab086e5263 (diff)
downloaderlang-58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b.tar.gz
Fix handling of AVP length errors (5014) in unknown AVPs
Commit 4ce2d3a6 added the insertion of a single bit into binary AVP data to induce an encode error in the case of a header length that pointed past the available bytes: a 5014 = DIAMETER_INVALID_AVP_LENGTH error. Commit 838856b fixed this for stringish Diameter types, but both commits neglected the case in which the offending AVP isn't known to the dictionary in question. Unless the AVP was regarded as erroneous for other reasons (eg. an M-bit resulting in 5001) it would be happily be packed into an 'AVP' field. If it was regarded as an error, the record could be passed back to diameter_codec:pack_avp/1, and if the record contained header data then there was no clause to deal with the unpleasantry. Deal with it by having the dictionary module strip the extra bit and flag the AVP as 5014, and by having diameter_codec handle any extra bit coming from an dictionary compiled against an old diameter_gen. An old dictionary won't detect 5014 however, so dictionaries should be recompiled. Change most of the guards in diameter_codec from is_bitstring/1 to is_binary/1. What's being passed to the decode functions are binaries received other the network. The only case in which a non-binary bitstring is when we've placed an extra bit there ourselves. (Modulo someone doing something they shouldn't.)
Diffstat (limited to 'lib/diameter/include')
-rw-r--r--lib/diameter/include/diameter_gen.hrl17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 319ad5a783..ebc10b8918 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -412,6 +412,23 @@ pack_avp(_, Arity, Avp, Acc) ->
%% pack_AVP/3
+%% Length failure was induced because of a header/payload length
+%% mismatch. The AVP Length is reset to match the received data if
+%% this AVP is encoded in an answer message, since the length is
+%% computed.
+%%
+%% Data is a truncated header if command_code = undefined, otherwise
+%% payload bytes. The former is padded to the length of a header if
+%% the AVP reaches an outgoing encode in diameter_codec.
+%%
+%% RFC 6733 says that an AVP returned with 5014 can contain a minimal
+%% payload for the AVP's type, but in this case we don't know the
+%% type.
+
+pack_AVP(_, #diameter_avp{data = <<0:1, Data/binary>>} = Avp, Acc) ->
+ {Rec, Failed} = Acc,
+ {Rec, [{5014, Avp#diameter_avp{data = Data}} | Failed]};
+
pack_AVP(Name, #diameter_avp{is_mandatory = M} = Avp, Acc) ->
case pack_arity(Name, M) of
0 ->