From 1fd9b919608b54e4d08340c45fe1cabb6975880c Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Tue, 29 Aug 2017 14:33:47 +0200 Subject: Delay rotation of diameter_sctp outbound streams For the same reason as unordered delivery is delayed in the grandparent commit. Delivery is ordered only within a stream, so until a second message is received from the peer, there's no guarantee that a second outgoing request won't be received before the initial capablities exchange message. Rotation begins upon reception of a second message from the peer, messages being sent on stream 0 until then. --- lib/diameter/src/transport/diameter_sctp.erl | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'lib/diameter') diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl index 0d8fb37629..86a98776c5 100644 --- a/lib/diameter/src/transport/diameter_sctp.erl +++ b/lib/diameter/src/transport/diameter_sctp.erl @@ -105,7 +105,7 @@ packet = true :: boolean() %% legacy transport_data? | raw, message_cb = false :: false | diameter:eval(), - unordered = false :: boolean() | 0 | 1, %% send unordered? + unordered = 1 :: boolean() | 0 | 1, %% send unordered? send = false :: pid() | boolean()}). %% sending process %% Monitor process state. @@ -678,15 +678,16 @@ send(#diameter_packet{transport_data = {outstream, SId}} = S) -> send(SId rem OS, Msg, S); -%% ... or not: send unordered on a lone stream ... -send(Msg, #transport{unordered = true} = S) -> - send(0, Msg, S); - -%% ... or rotate through all. -send(Msg, #transport{streams = {_, OS}, +%% ... or not: rotate when sending ordered ... +send(Msg, #transport{unordered = false, + streams = {_, OS}, os = N} = S) -> - send(N, Msg, S#transport{os = (N + 1) rem OS}). + send(N, Msg, S#transport{os = (N + 1) rem OS}); + +%% ... or send only on the first stream, possibly unordered. +send(Msg, S) -> + send(0, Msg, S). %% send/3 @@ -730,7 +731,6 @@ recv({_, #sctp_assoc_change{state = comm_up, %% Deal with different association id after peeloff on Solaris by %% taking the id from the first reception. up(S#transport{assoc_id = T == accept orelse Id, - unordered = 1 == OS andalso 1, streams = {IS, OS}}); %% ... or not: try the next address. @@ -785,11 +785,14 @@ recv(#transport{unordered = B} = S) when is_boolean(B) -> S; -recv(#transport{unordered = 0, socket = Sock} = S) -> +recv(#transport{unordered = 0, streams = {_, 1}, socket = Sock} = S) -> ok = inet:setopts(Sock, [{sctp_default_send_param, #sctp_sndrcvinfo{flags = [unordered]}}]), S#transport{unordered = true}; +recv(#transport{unordered = 0} = S) -> + S#transport{unordered = false}; + recv(#transport{unordered = N} = S) -> S#transport{unordered = N-1}. -- cgit v1.2.3