aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2015-08-13 12:34:00 +0200
committerErlang/OTP <[email protected]>2015-08-13 12:34:00 +0200
commite32557afa1ad7299c821c92446265daade52879a (patch)
treef32ab6f3fab2bf014730d8d12110fac8894dbc26 /lib
parent8929f163480085e2d2f2ab9eb14cf83080717da5 (diff)
parent9ab5d8afedc6d2f56997276e3f016ec1c6dac6a5 (diff)
downloadotp-e32557afa1ad7299c821c92446265daade52879a.tar.gz
otp-e32557afa1ad7299c821c92446265daade52879a.tar.bz2
otp-e32557afa1ad7299c821c92446265daade52879a.zip
Merge branch 'anders/diameter/decode/OTP-12891' into maint-17
* anders/diameter/decode/OTP-12891: Don't compute AVP list length unnecessarily at AVP decode
Diffstat (limited to 'lib')
-rw-r--r--lib/diameter/doc/src/diameter.xml8
-rw-r--r--lib/diameter/include/diameter_gen.hrl32
2 files changed, 22 insertions, 18 deletions
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index cb628f9529..854bc5b432 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -794,14 +794,6 @@ Messages larger than the specified number of bytes are discarded.</p>
Defaults to <c>16777215</c>, the maximum value of the 24-bit Message
Length field in a Diameter Header.</p>
-<warning>
-<p>
-This option should be set to as low a value as is sufficient for the
-Diameter applications and peers in question, since decoding incoming
-messages from a malicious peer can otherwise generate significant
-load.</p>
-</warning>
-
</item>
<tag><c>{restrict_connections, false
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 79b8e6ecde..ebe9e6363d 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -210,18 +210,27 @@ missing(Rec, Name, Failed) ->
sets:new(),
Failed),
[{5005, A} || F <- '#info-'(element(1, Rec), fields),
- not have_arity(avp_arity(Name, F), '#get-'(F, Rec)),
+ not has_arity(avp_arity(Name, F), '#get-'(F, Rec)),
#diameter_avp{code = C, vendor_id = V}
= A <- [empty_avp(F)],
not sets:is_element({C,V}, Avps)].
%% Maximum arities have already been checked in building the record.
-have_arity({Min, _}, L) ->
- Min =< length(L);
-have_arity(N, V) ->
+has_arity({Min, _}, L) ->
+ has_prefix(Min, L);
+has_arity(N, V) ->
N /= 1 orelse V /= undefined.
+%% Compare a non-negative integer and the length of a list without
+%% computing the length.
+has_prefix(0, _) ->
+ true;
+has_prefix(_, []) ->
+ false;
+has_prefix(N, L) ->
+ has_prefix(N-1, tl(L)).
+
%% empty_avp/1
empty_avp(Name) ->
@@ -589,14 +598,17 @@ pack(undefined, 1, FieldName, Avp, Acc) ->
%% AVP MUST be included and contain a copy of the first instance of
%% the offending AVP that exceeded the maximum number of occurrences
%%
+
pack(_, 1, _, Avp, {Rec, Failed}) ->
{Rec, [{5009, Avp} | Failed]};
-pack(L, {_, Max}, _, Avp, {Rec, Failed})
- when length(L) == Max ->
- {Rec, [{5009, Avp} | Failed]};
-
-pack(L, _, FieldName, Avp, Acc) ->
- p(FieldName, fun(V) -> [V|L] end, Avp, Acc).
+pack(L, {_, Max}, FieldName, Avp, Acc) ->
+ case '*' /= Max andalso has_prefix(Max, L) of
+ true ->
+ {Rec, Failed} = Acc,
+ {Rec, [{5009, Avp} | Failed]};
+ false ->
+ p(FieldName, fun(V) -> [V|L] end, Avp, Acc)
+ end.
%% p/4