aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2015-03-23 12:37:14 +0100
committerAnders Svensson <[email protected]>2015-03-23 12:37:14 +0100
commit88c8959a685ee5c296d57e9d50de46dbb19cc1df (patch)
treec5bb029037028fc76b6952d6866a1097d86c08c0 /lib/diameter/src
parent7a4967882b44e9048949bd8dc6cb6e953ea0c1c9 (diff)
parentb1fd629917c2dc4563038f21e0727e2c85b6d07c (diff)
downloadotp-88c8959a685ee5c296d57e9d50de46dbb19cc1df.tar.gz
otp-88c8959a685ee5c296d57e9d50de46dbb19cc1df.tar.bz2
otp-88c8959a685ee5c296d57e9d50de46dbb19cc1df.zip
Merge branch 'anders/diameter/dpr/OTP-12543' into maint
* anders/diameter/dpr/OTP-12543: Discard incoming requests after outgoing DPR Discard outgoing requests after outgoing DPR
Diffstat (limited to 'lib/diameter/src')
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl50
1 files changed, 42 insertions, 8 deletions
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index ee6e7dd89e..23bba701eb 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -397,8 +397,8 @@ transition({timeout, _}, _) ->
ok;
%% Outgoing message.
-transition({send, Msg}, #state{transport = TPid}) ->
- send(TPid, Msg),
+transition({send, Msg}, S) ->
+ outgoing(Msg, S),
ok;
%% Request for graceful shutdown at remove_transport, stop_service of
@@ -516,12 +516,9 @@ encode(Rec, Dict) ->
recv(#diameter_packet{header = #diameter_header{} = Hdr}
= Pkt,
- #state{parent = Pid,
- dictionary = Dict0}
+ #state{dictionary = Dict0}
= S) ->
- Name = diameter_codec:msg_name(Dict0, Hdr),
- Pid ! {recv, self(), Name, Pkt},
- rcv(Name, Pkt, S);
+ recv1(diameter_codec:msg_name(Dict0, Hdr), Pkt, S);
recv(#diameter_packet{header = undefined,
bin = Bin}
@@ -532,6 +529,22 @@ recv(#diameter_packet{header = undefined,
recv(Bin, S) ->
recv(#diameter_packet{bin = Bin}, S).
+%% recv1/3
+
+%% Incoming request after DPR has been sent: discard. Don't discard
+%% DPR, so both ends don't do so when sending simultaneously.
+recv1(Name,
+ #diameter_packet{header = #diameter_header{is_request = true} = H},
+ #state{dpr = {_,_}})
+ when Name /= 'DPR' ->
+ invalid(false, recv_after_dpr, H);
+
+%% Any other message with a header and no length errors: send to the
+%% parent.
+recv1(Name, Pkt, #state{parent = Pid} = S) ->
+ Pid ! {recv, self(), Name, Pkt},
+ rcv(Name, Pkt, S).
+
%% recv/3
recv(#diameter_header{length = Len}
@@ -640,6 +653,27 @@ incr_error(Dir, Pkt, Dict0) ->
send(Pid, Msg) ->
diameter_peer:send(Pid, Msg).
+%% outgoing/2
+
+%% DPR not sent: send.
+outgoing(Msg, #state{transport = TPid, dpr = false}) ->
+ send(TPid, Msg);
+
+%% Outgoing answer: send.
+outgoing(#diameter_packet{header = #diameter_header{is_request = false}}
+ = Pkt,
+ #state{transport = TPid}) ->
+ send(TPid, Pkt);
+
+%% Outgoing request: discard.
+outgoing(Msg, #state{dpr = {_,_}}) ->
+ invalid(false, send_after_dpr, header(Msg)).
+
+header(#diameter_packet{header = H}) ->
+ H;
+header(Bin) -> %% DWR
+ diameter_codec:decode_header(Bin).
+
%% handle_request/3
%%
%% Incoming CER or DPR.