diff options
author | Anders Svensson <[email protected]> | 2014-05-23 18:28:19 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2014-05-26 17:14:59 +0200 |
commit | 58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b (patch) | |
tree | 1291a8c77203567708bf5f0857016241b3503a98 /lib/diameter/include | |
parent | da356f2e79b2cf5e767cb11cc643beab086e5263 (diff) | |
download | otp-58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b.tar.gz otp-58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b.tar.bz2 otp-58a74f2b6b6bd604d60fa8dca347cdd4ad2e4a3b.zip |
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.hrl | 17 |
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 -> |