From 5bd2d72eeede1ddc13fcaf483d48d88833c691da Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Fri, 6 Mar 2015 02:24:28 +0100 Subject: 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. --- lib/diameter/src/base/diameter_peer_fsm.erl | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'lib/diameter/src') 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. -- cgit v1.2.3