aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2015-03-06 02:24:28 +0100
committerAnders Svensson <[email protected]>2015-03-22 09:59:14 +0100
commit5bd2d72eeede1ddc13fcaf483d48d88833c691da (patch)
treeef698d6da827610bedfb8c7ded9f7e00fc19b175
parentaf87b1c3d4897840d8247589a88d3611106ecedc (diff)
downloadotp-5bd2d72eeede1ddc13fcaf483d48d88833c691da.tar.gz
otp-5bd2d72eeede1ddc13fcaf483d48d88833c691da.tar.bz2
otp-5bd2d72eeede1ddc13fcaf483d48d88833c691da.zip
Discard outgoing requests after outgoing DPR
RFC 6733 isn't terribly clear about what should happen to incoming or outgoing messages once DPR is sent and the Peer State Machine transitions into state Closing. There's no event for this in section 5.6, Peer State Machine, and no clarification in section 5.4, Disconnecting Peer Connections. There is a little bit of discussion in 2.1.1, SCTP Guidelines, in relation to unordered message delivery, but the tone there is that messages might be received after DPR because of unordered delivery, not because they were actually sent after DPR. Discarding outgoing answers may do more harm than good, but requests are more likely to be unexpected, as has been seen to be the case with DWR following DPR. DPR indicates a desire to close the connection: discard any subsequent outgoing requests.
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl27
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index ee6e7dd89e..e733e973ab 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
@@ -640,6 +640,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.