diff options
author | Anders Svensson <[email protected]> | 2015-02-16 09:11:50 +0100 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2015-02-17 02:29:19 +0100 |
commit | ebe60da137dafe659d9577e1c6411bcc1ea431af (patch) | |
tree | 6a307424b19e0f4667e4245feabe360cbf3afc79 /lib/diameter | |
parent | 60ddb0dc9e5c1e28aa01548b01310744fd9ede15 (diff) | |
download | otp-ebe60da137dafe659d9577e1c6411bcc1ea431af.tar.gz otp-ebe60da137dafe659d9577e1c6411bcc1ea431af.tar.bz2 otp-ebe60da137dafe659d9577e1c6411bcc1ea431af.zip |
Don't discard component diameter_avp list on Grouped AVP decode error
The AVPs of an incoming Diameter message diameter_codec:decode/2,3 are
decoded into a diameter_packet record in two ways: as a message-specific
record in the 'msg' field and as a deep list of diameter_avp records in
the 'avps' field. The record decode came first; the diameter_avp decode
came later to support the Diameter relay application, but can also be
convenient for non-relay applications. The diameter_avp representation
can be used with outgoing messages, but what exactly is supported for
isn't clearly documented.
In the diameter_avp list representation, it's AVPs of type Grouped that
lead to nesting: instead of a diameter_avp record, a Grouped AVP is
represented by a diameter_avp list whose head is the Grouped AVP itself,
and whose tail is the list of component AVPs.
The diameter_avp decode was broken in the case of decode errors: the
Grouped AVP was represented as a bare diameter_avp, and the component
records were lost. The decode now produces the intended list. Note that
component AVPs that could not be decoded will have 'undefined' in their
data field.
Diffstat (limited to 'lib/diameter')
-rw-r--r-- | lib/diameter/include/diameter_gen.hrl | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl index 49287b3f70..8916286275 100644 --- a/lib/diameter/include/diameter_gen.hrl +++ b/lib/diameter/include/diameter_gen.hrl @@ -323,12 +323,19 @@ d(Name, Avp, Acc) -> %% decode is packed into 'AVP'. Mod = dict(Failed), %% Dictionary to decode in. + %% On decode, a Grouped AVP is represented as a #diameter_avp{} + %% list with AVP as head and component AVPs as tail. On encode, + %% data can be a list of component AVPs. + try Mod:avp(decode, Data, AvpName) of V -> {Avps, T} = Acc, {H, A} = ungroup(V, Avp), {[H | Avps], pack_avp(Name, A, T)} catch + throw: {?TAG, {grouped, RC, ComponentAvps}} -> + {Avps, {Rec, Failed}} = Acc, + {[[Avp | ComponentAvps] | Avps], {Rec, [{RC, Avp} | Failed]}}; error: Reason -> d(undefined == Failed orelse is_failed(), Reason, @@ -599,11 +606,11 @@ value(_, Avp) -> | no_return(). grouped_avp(decode, Name, Data) -> - {Rec, Avps, []} = decode_avps(Name, diameter_codec:collect_avps(Data)), + {Rec, Avps, Es} = decode_avps(Name, diameter_codec:collect_avps(Data)), + [] == Es orelse throw({?TAG, {grouped, 5004, Avps}}), %% decode failure {Rec, Avps}; -%% A failed match here will result in 5004. Note that this is the only -%% AVP type that doesn't just return the decoded record, also -%% returning the list of component AVP's. +%% Note that this is the only AVP type that doesn't just return the +%% decoded record, also returning the list of component AVP's. grouped_avp(encode, Name, Data) -> encode_avps(Name, Data). |