aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2015-03-06 08:51:23 +0100
committerAnders Svensson <[email protected]>2015-03-22 10:00:02 +0100
commitb1fd629917c2dc4563038f21e0727e2c85b6d07c (patch)
treef2e7b2756b88111131fb3b8df92f0a620edfcbd4 /lib/diameter/src
parent5bd2d72eeede1ddc13fcaf483d48d88833c691da (diff)
downloadotp-b1fd629917c2dc4563038f21e0727e2c85b6d07c.tar.gz
otp-b1fd629917c2dc4563038f21e0727e2c85b6d07c.tar.bz2
otp-b1fd629917c2dc4563038f21e0727e2c85b6d07c.zip
Discard incoming requests after outgoing DPR
Since there's a race between an answer being sent and the connection being closed upon the reception of DPA that's likely to be lost, and because of the questionability of sending messages after DPR, as discussed in the parent commit. An exception is made for DPR so that simultaneous DPR in both directions doesn't result in it being discarded on both ends.
Diffstat (limited to 'lib/diameter/src')
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl23
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index e733e973ab..23bba701eb 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -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}