aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-01-23 09:20:46 +0100
committerAnders Svensson <[email protected]>2014-01-24 16:03:05 +0100
commited6395a69435354c9d3d5accbd3adbfc45d5becf (patch)
tree08ae3b8ca16f93218482f69cc96861f455f63968
parent25237481ccccd3ddfa74582dc267632ad618ba30 (diff)
downloadotp-ed6395a69435354c9d3d5accbd3adbfc45d5becf.tar.gz
otp-ed6395a69435354c9d3d5accbd3adbfc45d5becf.tar.bz2
otp-ed6395a69435354c9d3d5accbd3adbfc45d5becf.zip
Change interface for communicating outbound stream id to diameter_sctp
The module uses the transport_data field of record diameter_packet to communicate the stream on which the an incoming message is received and on which an outgoing message should be sent, the previous interface being that both are communicated as a tuple of the form {stream, Id}. However, since diameter retains the value of an incoming request's transport_data unless the corresponding answer message specifies otherwise, the behaviour in this case is to send an answer on the outbound stream with the same identifier as the that of the inbound stream on which the request was received. If the inbound stream id is greater than or equal to the number of outbound streams then this is guaranteed to fail, causing the transport process in question to terminate. There is no relationship between inbound and outbound stream identifiers so diameter_sctp's imposition of one is simply wrong. Outbound stream ids are now communicated with a different tuple: {outstream, Id}, interpreted modulo the number of outbound streams. Thus, retention of an inbound request's transport_data has no effect on the selection of an outbound stream. The change in interface is not strictly backwards compatible because of the new atom for the outbound stream. However, as there is currently no documented way of obtaining the available number of outbound streams for a peer connection, there is no way for a client to have known the range of ids from which it could reliably have chosen with the previous interface, so any setting of the outbound stream has probably been unintentional. Not explicitly specifying an outbound stream now results in a round-robin selection.
-rw-r--r--lib/diameter/doc/src/diameter_sctp.xml36
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl10
2 files changed, 21 insertions, 25 deletions
diff --git a/lib/diameter/doc/src/diameter_sctp.xml b/lib/diameter/doc/src/diameter_sctp.xml
index 2be77e3dfd..021770b63a 100644
--- a/lib/diameter/doc/src/diameter_sctp.xml
+++ b/lib/diameter/doc/src/diameter_sctp.xml
@@ -15,7 +15,8 @@
<erlref>
<header>
<copyright>
-<year>2011</year><year>2013</year>
+<year>2011</year>
+<year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -113,7 +114,7 @@ and port respectively.</p>
<p>
Multiple <c>ip</c> options can be specified for a multihomed peer.
If none are specified then the values of <c>Host-IP-Address</c>
-in the <c>#diameter_service{}</c> record are used.
+in the <c>diameter_service</c> record are used.
(In particular, one of these must be specified.)
Option <c>port</c> defaults to 3868 for a listening transport and 0 for a
connecting transport.</p>
@@ -131,25 +132,18 @@ the buffer size.</p>
</warning>
<p>
-diameter_sctp uses the <c>transport_data</c> field of
-the <c>#diameter_packet{}</c> record to communicate the stream on which an
-inbound message has been received, or on which an outbound message
-should be sent: the value will be of the form <c>{stream, Id}</c>
-on an inbound message passed to a &app_handle_request; or
-&app_handle_answer; callback.
-For an outbound message, either <c>undefined</c> (explicitly or
-by receiving the outbound message as a <c>binary()</c>) or a tuple
-should be set in the return value of &app_handle_request;
-(typically by retaining the value passed into this function)
-or &app_prepare_request;.
-The value <c>undefined</c> uses a "next outbound stream" id and
-increments this modulo the total number outbound streams.
-That is, successive values of <c>undefined</c> cycle through all
-outbound streams.</p>
-
-<!-- TODO: Some way of getting at the number of available outbound -->
-<!-- streams. -->
-
+The <c>transport_data</c> field of record <c>diameter_packet</c>
+is used to communicate the stream on which an inbound message
+has been received, or on which an outbound message should be sent.
+The value will be of the form <c>{stream, Id}</c> for an inbound
+message passed to a &app_handle_request; or &app_handle_answer;
+callback.
+For an outbound message, <c>{outstream, Id}</c> in the return value of
+&app_handle_request; or &app_prepare_retransmit; sets the outbound
+stream, the stream id being interpreted modulo the number of outbound
+streams.
+Any other value, or not setting a value, causes successive such sends
+to cycle though all outbound streams.</p>
</desc>
</func>
diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl
index 49a530b4eb..7a4830e40c 100644
--- a/lib/diameter/src/transport/diameter_sctp.erl
+++ b/lib/diameter/src/transport/diameter_sctp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2014. 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
@@ -605,11 +605,13 @@ accept(_, Pid, #listener{ref = Ref, pending = {N,Q}} = S) ->
%% send/2
%% Outbound Diameter message on a specified stream ...
-send(#diameter_packet{bin = Bin, transport_data = {stream, SId}}, S) ->
- send(SId, Bin, S),
+send(#diameter_packet{bin = Bin, transport_data = {outstream, SId}},
+ #transport{streams = {_, OS}}
+ = S) ->
+ send(SId rem OS, Bin, S),
S;
-%% ... or not: rotate through all steams.
+%% ... or not: rotate through all streams.
send(Bin, #transport{streams = {_, OS},
os = N}
= S)