aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-08-29 14:33:47 +0200
committerAnders Svensson <[email protected]>2017-08-29 22:29:49 +0200
commit1fd9b919608b54e4d08340c45fe1cabb6975880c (patch)
tree41790f21a72601a9eac6f2a292f8e2d18b4d5b60
parent549a82df3ae250b7c5598a9451b7b9802073d6f9 (diff)
downloadotp-1fd9b919608b54e4d08340c45fe1cabb6975880c.tar.gz
otp-1fd9b919608b54e4d08340c45fe1cabb6975880c.tar.bz2
otp-1fd9b919608b54e4d08340c45fe1cabb6975880c.zip
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.
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl23
1 files changed, 13 insertions, 10 deletions
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}.