aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_traffic.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2015-03-25 07:21:46 +0100
committerAnders Svensson <[email protected]>2015-03-27 07:21:26 +0100
commit545ff7783cebddc2ca5b2af67a6f13b1a01a4d03 (patch)
treeaa5ea245e6bd77ee5df12e61f682a3f5903e270e /lib/diameter/src/base/diameter_traffic.erl
parentaaff5f36b836c65a72fb38a27e31a88d199a3155 (diff)
downloadotp-545ff7783cebddc2ca5b2af67a6f13b1a01a4d03.tar.gz
otp-545ff7783cebddc2ca5b2af67a6f13b1a01a4d03.tar.bz2
otp-545ff7783cebddc2ca5b2af67a6f13b1a01a4d03.zip
Add service_opt() incoming_maxlen
To bound the length of incoming messages that will be decoded. A message longer than the specified number of bytes is discarded. An incoming_maxlen_exceeded counter is incremented to make note of the occurrence. The motivation is to prevent a sufficiently malicious peer from generating significant load by sending long messages with many AVPs for diameter to decode. The 24-bit message length header accomodates (16#FFFFFF - 20) div 12 = 1398099 Unsigned32 AVPs for example, which the current record-valued decode is too slow with in practice. A bound of 16#FFFF bytes allows for 5461 small AVPs, which is probably more than enough for the majority of applications, but the default is the full 16#FFFFFF.
Diffstat (limited to 'lib/diameter/src/base/diameter_traffic.erl')
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index 784f9ca08f..538ebeeeba 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -78,7 +78,11 @@
service_name :: diameter:service_name(),
apps :: [#diameter_app{}],
sequence :: diameter:sequence(),
- codec :: list()}).
+ codec :: [{string_decode, boolean()}
+ | {incoming_maxlen, diameter:message_length()}]}).
+%% Note that incoming_maxlen is currently handled in diameter_peer_fsm,
+%% so that any message exceeding the maximum is discarded. Retain the
+%% option in case we want to extend the values and semantics.
%% Record stored in diameter_request for each outgoing request.
-record(request,
@@ -102,7 +106,9 @@ make_recvdata([SvcName, PeerT, Apps, SvcOpts | _]) ->
peerT = PeerT,
apps = Apps,
sequence = Mask,
- codec = [T || {K,_} = T <- SvcOpts, K == string_decode]}.
+ codec = [T || {K,_} = T <- SvcOpts,
+ lists:member(K, [string_decode,
+ incoming_maxlen])]}.
%% ---------------------------------------------------------------------------
%% peer_up/1
@@ -233,6 +239,8 @@ receive_message(TPid, Pkt, Dict0, RecvData)
Dict0,
RecvData).
+%% recv/6
+
%% Incoming request ...
recv(true, false, TPid, Pkt, Dict0, T) ->
spawn_request(TPid, Pkt, Dict0, T);
@@ -240,6 +248,7 @@ recv(true, false, TPid, Pkt, Dict0, T) ->
%% ... answer to known request ...
recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) ->
Pid ! {answer, Ref, Req, Dict0, Pkt};
+
%% Note that failover could have happened prior to this message being
%% received and triggering failback. That is, both a failover message
%% and answer may be on their way to the handler process. In the worst
@@ -1693,6 +1702,8 @@ send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) ->
end.
%% recv/4
+%%
+%% Relay an answer from a remote node.
recv(TPid, Pid, TRef, Ref) ->
receive