aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/include
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-08-20 22:44:28 +0200
committerAnders Svensson <[email protected]>2014-09-08 14:26:02 +0200
commit0f9cdbaf4d7fde93d319be7789dd4119092d91c6 (patch)
tree80a32548715f91ba7325fba457aa3cf8e740465c /lib/diameter/include
parentdeb951bf382edaf7e8fcec7f57a94d798d2a460f (diff)
downloadotp-0f9cdbaf4d7fde93d319be7789dd4119092d91c6.tar.gz
otp-0f9cdbaf4d7fde93d319be7789dd4119092d91c6.tar.bz2
otp-0f9cdbaf4d7fde93d319be7789dd4119092d91c6.zip
Fix best effort decode of Failed-AVP
Commit c2c00fdd didn't get it quite right: it only decoded failed AVPs in the common dictionary since it's this dictionary an answer-message is decoded in. An extra dictionary isn't something that's easily passed through the decode without rewriting dictionary compilation however, and that's no small job, so continue with the use/abuse of the process dictionary by storing the dictionary module for the decode to retrieve. This is one step worse than previous uses since the dictionary is put in one module (diameter_codec) and got in another (the dictionary module), but it's the lesser of two evils.
Diffstat (limited to 'lib/diameter/include')
-rw-r--r--lib/diameter/include/diameter_gen.hrl38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 97cf0c7e29..233eb8dd15 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -311,7 +311,9 @@ d(Name, Avp, Acc) ->
Failed = relax(Name), %% Not AvpName or else a failed Failed-AVP
%% decode is packed into 'AVP'.
- try avp(decode, Data, AvpName) of
+ Mod = dict(Failed), %% Dictionary to decode in.
+
+ try Mod:avp(decode, Data, AvpName) of
V ->
{Avps, T} = Acc,
{H, A} = ungroup(V, Avp),
@@ -324,6 +326,25 @@ d(Name, Avp, Acc) ->
reset(?FAILED_KEY, Failed)
end.
+%% dict/1
+%%
+%% Retrieve the dictionary for the best-effort decode of Failed-AVP,
+%% as put by diameter_codec:decode/2. See that function for the
+%% explanation.
+
+dict(true) ->
+ case get({diameter_codec, dictionary}) of
+ undefined ->
+ ?MODULE;
+ Mod ->
+ Mod
+ end;
+
+dict(_) ->
+ ?MODULE.
+
+%% d/5
+
%% Ignore a decode error within Failed-AVP ...
d(true, _, Name, Avp, Acc) ->
decode_AVP(Name, Avp, Acc);
@@ -341,6 +362,8 @@ d(false, Reason, Name, Avp, {Avps, Acc}) ->
{Rec, Failed} = Acc,
{[Avp|Avps], {Rec, [rc(Reason, Avp) | Failed]}}.
+%% relax/2
+
%% Set false in the process dictionary as soon as we see a Grouped AVP
%% that doesn't set the M-bit, so that is_strict() can say whether or
%% not to ignore the M-bit on an encapsulated AVP.
@@ -357,22 +380,23 @@ relax(_, _) ->
is_strict() ->
false /= getr(?STRICT_KEY).
+%% relax/1
+%%
%% Set true in the process dictionary as soon as we see Failed-AVP.
%% Matching on 'Failed-AVP' assumes that this is the RFC AVP.
%% Strictly, this doesn't need to be the case.
+
relax('Failed-AVP') ->
- case getr(?FAILED_KEY) of
- undefined ->
- putr(?FAILED_KEY, true);
- true = Yes ->
- Yes
- end;
+ is_failed() orelse putr(?FAILED_KEY, true);
+
relax(_) ->
is_failed().
is_failed() ->
true == getr(?FAILED_KEY).
+%% reset/2
+
reset(Key, undefined) ->
eraser(Key);
reset(_, _) ->