gen_sctp(3)



gen_sctp(3erl)             Erlang Module Definition             gen_sctp(3erl)

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} |
           {tclass, integer() >= 0} |
           {ttl, integer() >= 0} |
           {recvtos, boolean()} |
           {recvtclass, boolean()} |
           {recvttl, boolean()}

              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 |
           tclass | ttl | recvtos | recvtclass | recvttl

       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,  with-
              out  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, #sctp_assoc_change{state = comm_up}} |
                  {error, #sctp_assoc_change{state = cant_assoc}} |
                  {error, inet:posix()}

              Types:

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

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

       connect(Socket, Addr, Port, Opts, Timeout) ->
                  {ok, #sctp_assoc_change{state = comm_up}} |
                  {error, #sctp_assoc_change{state = cant_assoc}} |
                  {error, inet:posix()}

              Types:

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

              Establishes  a  new association for socket Socket, with the peer
              (SCTP server socket) specified by Addr and Port. Timeout, is ex-
              pressed  in milliseconds. A socket can be associated with multi-
              ple 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 de-
              fault values from RFC 4960 are used), can result in inconsistent
              or  incorrect return values. This is especially relevant for as-
              sociations sharing the same Socket (that is, source address  and
              port),  as  the  controlling  process blocks until connect/* re-
              turns. connect_init/* provides an alternative without this limi-
              tation.

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

              #sctp_assoc_change{
                    state             = atom(),
                    error             = integer(),
                    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. The error
              field value can be converted into a string using error_string/1.

       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_as-
              soc_change{}  event. The calling process must be prepared to re-
              ceive 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 implemen-
              tation 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_re-
              mote_error{} or #sctp_send_failed{} into an explanatory  string,
              or one of the atoms ok for no error or undefined for an unrecog-
              nized 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 associa-
              tions, 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 spec-
              ified 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  seq-
              packet, and with reasonably large kernel and driver buffers.

              If  the  socket  is in passive mode data can be received through
              the recv/1,2 calls.

              If the socket is in active mode data received data is  delivered
              to the controlling process as messages:

              {sctp, Socket, FromIP, FromPort, {AncData, Data}}

              See recv/1,2 for a description of the message fields.

          Note:
              This  message  format  unfortunately  differs  slightly from the
              gen_udp  message  format  with  ancillary  data,  and  from  the
              recv/1,2 return tuple format.

       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{} | inet:ancillary_data()]
                 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  de-
              fault,  as such ancillary data provides an easy way of determin-
              ing the association and stream over which  the  message  is  re-
              ceived.  (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).

              AncData  may  also  contain  ancillary data  from the socket op-
              tions recvtos, recvtclass or recvttl, if that  is  supported  by
              the platform for the socket.

              The  Data received can be a binary() or a list() of bytes (inte-
              gers 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 val-
                  ues 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 er-
                  ror term returned by recv. The error field value can be con-
                  verted 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  re-
                  turned 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 Er-
                  lang/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 identifi-
              cation. However, such a fine level of user control is rarely re-
              quired. 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 us-
       ing 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  ex-
             plicit recv call to retrieve the available data from the socket.

           * If true|once|N (active modes) received data or events are sent to
             the owning process. See open/0..2 for the message format.

           * If true (full active mode) there is no flow control.

       Note:
           Note that this can cause the message queue to overflow causing  for
           example the virtual machine to run out of memory and crash.

           * 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  in-
             ter-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  mes-
             sage {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 prioritiza-
           tion 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 negoti-
           ate 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  auto-
           matically 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/re-
           assembling). Notice that message fragmentation does not affect  the
           logical atomicity of its delivery; this option is provided for per-
           formance 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 ad-
           dress 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 estab-
           lishing 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 spec-
           ified 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  consid-
             ered unreachable (and an alternative address is selected)

           pathmtu:
             Fixed Path MTU, if automatic discovery is disabled (see flags be-
             low)

           sackdelay:
             Delay, in milliseconds, for SAC messages (if  the  delay  is  en-
             abled, 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 an-
           cillary 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  mes-
             sages 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 ad-
               dress

             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_sndrcv-
           info{}  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  as-
           sociation  specified  by  assoc_id.  The following are the possible
           values of state (the state designations  are  mostly  self-explana-
           tory):

           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 speci-
           fied 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  as-
           sociation  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. No-
       tice 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 corre-
       sponding 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

Ericsson AB                       kernel 7.0                    gen_sctp(3erl)

Man(1) output converted with man2html
list of all man pages