Provided by: erlang-manpages_20.2.2+dfsg-1ubuntu2_all bug

NAME

       gen_sctp - Functions for communicating with sockets using the SCTP
           protocol.

DESCRIPTION

       This module provides functions for communicating with sockets using the SCTP protocol. The
       implementation assumes that the OS kernel supports SCTP (RFC 2960) through the  user-level
       Sockets API Extensions.

       During development, this implementation was tested on:

         * Linux Fedora Core 5.0 (kernel 2.6.15-2054 or later is needed)

         * Solaris 10, 11

       During OTP adaptation it was tested on:

         * SUSE  Linux  Enterprise  Server  10  (x86_64)  kernel  2.6.16.27-0.6-smp, with lksctp-
           tools-1.0.6

         * Briefly on Solaris 10

         * SUSE Linux Enterprise Server 10 Service Pack  1  (x86_64)  kernel  2.6.16.54-0.2.3-smp
           with lksctp-tools-1.0.7

         * FreeBSD 8.2

       This  module was written for one-to-many style sockets (type seqpacket). With the addition
       of peeloff/2, one-to-one style sockets (type stream) were introduced.

       Record definitions for this module can be found using:

       -include_lib("kernel/include/inet_sctp.hrl").

       These  record  definitions  use  the  "new"  spelling  'adaptation',  not  the  deprecated
       'adaption', regardless of which spelling the underlying C API uses.

DATA TYPES

       assoc_id()

              An  opaque term returned in, for example, #sctp_paddr_change{}, which identifies an
              association for an SCTP socket. The term is opaque except for the special value  0,
              which has a meaning such as "the whole endpoint" or "all future associations".

       option() =
           {active, true | false | once | -32768..32767} |
           {buffer, integer() >= 0} |
           {dontroute, boolean()} |
           {high_msgq_watermark, integer() >= 1} |
           {linger, {boolean(), integer() >= 0}} |
           {low_msgq_watermark, integer() >= 1} |
           {mode, list | binary} |
           list |
           binary |
           {priority, integer() >= 0} |
           {recbuf, integer() >= 0} |
           {reuseaddr, boolean()} |
           {ipv6_v6only, boolean()} |
           {sctp_adaptation_layer, #sctp_setadaptation{}} |
           {sctp_associnfo, #sctp_assocparams{}} |
           {sctp_autoclose, integer() >= 0} |
           {sctp_default_send_param, #sctp_sndrcvinfo{}} |
           {sctp_delayed_ack_time, #sctp_assoc_value{}} |
           {sctp_disable_fragments, boolean()} |
           {sctp_events, #sctp_event_subscribe{}} |
           {sctp_get_peer_addr_info, #sctp_paddrinfo{}} |
           {sctp_i_want_mapped_v4_addr, boolean()} |
           {sctp_initmsg, #sctp_initmsg{}} |
           {sctp_maxseg, integer() >= 0} |
           {sctp_nodelay, boolean()} |
           {sctp_peer_addr_params, #sctp_paddrparams{}} |
           {sctp_primary_addr, #sctp_prim{}} |
           {sctp_rtoinfo, #sctp_rtoinfo{}} |
           {sctp_set_peer_primary_addr, #sctp_setpeerprim{}} |
           {sctp_status, #sctp_status{}} |
           {sndbuf, integer() >= 0} |
           {tos, integer() >= 0}

              One of the SCTP Socket Options.

       option_name() =
           active |
           buffer |
           dontroute |
           high_msgq_watermark |
           linger |
           low_msgq_watermark |
           mode |
           priority |
           recbuf |
           reuseaddr |
           ipv6_v6only |
           sctp_adaptation_layer |
           sctp_associnfo |
           sctp_autoclose |
           sctp_default_send_param |
           sctp_delayed_ack_time |
           sctp_disable_fragments |
           sctp_events |
           sctp_get_peer_addr_info |
           sctp_i_want_mapped_v4_addr |
           sctp_initmsg |
           sctp_maxseg |
           sctp_nodelay |
           sctp_peer_addr_params |
           sctp_primary_addr |
           sctp_rtoinfo |
           sctp_set_peer_primary_addr |
           sctp_status |
           sndbuf |
           tos

       sctp_socket()

              Socket identifier returned from open/*.

EXPORTS

       abort(Socket, Assoc) -> ok | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()
                 Assoc = #sctp_assoc_change{}

              Abnormally  terminates  the  association  specified  by  Assoc, without flushing of
              unsent data. The socket itself remains open.  Other  associations  opened  on  this
              socket are still valid, and the socket can be used in new associations.

       close(Socket) -> ok | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()

              Closes  the  socket  and  all  associations on it. The unsent data is flushed as in
              eof/2. The close/1 call is blocking or otherwise depending  of  the  value  of  the
              linger socket option. If close does not linger or linger time-out expires, the call
              returns and the data is flushed in the background.

       connect(Socket, Addr, Port, Opts) ->
                  {ok, Assoc} | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()
                 Addr = inet:ip_address() | inet:hostname()
                 Port = inet:port_number()
                 Opts = [Opt :: option()]
                 Assoc = #sctp_assoc_change{}

              Same as connect(Socket, Addr, Port, Opts, infinity).

       connect(Socket, Addr, Port, Opts, Timeout) ->
                  {ok, Assoc} | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()
                 Addr = inet:ip_address() | inet:hostname()
                 Port = inet:port_number()
                 Opts = [Opt :: option()]
                 Timeout = timeout()
                 Assoc = #sctp_assoc_change{}

              Establishes a new association for socket Socket, with the peer (SCTP server socket)
              specified  by Addr and Port. Timeout, is expressed in milliseconds. A socket can be
              associated with multiple peers.

          Warning:
              Using a value of Timeout less than the maximum time taken by the OS to establish an
              association  (around 4.5 minutes if the default values from RFC 4960 are used), can
              result in inconsistent or incorrect return values. This is especially relevant  for
              associations  sharing  the  same  Socket (that is, source address and port), as the
              controlling process blocks until  connect/*  returns.  connect_init/*  provides  an
              alternative without this limitation.

              The  result  of  connect/*  is  an  #sctp_assoc_change{}  event  that  contains, in
              particular, the new Association ID:

              #sctp_assoc_change{
                    state             = atom(),
                    error             = atom(),
                    outbound_streams  = integer(),
                    inbound_streams   = integer(),
                    assoc_id          = assoc_id()
              }

              The number of outbound and inbound streams can be set  by  giving  an  sctp_initmsg
              option to connect as in:

              connect(Socket, Ip, Port>,
                    [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
                                                 max_instreams=MaxInStreams}}])

              All  options  Opt  are set on the socket before the association is attempted. If an
              option record has undefined field values, the options record is first read from the
              socket  for those values. In effect, Opt option records only define field values to
              change before connecting.

              The returned outbound_streams and inbound_streams are the  stream  numbers  on  the
              socket.   These  can  be  different  from  the  requested  values  (OutStreams  and
              MaxInStreams, respectively) if the peer requires lower values.

              state can have the following values:

                comm_up:
                  Association is successfully established. This indicates a successful completion
                  of connect.

                cant_assoc:
                  The association cannot be established (connect/* failure).

              Other  states  do not normally occur in the output from connect/*. Rather, they can
              occur in #sctp_assoc_change{} events received instead of data in recv/* calls.  All
              of  them  indicate  losing the association because of various error conditions, and
              are listed here for the sake of completeness:

                comm_lost:

                restart:

                shutdown_comp:

              Field error can provide more detailed diagnostics.

       connect_init(Socket, Addr, Port, Opts) ->
                       ok | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()
                 Addr = inet:ip_address() | inet:hostname()
                 Port = inet:port_number()
                 Opts = [option()]

              Same as connect_init(Socket, Addr, Port, Opts, infinity).

       connect_init(Socket, Addr, Port, Opts, Timeout) ->
                       ok | {error, inet:posix()}

              Types:

                 Socket = sctp_socket()
                 Addr = inet:ip_address() | inet:hostname()
                 Port = inet:port_number()
                 Opts = [option()]
                 Timeout = timeout()

              Initiates a new association for socket Socket, with the peer (SCTP  server  socket)
              specified by Addr and Port.

              The  fundamental difference between this API and connect/* is that the return value
              is that of the underlying OS connect(2) system call. If ok is returned, the  result
              of  the  association  establishment  is  received  by  the  calling  process  as an
              #sctp_assoc_change{} event. The calling process must be prepared to  receive  this,
              or poll for it using recv/*, depending on the value of the active option.

              The parameters are as described in connect/*, except the Timeout value.

              The timer associated with Timeout only supervises IP resolution of Addr.

       controlling_process(Socket, Pid) -> ok | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Pid = pid()
                 Reason = closed | not_owner | badarg | inet:posix()

              Assigns   a   new  controlling  process  Pid  to  Socket.  Same  implementation  as
              gen_udp:controlling_process/2.

       eof(Socket, Assoc) -> ok | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Assoc = #sctp_assoc_change{}
                 Reason = term()

              Gracefully terminates the association specified by  Assoc,  with  flushing  of  all
              unsent  data.  The  socket  itself  remains open. Other associations opened on this
              socket are still valid. The socket can be used in new associations.

       error_string(ErrorNumber) -> ok | string() | unknown_error

              Types:

                 ErrorNumber = integer()

              Translates  an  SCTP  error  number  from,  for  example,  #sctp_remote_error{}  or
              #sctp_send_failed{} into an explanatory string, or one of the atoms ok for no error
              or undefined for an unrecognized error.

       listen(Socket, IsServer) -> ok | {error, Reason}

       listen(Socket, Backlog) -> ok | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Backlog = integer()
                 Reason = term()

              Sets up a socket to listen on the IP address and port number it is bound to.

              For type seqpacket, sockets (the default)  IsServer  must  be  true  or  false.  In
              contrast  to  TCP, there is no listening queue length in SCTP. If IsServer is true,
              the socket accepts new associations, that is, it becomes an SCTP server socket.

              For type stream, sockets Backlog define the backlog queue length just like in TCP.

       open() -> {ok, Socket} | {error, inet:posix()}

       open(Port) -> {ok, Socket} | {error, inet:posix()}

       open(Opts) -> {ok, Socket} | {error, inet:posix()}

       open(Port, Opts) -> {ok, Socket} | {error, inet:posix()}

              Types:

                 Opts = [Opt]
                 Opt =
                     {ip, IP} |
                     {ifaddr, IP} |
                     inet:address_family() |
                     {port, Port} |
                     {type, SockType} |
                     option()
                 IP = inet:ip_address() | any | loopback
                 Port = inet:port_number()
                 SockType = seqpacket | stream
                 Socket = sctp_socket()

              Creates an SCTP socket and binds it to the local addresses specified by all {ip,IP}
              (or  synonymously  {ifaddr,IP}) options (this feature is called SCTP multi-homing).
              The default IP and Port are any and 0, meaning bind to all local addresses  on  any
              free port.

              Other options:

                inet6:
                  Sets up the socket for IPv6.

                inet:
                  Sets up the socket for IPv4. This is the default.

              A  default  set  of  socket options is used. In particular, the socket is opened in
              binary and passive mode, with SockType seqpacket, and with reasonably large  kernel
              and driver buffers.

       peeloff(Socket, Assoc) -> {ok, NewSocket} | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Assoc = #sctp_assoc_change{} | assoc_id()
                 NewSocket = sctp_socket()
                 Reason = term()

              Branches  off  an  existing  association Assoc in a socket Socket of type seqpacket
              (one-to-many style) into a new socket NewSocket of type stream (one-to-one style).

              The existing association argument Assoc can be either a #sctp_assoc_change{} record
              as  returned  from,  for  example, recv/*, connect/*, or from a listening socket in
              active mode. It can also be just the field assoc_id integer from such a record.

       recv(Socket) ->
               {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}

       recv(Socket, Timeout) ->
               {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Timeout = timeout()
                 FromIP = inet:ip_address()
                 FromPort = inet:port_number()
                 AncData = [#sctp_sndrcvinfo{}]
                 Data =
                     binary() |
                     string() |
                     #sctp_sndrcvinfo{} |
                     #sctp_assoc_change{} |
                     #sctp_paddr_change{} |
                     #sctp_adaptation_event{}
                 Reason =
                     inet:posix() |
                     #sctp_send_failed{} |
                     #sctp_paddr_change{} |
                     #sctp_pdapi_event{} |
                     #sctp_remote_error{} |
                     #sctp_shutdown_event{}

              Receives the Data message from any association of the socket. If the receive  times
              out,  {error,timeout}  is  returned.  The  default time-out is infinity. FromIP and
              FromPort indicate the address of the sender.

              AncData is a list of ancillary data items that can be received along with the  main
              Data.  This  list  can  be  empty, or contain a single #sctp_sndrcvinfo{} record if
              receiving of such ancillary data is enabled (see option sctp_events). It is enabled
              by  default,  as  such  ancillary  data  provides  an  easy  way of determining the
              association and stream over which the message is received. (An alternative  way  is
              to   get   the  association  ID  from  FromIP  and  FromPort  using  socket  option
              sctp_get_peer_addr_info, but this does still not produce the stream number).

              The Data received can be a binary() or a list() of bytes (integers in the  range  0
              through 255) depending on the socket mode, or an SCTP event.

              Possible SCTP events:

                * #sctp_sndrcvinfo{}

                * #sctp_assoc_change{}

                *

                #sctp_paddr_change{
                      addr      = {ip_address(),port()},
                      state     = atom(),
                      error     = integer(),
                      assoc_id  = assoc_id()
                }

                  Indicates  change of the status of the IP address of the peer specified by addr
                  within association assoc_id. Possible values of state (mostly self-explanatory)
                  include:

                  addr_unreachable:

                  addr_available:

                  addr_removed:

                  addr_added:

                  addr_made_prim:

                  addr_confirmed:

                  In  case of an error (for example, addr_unreachable), field error provides more
                  diagnostics.  In  such  cases,  event  #sctp_paddr_change{}  is   automatically
                  converted  into  an  error  term returned by recv. The error field value can be
                  converted into a string using error_string/1.

                *

                #sctp_send_failed{
                      flags     = true | false,
                      error     = integer(),
                      info      = #sctp_sndrcvinfo{},
                      assoc_id  = assoc_id()
                      data      = binary()
                }

                  The sender can receive this event if a send operation fails.

                  flags:
                    A Boolean specifying if the data has been transmitted over the wire.

                  error:
                    Provides extended diagnostics, use error_string/1.

                  info:
                    The original #sctp_sndrcvinfo{} record used in the failed send/*.

                  data:
                    The whole original data chunk attempted to be sent.

                  In the current  implementation  of  the  Erlang/SCTP  binding,  this  event  is
                  internally converted into an error term returned by recv/*.

                *

                #sctp_adaptation_event{
                      adaptation_ind = integer(),
                      assoc_id       = assoc_id()
                }

                  Delivered   when   a  peer  sends  an  adaptation  layer  indication  parameter
                  (configured through option sctp_adaptation_layer). Notice that with the current
                  implementation of the Erlang/SCTP binding, this event is disabled by default.

                *

                #sctp_pdapi_event{
                      indication = sctp_partial_delivery_aborted,
                      assoc_id   = assoc_id()
                }

                  A  partial  delivery  failure. In the current implementation of the Erlang/SCTP
                  binding, this event is internally converted into  an  error  term  returned  by
                  recv/*.

       send(Socket, SndRcvInfo, Data) -> ok | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 SndRcvInfo = #sctp_sndrcvinfo{}
                 Data = binary() | iolist()
                 Reason = term()

              Sends  the  Data  message  with  all  sending  parameters from a #sctp_sndrcvinfo{}
              record. This way, the user can specify the PPID (passed  to  the  remote  end)  and
              context (passed to the local SCTP layer), which can be used, for example, for error
              identification. However, such a fine level of user control is rarely required.  The
              function send/4 is sufficient for most applications.

       send(Socket, Assoc, Stream, Data) -> ok | {error, Reason}

              Types:

                 Socket = sctp_socket()
                 Assoc = #sctp_assoc_change{} | assoc_id()
                 Stream = integer()
                 Data = binary() | iolist()
                 Reason = term()

              Sends a Data message over an existing association and specified stream.

SCTP SOCKET OPTIONS

       The  set  of  admissible  SCTP socket options is by construction orthogonal to the sets of
       TCP, UDP, and generic inet options. Only options listed here are allowed for SCTP sockets.
       Options  can  be  set  on  the  socket  using  open/1,2 or inet:setopts/2, retrieved using
       inet:getopts/2. Options can be changed when calling connect/4,5.

         {mode, list|binary} or just list or binary:
           Determines the type of data returned from recv/1,2.

         {active, true|false|once|N}:

           * If false (passive mode, the default), the caller must do an explicit  recv  call  to
             retrieve the available data from the socket.

           * If  true  (full  active  mode),  the  pending  data or events are sent to the owning
             process.

             Notice that this can cause the message queue to overflow, as  there  is  no  way  to
             throttle the sender in this case (no flow control).

           * If  once,  only  one message is automatically placed in the message queue, and after
             that the mode is automatically reset to passive. This provides flow control and  the
             possibility  for  the receiver to listen for its incoming SCTP data interleaved with
             other inter-process messages.

           * If active is specified as an integer N in the range  -32768  to  32767  (inclusive),
             that  number  is  added to the socket's counting of data messages to be delivered to
             the controlling process. If the result of the addition is negative, the count is set
             to  0. Once the count reaches 0, either through the delivery of messages or by being
             explicitly set with inet:setopts/2,  the  socket  mode  is  automatically  reset  to
             passive  ({active, false}). When a socket in this active mode transitions to passive
             mode, the message {sctp_passive, Socket} is  sent  to  the  controlling  process  to
             notify  it  that  if it wants to receive more data messages from the socket, it must
             call inet:setopts/2 to set the socket back into an active mode.

         {tos, integer()}:
           Sets the Type-Of-Service field on the IP datagrams that are  sent,  to  the  specified
           value.  This  effectively determines a prioritization policy for the outbound packets.
           The acceptable values are system-dependent.

         {priority, integer()}:
           A protocol-independent equivalent of tos above. Setting priority implies  setting  tos
           as well.

         {dontroute, true|false}:
           Defaults to false. If true, the kernel does not send packets through any gateway, only
           sends them to directly connected hosts.

         {reuseaddr, true|false}:
           Defaults to false. If true, the local binding address {IP,Port} of the socket  can  be
           reused  immediately.  No waiting in state CLOSE_WAIT is performed (can be required for
           high-throughput servers).

         {sndbuf, integer()}:
           The size, in bytes, of the OS kernel send buffer for this socket. Sending errors would
           occur for datagrams larger than val(sndbuf). Setting this option also adjusts the size
           of the driver buffer (see buffer above).

         {recbuf, integer()}:
           The size, in bytes, of the OS kernel receive buffer for this  socket.  Sending  errors
           would  occur  for  datagrams larger than val(recbuf). Setting this option also adjusts
           the size of the driver buffer (see buffer above).

         {sctp_module, module()}:
           Overrides which callback module is used. Defaults to inet_sctp for IPv4 and inet6_sctp
           for IPv6.

         {sctp_rtoinfo, #sctp_rtoinfo{}}:

         #sctp_rtoinfo{
               assoc_id = assoc_id(),
               initial  = integer(),
               max      = integer(),
               min      = integer()
         }

           Determines retransmission time-out parameters, in milliseconds, for the association(s)
           specified by assoc_id.

           assoc_id = 0 (default) indicates the whole endpoint. See  RFC  2960  and  Sockets  API
           Extensions for SCTP for the exact semantics of the field values.

         {sctp_associnfo, #sctp_assocparams{}}:

         #sctp_assocparams{
               assoc_id                 = assoc_id(),
               asocmaxrxt               = integer(),
               number_peer_destinations = integer(),
               peer_rwnd                = integer(),
               local_rwnd               = integer(),
               cookie_life              = integer()
         }

           Determines association parameters for the association(s) specified by assoc_id.

           assoc_id  =  0  (default) indicates the whole endpoint. See Sockets API Extensions for
           SCTP for the discussion of their semantics. Rarely used.

         {sctp_initmsg, #sctp_initmsg{}}:

         #sctp_initmsg{
              num_ostreams   = integer(),
              max_instreams  = integer(),
              max_attempts   = integer(),
              max_init_timeo = integer()
         }

           Determines the default parameters that this socket tries to negotiate  with  its  peer
           while  establishing  an  association with it. Is to be set after open/* but before the
           first connect/*. #sctp_initmsg{} can also be used as ancillary  data  with  the  first
           call of send/* to a new peer (when a new association is created).

           num_ostreams:
             Number of outbound streams

           max_instreams:
             Maximum number of inbound streams

           max_attempts:
             Maximum retransmissions while establishing an association

           max_init_timeo:
             Time-out, in milliseconds, for establishing an association

         {sctp_autoclose, integer() >= 0}:
           Determines  the  time,  in  seconds,  after which an idle association is automatically
           closed. 0 means that the association is never automatically closed.

         {sctp_nodelay, true|false}:
           Turns on|off the Nagle algorithm for merging small  packets  into  larger  ones.  This
           improves throughput at the expense of latency.

         {sctp_disable_fragments, true|false}:
           If true, induces an error on an attempt to send a message larger than the current PMTU
           size  (which  would   require   fragmentation/reassembling).   Notice   that   message
           fragmentation  does  not  affect the logical atomicity of its delivery; this option is
           provided for performance reasons only.

         {sctp_i_want_mapped_v4_addr, true|false}:
           Turns on|off automatic mapping of IPv4 addresses into IPv6 ones (if the socket address
           family is AF_INET6).

         {sctp_maxseg, integer()}:
           Determines  the  maximum  chunk size if message fragmentation is used. If 0, the chunk
           size is limited by the Path MTU only.

         {sctp_primary_addr, #sctp_prim{}}:

         #sctp_prim{
               assoc_id = assoc_id(),
               addr     = {IP, Port}
         }
          IP = ip_address()
          Port = port_number()

           For the association  specified  by  assoc_id,  {IP,Port}  must  be  one  of  the  peer
           addresses.  This  option determines that the specified address is treated by the local
           SCTP stack as the primary address of the peer.

         {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}:

         #sctp_setpeerprim{
               assoc_id = assoc_id(),
               addr     = {IP, Port}
         }
          IP = ip_address()
          Port = port_number()

           When set, informs the peer to use {IP, Port} as  the  primary  address  of  the  local
           endpoint for the association specified by assoc_id.

         {sctp_adaptation_layer, #sctp_setadaptation{}}:

         #sctp_setadaptation{
               adaptation_ind = integer()
         }

           When  set, requests that the local endpoint uses the value specified by adaptation_ind
           as the Adaptation Indication parameter for establishing new associations. For details,
           see RFC 2960 and Sockets API Extenstions for SCTP.

         {sctp_peer_addr_params, #sctp_paddrparams{}}:

         #sctp_paddrparams{
               assoc_id   = assoc_id(),
               address    = {IP, Port},
               hbinterval = integer(),
               pathmaxrxt = integer(),
               pathmtu    = integer(),
               sackdelay  = integer(),
               flags      = list()
         }
         IP = ip_address()
         Port = port_number()

           Determines  various  per-address  parameters for the association specified by assoc_id
           and the peer address address (the SCTP protocol supports multi-homing,  so  more  than
           one address can correspond to a specified association).

           hbinterval:
             Heartbeat interval, in milliseconds

           pathmaxrxt:
             Maximum number of retransmissions before this address is considered unreachable (and
             an alternative address is selected)

           pathmtu:
             Fixed Path MTU, if automatic discovery is disabled (see flags below)

           sackdelay:
             Delay, in milliseconds, for SAC messages (if the delay is enabled, see flags below)

           flags:
             The following flags are available:

             hb_enable:
               Enables heartbeat

             hb_disable:
               Disables heartbeat

             hb_demand:
               Initiates heartbeat immediately

             pmtud_enable:
               Enables automatic Path MTU discovery

             pmtud_disable:
               Disables automatic Path MTU discovery

             sackdelay_enable:
               Enables SAC delay

             sackdelay_disable:
               Disables SAC delay

         {sctp_default_send_param, #sctp_sndrcvinfo{}}:

         #sctp_sndrcvinfo{
               stream     = integer(),
               ssn        = integer(),
               flags      = list(),
               ppid       = integer(),
               context    = integer(),
               timetolive = integer(),
               tsn        = integer(),
               cumtsn     = integer(),
               assoc_id   = assoc_id()
         }

           #sctp_sndrcvinfo{} is used both in this socket option, and  as  ancillary  data  while
           sending  or receiving SCTP messages. When set as an option, it provides default values
           for subsequent send calls on the association specified by assoc_id.

           assoc_id = 0 (default) indicates the whole endpoint.

           The following fields typically must be specified by the sender:

           sinfo_stream:
             Stream number (0-base) within the association to send the messages through;

           sinfo_flags:
             The following flags are recognised:

             unordered:
               The message is to be sent unordered

             addr_over:
               The address specified in send overwrites the primary peer address

             abort:
               Aborts the current association without flushing any unsent data

             eof:
               Gracefully shuts down the current association, with flushing of unsent data

             Other fields are rarely used. For complete information, see RFC 2960 and Sockets API
             Extensions for SCTP.

         {sctp_events, #sctp_event_subscribe{}}:

         #sctp_event_subscribe{
                 data_io_event          = true | false,
                 association_event      = true | false,
                 address_event          = true | false,
                 send_failure_event     = true | false,
                 peer_error_event       = true | false,
                 shutdown_event         = true | false,
                 partial_delivery_event = true | false,
                 adaptation_layer_event = true | false
         }

           This  option  determines  which  SCTP Events are to be received (through recv/*) along
           with the data.  The  only  exception  is  data_io_event,  which  enables  or  disables
           receiving  of  #sctp_sndrcvinfo{}  ancillary  data,  not events. By default, all flags
           except   adaptation_layer_event   are   enabled,   although   sctp_data_io_event   and
           association_event are used by the driver itself and not exported to the user level.

         {sctp_delayed_ack_time, #sctp_assoc_value{}}:

         #sctp_assoc_value{
               assoc_id    = assoc_id(),
               assoc_value = integer()
         }

           Rarely  used.  Determines the ACK time (specified by assoc_value, in milliseconds) for
           the specified association or the whole endpoint if assoc_value = 0 (default).

         {sctp_status, #sctp_status{}}:

         #sctp_status{
               assoc_id            = assoc_id(),
               state               = atom(),
               rwnd                = integer(),
               unackdata           = integer(),
               penddata            = integer(),
               instrms             = integer(),
               outstrms            = integer(),
               fragmentation_point = integer(),
               primary             = #sctp_paddrinfo{}
         }

           This option is read-only. It determines the status of the SCTP  association  specified
           by  assoc_id.  The  following are the possible values of state (the state designations
           are mostly self-explanatory):

           sctp_state_empty:
             Default. Means that no other state is active.

           sctp_state_closed:

           sctp_state_cookie_wait:

           sctp_state_cookie_echoed:

           sctp_state_established:

           sctp_state_shutdown_pending:

           sctp_state_shutdown_sent:

           sctp_state_shutdown_received:

           sctp_state_shutdown_ack_sent:

           Semantics of the other fields:

           sstat_rwnd:
             Current receiver window size of the association

           sstat_unackdata:
             Number of unacked data chunks

           sstat_penddata:
             Number of data chunks pending receipt

           sstat_instrms:
             Number of inbound streams

           sstat_outstrms:
             Number of outbound streams

           sstat_fragmentation_point:
             Message size at which SCTP fragmentation occurs

           sstat_primary:
             Information on the current primary  peer  address  (see  below  for  the  format  of
             #sctp_paddrinfo{})

         {sctp_get_peer_addr_info, #sctp_paddrinfo{}}:

         #sctp_paddrinfo{
               assoc_id  = assoc_id(),
               address   = {IP, Port},
               state     = inactive | active | unconfirmed,
               cwnd      = integer(),
               srtt      = integer(),
               rto       = integer(),
               mtu       = integer()
         }
         IP = ip_address()
         Port = port_number()

           This  option  is  read-only. It determines the parameters specific to the peer address
           specified by address within the association specified by assoc_id. Field address fmust
           be  set  by  the  caller;  all  other  fields are filled in on return. If assoc_id = 0
           (default), the address is automatically translated into the corresponding  association
           ID.  This  option  is  rarely  used. For the semantics of all fields, see RFC 2960 and
           Sockets API Extensions for SCTP.

SCTP EXAMPLES

       Example of an Erlang SCTP server that receives  SCTP  messages  and  prints  them  on  the
       standard output:

       -module(sctp_server).

       -export([server/0,server/1,server/2]).
       -include_lib("kernel/include/inet.hrl").
       -include_lib("kernel/include/inet_sctp.hrl").

       server() ->
           server(any, 2006).

       server([Host,Port]) when is_list(Host), is_list(Port) ->
           {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
           io:format("~w -> ~w~n", [Host, IP]),
           server([IP, list_to_integer(Port)]).

       server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
                             is_integer(Port) ->
           {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
           io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
           ok     = gen_sctp:listen(S, true),
           server_loop(S).

       server_loop(S) ->
           case gen_sctp:recv(S) of
           {error, Error} ->
               io:format("SCTP RECV ERROR: ~p~n", [Error]);
           Data ->
               io:format("Received: ~p~n", [Data])
           end,
           server_loop(S).

       Example  of  an  Erlang SCTP client interacting with the above server. Notice that in this
       example the client creates an  association  with  the  server  with  5  outbound  streams.
       Therefore, sending of "Test 0" over stream 0 succeeds, but sending of "Test 5" over stream
       5 fails. The client then aborts the association, which results in that  the  corresponding
       event is received on the server side.

       -module(sctp_client).

       -export([client/0, client/1, client/2]).
       -include_lib("kernel/include/inet.hrl").
       -include_lib("kernel/include/inet_sctp.hrl").

       client() ->
           client([localhost]).

       client([Host]) ->
           client(Host, 2006);

       client([Host, Port]) when is_list(Host), is_list(Port) ->
           client(Host,list_to_integer(Port)),
           init:stop().

       client(Host, Port) when is_integer(Port) ->
           {ok,S}     = gen_sctp:open(),
           {ok,Assoc} = gen_sctp:connect
               (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
           io:format("Connection Successful, Assoc=~p~n", [Assoc]),

           io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
           io:nl(),
           timer:sleep(10000),
           io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
           io:nl(),
           timer:sleep(10000),
           io:write(gen_sctp:abort(S, Assoc)),
           io:nl(),

           timer:sleep(1000),
           gen_sctp:close(S).

       A simple Erlang SCTP client that uses the connect_init API:

       -module(ex3).

       -export([client/4]).
       -include_lib("kernel/include/inet.hrl").
       -include_lib("kernel/include/inet_sctp.hrl").

       client(Peer1, Port1, Peer2, Port2)
         when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
           {ok,S}     = gen_sctp:open(),
           SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
           ActiveOpt = {active, true},
           Opts = [SctpInitMsgOpt, ActiveOpt],
           ok = gen_sctp:connect(S, Peer1, Port1, Opts),
           ok = gen_sctp:connect(S, Peer2, Port2, Opts),
           io:format("Connections initiated~n", []),
           client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).

       client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
           receive
               {sctp, S, Peer1, Port1, {_Anc, SAC}}
                 when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
                   io:format("Association 1 connect result: ~p. AssocId: ~p~n",
                             [SAC#sctp_assoc_change.state,
                              SAC#sctp_assoc_change.assoc_id]),
                   client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
                               Peer2, Port2, AssocId2);

               {sctp, S, Peer2, Port2, {_Anc, SAC}}
                 when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
                   io:format("Association 2 connect result: ~p. AssocId: ~p~n",
                             [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
                   client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
                              SAC#sctp_assoc_change.assoc_id);

               {sctp, S, Peer1, Port1, Data} ->
                   io:format("Association 1: received ~p~n", [Data]),
                   client_loop(S, Peer1, Port1, AssocId1,
                               Peer2, Port2, AssocId2);

               {sctp, S, Peer2, Port2, Data} ->
                   io:format("Association 2: received ~p~n", [Data]),
                   client_loop(S, Peer1, Port1, AssocId1,
                               Peer2, Port2, AssocId2);

               Other ->
                   io:format("Other ~p~n", [Other]),
                   client_loop(S, Peer1, Port1, AssocId1,
                               Peer2, Port2, AssocId2)

           after 5000 ->
                   ok
           end.

SEE ALSO

       gen_tcp(3erl), gen_udp(3erl), inet(3erl), RFC 2960 (Stream Control Transmission Protocol),
       Sockets API Extensions for SCTP