Use unordered delivery on a lone outbound stream in diameter_sctp
Use unordered delivery on a lone outbound stream in diameter_sctp

RFC 6733 say the below about head-of-line blocking and SCTP, the
suggestion of unordered sending being new compared to the RFC 3588.
Until now, all delivery in diameter_sctp has been ordered, and
roundrobin over available streams unless the user passes a stream
identifier in an outgoing diameter_packet record. This commit changes
this to use unordered delivery when there's only a single outbound
stream to choose from.

The special case at capabilities exchange is handled by only starting to
send unordered after the second message from the peer has been received.
(First message after capabilities exchange, as the RFC probably means.)
The special case at DPR isn't handled, since there's no knowing the
order in which a peer will answer: a node that sends DPR while it has
other requests outstanding can't expect that the latter will be answered
before DPR, even if delivery is ordered since incoming requests are
handled concurrently. If it wants a guarantee then it simply has to wait
for answers before sending DPR.

A user can force all delivery to be unordered by specifying

  {sctp_default_send_params, #sctp_sndrcvinfo{flags = [unordered]}}

as a config option to diameter_sctp, but in this case there's no
handling of a request being sent directly after CEA since there's no
ordered flag to override the default.

RFC 6733:

2.1.1.  SCTP Guidelines

   Diameter messages SHOULD be mapped into SCTP streams in a way that
   avoids head-of-the-line (HOL) blocking.  Among different ways of
   performing the mapping that fulfill this requirement it is
   RECOMMENDED that a Diameter node send every Diameter message (request
   or response) over stream zero with the unordered flag set.  However,
   Diameter nodes MAY select and implement other design alternatives for
   avoiding HOL blocking such as using multiple streams with the
   unordered flag cleared (as originally instructed in RFC 3588).  On
   the receiving side, a Diameter entity MUST be ready to receive
   Diameter messages over any stream, and it is free to return responses
   over a different stream.  This way, both sides manage the available
   streams in the sending direction, independently of the streams chosen
   by the other side to send a particular Diameter message.  These
   messages can be out-of-order and belong to different Diameter
   sessions.

   Out-of-order delivery has special concerns during a connection
   establishment and termination.  When a connection is established, the
   responder side sends a CEA message and moves to R-Open state as
   specified in Section 5.6.  If an application message is sent shortly
   after the CEA and delivered out-of-order, the initiator side, still
   in Wait-I-CEA state, will discard the application message and close
   the connection.  In order to avoid this race condition, the receiver
   side SHOULD NOT use out-of-order delivery methods until the first
   message has been received from the initiator, proving that it has
   moved to I-Open state.  To trigger such a message, the receiver side
   could send a DWR immediately after sending a CEA.  Upon reception of
   the corresponding DWA, the receiver side should start using out-of-
   order delivery methods to counter the HOL blocking.

   Another race condition may occur when DPR and DPA messages are used.
   Both DPR and DPA are small in size; thus, they may be delivered to
   the peer faster than application messages when an out-of-order
   delivery mechanism is used.  Therefore, it is possible that a DPR/DPA
   exchange completes while application messages are still in transit,
   resulting in a loss of these messages.  An implementation could
   mitigate this race condition, for example, using timers, and wait for
   a short period of time for pending application level messages to
   arrive before proceeding to disconnect the transport connection.
   Eventually, lost messages are handled by the retransmission mechanism
   described in Section 5.5.4.

cobusc/otp,jj1bdx/otp,vinoski/otp,lrascao/otp,falkevik/otp,rlipscombe/otp,potatosalad/otp,rlipscombe/otp,bernardd/otp,kvakvs/otp,rlipscombe/otp,vinoski/otp,RoadRunnr/otp,goertzenator/otp,fenollp/otp,saleyn/otp,vinoski/otp,vladdu/otp,kvakvs/otp,dumbbell/otp,potatosalad/otp,emacsmirror/erlang,getong/otp,saleyn/otp,dgud/otp,emacsmirror/erlang,jj1bdx/otp,kvakvs/otp,getong/otp,bernardd/otp,saleyn/otp,mikpe/otp,getong/otp,mikpe/otp,saleyn/otp,saleyn/otp,getong/otp,jj1bdx/otp,g-andrade/otp,RaimoNiskanen/otp,uabboli/otp,matwey/otp,ferd/otp,vinoski/otp,vinoski/otp,bjorng/otp,saleyn/otp,erlang/otp,vinoski/otp,legoscia/otp,fenollp/otp,erlang/otp,emacsmirror/erlang,emacsmirror/erlang,emacsmirror/erlang,dgud/otp,emacsmirror/erlang,electricimp/otp,getong/otp,RoadRunnr/otp,dumbbell/otp,getong/otp,bernardd/otp,isvilen/otp,rlipscombe/otp,aboroska/otp,kvakvs/otp,falkevik/otp,matwey/otp,fenollp/otp,bernardd/otp,kvakvs/otp,uabboli/otp,bjorng/otp,cobusc/otp,getong/otp,potatosalad/otp,g-andrade/otp,bjorng/otp,jj1bdx/otp,isvilen/otp,vinoski/otp,erlang/otp,jj1bdx/otp,dumbbell/otp,dumbbell/otp,matwey/otp,erlang/otp,dgud/otp,goertzenator/otp,vladdu/otp,potatosalad/otp,aboroska/otp,rlipscombe/otp,RaimoNiskanen/otp,isvilen/otp,jj1bdx/otp,electricimp/otp,erlang/otp,matwey/otp,bernardd/otp,goertzenator/otp,mikpe/otp,jj1bdx/otp,dgud/otp,bjorng/otp,bsmr-erlang/otp,fenollp/otp,mikpe/otp,dgud/otp,electricimp/otp,falkevik/otp,vladdu/otp,emacsmirror/erlang,bernardd/otp,erlang/otp,bsmr-erlang/otp,RaimoNiskanen/otp,ferd/otp,vinoski/otp,falkevik/otp,lrascao/otp,dumbbell/otp,lrascao/otp,uabboli/otp,tuncer/otp,emacsmirror/erlang,lrascao/otp,RaimoNiskanen/otp,RaimoNiskanen/otp,electricimp/otp,legoscia/otp,uabboli/otp,bjorng/otp,uabboli/otp,aboroska/otp,falkevik/otp,fenollp/otp,bernardd/otp,ferd/otp,goertzenator/otp,kvakvs/otp,kvakvs/otp,legoscia/otp,dumbbell/otp,potatosalad/otp,emacsmirror/erlang,dgud/otp,dgud/otp,isvilen/otp,g-andrade/otp,fenollp/otp,RoadRunnr/otp,fenollp/otp,isvilen/otp,g-andrade/otp,lrascao/otp,electricimp/otp,bsmr-erlang/otp,legoscia/otp,lrascao/otp,vladdu/otp,electricimp/otp,rlipscombe/otp,bjorng/otp,vladdu/otp,goertzenator/otp,g-andrade/otp,tuncer/otp,potatosalad/otp,uabboli/otp,lrascao/otp,bjorng/otp,aboroska/otp,tuncer/otp,bsmr-erlang/otp,kvakvs/otp,vladdu/otp,bsmr-erlang/otp,g-andrade/otp,isvilen/otp,dumbbell/otp,uabboli/otp,tuncer/otp,jj1bdx/otp,RoadRunnr/otp,tuncer/otp,rlipscombe/otp,RoadRunnr/otp,goertzenator/otp,erlang/otp,bsmr-erlang/otp,vladdu/otp,saleyn/otp,bsmr-erlang/otp,getong/otp,tuncer/otp,potatosalad/otp,RaimoNiskanen/otp,ferd/otp,potatosalad/otp,erlang/otp,aboroska/otp,falkevik/otp,dgud/otp,falkevik/otp,getong/otp,bernardd/otp,g-andrade/otp,dgud/otp,aboroska/otp,aboroska/otp,lrascao/otp,isvilen/otp,matwey/otp,potatosalad/otp,lrascao/otp,tuncer/otp,jj1bdx/otp,cobusc/otp,mikpe/otp,electricimp/otp,saleyn/otp,matwey/otp,bernardd/otp,falkevik/otp,aboroska/otp,ferd/otp,RoadRunnr/otp,dumbbell/otp,RaimoNiskanen/otp,getong/otp,goertzenator/otp,RoadRunnr/otp,fenollp/otp,g-andrade/otp,uabboli/otp,vinoski/otp,matwey/otp,tuncer/otp,mikpe/otp,dumbbell/otp,matwey/otp,isvilen/otp,erlang/otp,ferd/otp,falkevik/otp,saleyn/otp,bjorng/otp,aboroska/otp,bsmr-erlang/otp,ferd/otp,RoadRunnr/otp,legoscia/otp,legoscia/otp,g-andrade/otp,vinoski/otp,vladdu/otp,uabboli/otp,isvilen/otp,cobusc/otp,tuncer/otp,RaimoNiskanen/otp,bjorng/otp,fenollp/otp,ferd/otp,kvakvs/otp,cobusc/otp,cobusc/otp,electricimp/otp,legoscia/otp,electricimp/otp,rlipscombe/otp,legoscia/otp,mikpe/otp,jj1bdx/otp,rlipscombe/otp,cobusc/otp,mikpe/otp,g-andrade/otp,matwey/otp,ferd/otp,mikpe/otp,RoadRunnr/otp,emacsmirror/erlang,vladdu/otp,RaimoNiskanen/otp,potatosalad/otp,dumbbell/otp,rlipscombe/otp,dgud/otp,cobusc/otp,legoscia/otp,erlang/otp,goertzenator/otp,bjorng/otp,bsmr-erlang/otp,goertzenator/otp,mikpe/otp,isvilen/otp