Erlang diameter / diameter_sctp transport; send() on SCTP socket gets EAGAIN/EWOULDBLOCK


As far as I have seen on a running system and as far I understand from here:
sockets are non-blocking when created in Erlang. I assume this applies to gen_sctp sockets too. Pls. correct me if I am wrong.


  1. based on some traces captured on a Linux system on which an Erlang diameter application is running (both strace and pcaps)
  2. looking at the code in:


send(Sock, AssocId, StreamId, Bin) ->
    case gen_sctp:send(Sock, AssocId, StreamId, Bin) of
        ok ->
        {error, Reason} ->
            x({send, Reason})

%% x/1

x(Reason) ->
    exit({shutdown, Reason}).

to me it looks like:

  1. Regardless of the error in case of a send() system call which uses the socket the socket will be closed (gracefully)
  2. Since the socket is asynch., everytime the peer will slow down due to some kind of app congestion, the local kernel socket send buffer will become full (normal SCTP behaviour in this case) and the send() will get an EAGAIN/EWOULDBLOCK. For most of the telco diameter applications I worked with (be it Diameter Routers, HSS, IMS SIP Proxies aso) closing the persistent SCTP association in such a case is not always the optimal solution. An option is to stop sending data from the app on that socket and monitor it for “write ready” events.
    I see that the generic “socket” has a mechanism for this kind of monitoring:
    Erlang -- socket
    Is this usable with gen_sctp:send() as well?
    Or should one use the SCTP_SENDER_DRY_EVENT (is it implemented in Erlang)?
    See here:
    RFC 6458 - Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)

Thank you