SCTP Programming Guide
SCTP Programming Guide
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
Version History
TypeUnitOrDepartmentHere
TypeYourNameHere                                                              TypeDateHere
Table of Contents
1.  INTRODUCTION........................................................................................................................... 4
  1.1   Purpose.................................................................................................................................. 4
  1.2   Scope..................................................................................................................................... 4
  1.3   Glossary................................................................................................................................. 4
    1.3.1     Abbreviations................................................................................................................... 4
2. Socket API.................................................................................................................................... 4
  2.1   Objectives............................................................................................................................... 4
    2.1.1     Maintain consistency with existing sockets APIs:.............................................................4
    2.1.2     Support a one to many style interface.............................................................................4
    2.1.3     Support a one to one style interface................................................................................4
  2.2   Data Types............................................................................................................................. 5
  2.3   How to program...................................................................................................................... 5
  2.4   Basic socket functions............................................................................................................ 6
    2.4.1     introduction...................................................................................................................... 6
    2.4.2     socket address................................................................................................................ 6
    2.4.3     byte-order........................................................................................................................ 6
    2.4.4     socket operations............................................................................................................ 7
    2.4.5     Non-blocking mode........................................................................................................10
  2.5   Header data structures and event data structures................................................................10
    2.5.1     The msghdr and cmsghdr Structures.............................................................................10
    2.5.2     SCTP msg_control Structures.......................................................................................11
    2.5.3     SCTP Events and Notifications in /include/net/sctp/sctp_user.h....................................12
  2.6   Super socket operations for Both Styles...............................................................................14
    2.6.1     send(), recv(), sendto(), recvfrom()................................................................................14
    2.6.2     sendmsg() and recvmsg()..............................................................................................15
    2.6.3     read() and wirte()........................................................................................................... 16
    2.6.4     getsockname()...............................................................................................................16
    2.6.5     setsockopt(), getsockopt().............................................................................................17
  2.7   The function of event and how to use...................................................................................17
  2.8   Ancillary Data Considerations and Semantics......................................................................19
    2.8.1     Multiple Items and Ordering...........................................................................................19
    2.8.2     Accessing and Manipulating Ancillary Data...................................................................19
    2.8.3     Control Message Buffer Sizing......................................................................................20
    2.8.4     How to use data structures when programming.............................................................20
  2.9   Socket Options..................................................................................................................... 20
    2.9.1     table of socket options’ functions...................................................................................21
  2.10     New Interfaces..................................................................................................................22
    2.10.1       sctp_bindx()............................................................................................................... 22
    2.10.2       sctp_peeloff().............................................................................................................23
    2.10.3       sctp_getpaddrs()........................................................................................................23
    2.10.4       sctp_freepaddrs().......................................................................................................24
    2.10.5       sctp_getladdrs()......................................................................................................... 24
    2.10.6       sctp_freeladdrs()........................................................................................................25
    2.10.7       sctp_sendmsg().........................................................................................................25
    2.10.8       sctp_recvmsg().......................................................................................................... 25
3. Installation Guide........................................................................................................................ 26
  3.1   account in isource.nokia.com................................................................................................26
  3.2   Create the source tree (based on Linux Kernel 2.4.18).........................................................26
  3.3   File list.................................................................................................................................. 27
  3.4   Compile................................................................................................................................ 27
    3.4.1     Compile lksctp in kernel.................................................................................................27
                                                                              DOCUMENTTYPE                                              3 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                                              TypeDateHere
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
1. INTRODUCTION
1.1 Purpose
           This document is the application guide for Nokia Linux kernel SCTP implementation. The
           instructions herein are meant for the developers of SCTP user applications in. This
           document was originally written by members of the noklksctp team at NRC Beijing.
1.2 Scope
           This document has 3 parts: including SCTP socket API description and LKSCTP
           installation and configuration guide. The third part is Chapter 6 SCTP in FlexiServer, which
           contains FlexiServer-specific SCTP information.
1.3 Glossary
1.3.1 Abbreviations
2. SOCKET API
2.1 Objectives
           Defines a method to map the existing sockets API for use with SCTP, providing both a
           base for access to new features and compatibility so that most existing TCP applications
           can be migrated to SCTP with few (if any) changes.
           We define a sockets mapping for SCTP that is consistent with other sockets API protocol
           mappings (for instance, UDP, TCP, IPv4, and IPv6).
           This set of semantics is similar to that defined for connectionless protocols, such as UDP.
           It is more efficient than a TCP-like connection-oriented interface in terms of exploring the
           new features of SCTP.
           Note that SCTP is connection-oriented in nature, and it does not support broadcast or
           multicast communications, as UDP does.
           This interface supports the same basic semantics as sockets for connection-oriented
           protocols, such as TCP.
                                                     DOCUMENTTYPE                              5 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
           The purpose of defining this interface is to allow existing applications built on connection-
           oriented protocols be ported to use SCTP with very little effort, and developers familiar with
           those semantics can easily adapt to SCTP.
           Extensions will be added to this mapping to provide mechanisms to exploit new features of
           SCTP.
           Goals 2 and 3 are not compatible, so in this document we define two modes of mapping,
           namely the one to many style(UDP style) mapping and the one to one style(TCP-style)
           mapping. These two modes share some common data structures and operations, but will
           require the use of two different application programming models.
           Some of the SCTP mechanisms cannot be adequately mapped to existing socket interface.
           In some cases, it is more desirable to have new interface instead of using existing socket
           calls. This document also describes those new interface.
           Whenever possible, data types from Draft 6.6 (March 1997) of POSIX 1003.1g are used:
           uintN_t means an unsigned integer of exactly N bits (e.g., uint16_t). We also assume the
           argument data types from 1003.1g when possible (e.g., the final argument to setsockopt()
           is a size_t value). Whenever buffer sizes are specified, the POSIX 1003.1 size_t data type
           is used.
           When a programmer begins his/her programming, he/she has one step which must be
           done before programming. That is he/she should copy some files provided by us to his/her
           own directory or to the place according to necessary. Now, we put those files in
           noklksctp/test/libc/include/netinet/. E.g., we put data structures and event structures in
           sctp.h. Users clould named his/her directory if only the directory include these files.
           The data structures of events and socket options which are already included in linux kernel.
           While linux operating system will only auto read files in <sys/>, therefore, for the users’
           program, it could not find those SCTP data structures although they are already belong to
           linux kernel.
Library functions:
           Nokia linux kernel support some lirary functions according to draft api, such as
           sctp_bindx(); sctp_sendmsg(); sctp_recvmsg() and so on. Their aim is to provide
           convenience to the user. Each function is elaborately described in section 2.10. Now, all
           these library fuctions are included in /noklksctp/test/sctp_lib.c. Since our c program are all
           in the same directory, it is no use to point at the directrory in makefile. However, if users
           want to put sctp_lib.c in his/her directory, he/her must point at the directory.
           User could use makefile to include the directory which include those files.
                                                      DOCUMENTTYPE                             6 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
2.4.1 introduction
            Linux provide socket mechanism to access network protocol of lower layer. The following
           firstly introduce address format and byte-orders which are used by socket functions. Then
           discuss basic socket functions. More elaborately functions will be described in attachment.
           struct sockaddr
           {
                        unsigned short sa_family;          /* type of address, AF_**** */
                        char           sa_data[14];        /*address */
           };
           struct sockaddr_in {
                        short int                     sin_family;    /* type of address. */
                        unsigned shot int             sin_port;      /* port */
                        struct in_addr;               sin_addr;     /* internet address */
                        unsigned char                 pad;          /* pad, in order to compatible with
BSD. */
           }
note:
           (1) <linux/socket.h> and <linux/in.h> is head files which specially owned by linux. In order
               to keep code could be transplanted, we should not include these two files, while should
               include <sys/socket.h> and <netinet/in.h> which have no relationship with platform.
           (2) port and address in struct sockaddr_in are all stored in host byte-order. They should be
               converted to network byte-order when programming.
2.4.3 byte-order
TypeUnitOrDepartmentHere
TypeYourNameHere                                         TypeDateHere
                     (2) when programming, it had better use these functions while not depending on
               special machines.
The following table compares the socket operations of UDP style and TCP style.
Under the table, we state the functions and difference of UDP and TCP styles simply.
               Elaberation of the fuction and parameters list in the appendix, whose index number is
               written down in the table.
We alse have some examples in the attachment for each socket operation.
socket()
UDP socket(PF_INET,SEQ_PACKET,IPPROTO_SCTP)
TCP socket(PF_INET,STREAM,IPPROTO_SCTP)
               Function: creating a socket descriptor, that is to say, to create a data struct of sock, which
               use to communicate with peer.
               Difference: only the second parameter in the bracket has difference. That parameter is
               used to mark the style of the socket.
bind()
               Function: binding a socket descriptor with a port. I.e., if a socket descriptor is a telephone,
               then a socket descriptor with port is a telephone with line.
               Note:
               Use wild-card is need to use parameters INADDR_ANY. It has some difference with TCP
               protocol. In SCTP, using this parameter means that host will choose multiple address for
               communication, whereas in TCP protocol, this parameter has two meanings. In TCP
               protocol, when a server use INADDR_ANY for binding address, it means the server will
               accept any connection whatever the clients’ address are. When a client use this address, it
               means local host.
                                                      DOCUMENTTYPE                              8 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
             Difference: although they seems same in style, while UDP can build association without call
             bind(). It means that UDP socket support auto bind whereas TCP can’t.
listen()
             Function: the operation is only used in server. Firstly, to create a corresponding socket to
             the client to prepare communicate. Secondly, it will monitor whether it could accept an
             other client’s connection.
             Difference: although they seems same in style, while the parameter----backlog is not
             supported by UDP. It means the second parameter in listen() is “false”.
connect()
UDP connect(int sd, const struct sockaddr *nam, socklen_t len) 2.4.1.6
TCP connect(int sd, const struct sockaddr *nam, socklen_t len) 2.5.1.5
             Difference: although there is no defference in form for the two style, while in practice UDP
             style seldom use connect(). UDP socket always use sendmsg() or sendto() to establish
             association.
accept()
TCP accept(int sd, const struct sockaddr *addr, socklen_t addrlen) 2.5.1.4
             Function: it is to move the socket from the listen socket so as to build one-to-one style
             communication mechanism.
                                                      DOCUMENTTYPE                              9 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
              Difference: It is clear that UDP do not support accept(), while it has similar operation which
             is named peel off().
close()
             Function: close() will decrease the counter of socket descriptor. If it is decresed to zero,
             descriptor will be free, otherwise it means there is some other course using the descriptor,
             then close() will return normally. Until there is no any course using the descriptor, the
             descriptor will be freed.
shutdown()
             Fuction: gracefully shutdown when necessary. It could be called whenever the program
             want. While close() always be called after finishing of communication.
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
           Function: (1)after the client calls connect(), getsockname() may get the address and port of
           local host.(2) After connected, getpeername() used by server, after calling this, server may
           get the address and port of remote host.
           Some SCTP users might want to avoid blocking when they call socket interface function.
           Whenever the user which want to avoid blocking must call select() before calling
           If the socket status is not writable sendmsg() and sendto() return EAGAIN and do not
           transmit the message. Similarly, if the status is not readable, recvmsg() and recvfrom()
           return EAGAIN.
           Once all bind() calls are complete on a one-to-many style socket, the application must set
           the non-blocking option by a fcntl() (such as O_NONBLOCK). After which the sendmsg()
           function returns immediately, and the success or failure of the data message (and possible
           SCTP_INITMSG parameters) will be signaled by the SCTP_ASSOC_CHANGE event with
           SCTP_COMM_UP or CANT_START_ASSOC. If user data could not be sent (due to a
           CANT_START_ASSOC), the sender will also receive a SCTP_SEND_FAILED event.
           Those event(s) can be received by the user calling of recvmsg(). A server (having called
           listen()) is also notified of an association up event by the reception of a
           SCTP_ASSOC_CHANGE with SCTP_COMM_UP via the calling of recvmsg() and possibly
           the reception of the first data message.
            In order to shutdown the association gracefully, the user must call sendmsg() with no data
           and with the MSG_EOF flag set. The function returns immediately, and completion of the
           graceful shutdown is indicated by an SCTP_ASSOC_CHANGE notification of type
           SHUTDOWN_COMPLET.
           In this part, we introduce message header structure, control message header structure and
           some event structures. And in the following two parts, we introduce the functions and
           usage of these two kinds of structure. Firstly, we use socket interface sendmsg()(2.5.1) to
           show how msghdr and cmsghdr is used, then we inscribe a table to list each event(2.6.1)
           and explain how these events work.
           struct msghdr {
                        void           *msg_name;                /* Socket name*/
                        int            msg_namelen;              /* Length of name*/
                        struct iovec * msg_iov;                  /* Data blocks
                        */
                                                         DOCUMENTTYPE                               11 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                         TypeDateHere
           struct iovec {
                            void         iov_base;      /* beginning address of buffer. */
                            size_t       iov_len; /* the size of the buffer. */
           }
           struct cmsghdr {
           __kernel_size_t               cmsg_len;                      /* data byte count, including hdr */
           int                           cmsg_level;                    /* originating protocol */
           int                           cmsg_type;                     /* protocol-specific type */
           };
The use of the above two structures is same with TCP/UDP protocol.
           struct SCTP_cmsghdr {
                size_t                   cmsg_len; /* #bytes, including this header */
                int                      cmsg_level; /* originating protocol */
                sctp_cmsg_t              cmsg_type; /* protocol-specific type */
                sctp_cmsg_data_t         cmsg_data;
           };
TypeUnitOrDepartmentHere
TypeYourNameHere                                        TypeDateHere
                uint16_t sinit_max_init_timeo;
           };
           This cmsghdr structure provides information for initializing new SCTP associations with
           sendmsg(). The SCTP_INITMSG socket option used this same data structure. This
           structure is not used for recvmsg().
           This cmsghdr structure specifies SCTP options for sendmsg() and describes SCTP header
           information about a received message through recvmsg().
           enum sctp_sn_type {
                      SCTP_SN_TYPE_BASE = (1<<15),
                      SCTP_ASSOC_CHANGE,
                      SCTP_PEER_ADDR_CHANGE,
                      SCTP_SEND_FAILED,
                      SCTP_REMOTE_ERROR,
                      SCTP_SHUTDOWN_EVENT,
                      SCTP_PARTIAL_DELIVERY_EVENT,
                      SCTP_ADAPTION_INDICATION,
           };
This structure is notification to the user, let ULP know which event has happened.
2.5.3.1 SCTP_ASSOC_CHANGE
           struct sctp_assoc_change {
                        uint16_t sac_type;
                        uint16_t sac_flags;
                        uint32_t sac_length;
                        uint16_t sac_state;
                        uint16_t sac_error;
                        uint16_t sac_outbound_streams;
                                                    DOCUMENTTYPE                             13 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
                        uint16_t sac_inbound_streams;
                        sctp_assoc_t sac_assoc_id;
                        uint8_t sac_info[0];
           };
Communication notifications inform ULP that SCTP association has either begun or ended.
2.5.3.2 SCTP_PEER_ADDR_CHANGE
           struct sctp_paddr_change{
                        uint16_t spc_type;
                        uint16_t spc_flags;
                        uint32_t spc_length;
                        struct sockaddr_storage spc_aaddr;
                        int spc_state;
                        int spc_error;
                        sctp_assoc_t spc_assoc_id;
           };
2.5.3.3 SCTP_REMOTE_ERROR
           struct sctp_remote_error {
                uint16_t sre_type;
                uint16_t sre_flags;
                uint32_t sre_length;
                uint16_t sre_error;
                sctp_assoc_t sre_assoc_id;
                uint8_t sre_data[0];
           };
When peer encounter an operational error, it will send the error by this structure.
2.5.3.4 SCTP_SEND_FAILED
           struct sctp_send_failed {
                uint16_t ssf_type;
                uint16_t ssf_flags;
                uint32_t ssf_length;
                uint32_t ssf_error;
                struct sctp_sndrcvinfo ssf_info;
                sctp_assoc_t ssf_assoc_id;
                uint8_t ssf_data[0];
           };
           If a host can not deliver a message to peer, it will notify ULP with SCTP_SEND_FAILED
           event by this structure. Of course attached data in this structure can not be delivered to
           peer.
                                                    DOCUMENTTYPE                             14 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
2.5.3.5 SCTP_SHUTDOWN_EVENT
           struct sctp_shutdown_event {
                uint16_t sse_type;
                uint16_t sse_flags;
                uint32_t sse_length;
                sctp_assoc_t sse_assoc_id;
           };
2.5.3.6 SCTP_ADAPTION_INDICATION
           struct sctp_adaption_event {
                uint16_t sai_type;
                uint16_t sai_flags;
                uint32_t sai_length;
                uint32_t sai_adaptation_ind;
                sctp_assoc_t sse_assoc_id;
           };
           When a peer sends a Adaption Layer Indication parameter , SCTP delivers this notification
           to inform the application that of the peers requested adaption layer.
2.5.3.7 SCTP_PARTIAL_DELIVERY_EVENT
           struct sctp_rcv_pdapi_event {
                uint16_t pdapi_type;
                uint16_t pdapi_flags;
                uint32_t pdapi_length;
                uint32_t pdapi_indication;
                sctp_assoc_t pdapi_assoc_id;
           };
           When a receiver is engaged in a partial delivery of a message this notification will be used
           to indicate various events.
           Applications can use send() and sendto() to transmit data to the peer of an SCTP endpoint.
           recv() and recvfrom() can be used to receive data from the peer.
            ssize_t send(int sd, connst void *msg, size_t len, int flags);
            ssize_t sendto(int sd, const void *msg, size_t len, int flags,
                      const struct sockaddr *to, int tolen);
            ssize_t recv(int sd, void *buf, size_t len, int flags);
            ssize_t recvfrom(int sd, void *buf, size_t len, int flags,
                       struct sockaddr *from, int *fromlen);
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
           These calls give access to only basic SCTP protocol features. If either peer in the
           association uses multiple streams, or sends unordered data these calls will usually be
           inadequate, and may deliver the data in unpredictable ways.
           SCTP has the concept of multiple streams in one association. The above calls do not allow
           the caller to specify on which stream a message should be sent. The system uses stream
           0 as the default stream for send() and sendto(). recv() and recvfrom() return data from any
           stream, but the caller can not distinguish the different streams. This may result in data
           seeming to arrive out of order. Similarly, if a data chunk is sent unordered, recv() and
           recvfrom() provide no indication.
           SCTP is message based. The msg buffer above in send() and sendto() is considered to be
           a single message. This means that if the caller wants to send a message which is
           composed by several buffers, the caller needs to combine them before calling send() or
           sendto(). Alternately, the caller can use sendmsg() to do that without combining them.
           recv() and recvfrom() cannot distinguish message boundaries.
           In receiving, if the buffer supplied is not large enough to hold a complete message, the
           receive call acts like a stream socket and returns as much data as will fit in the buffer.
           Note, the send and recv calls, when used in the UDP-style model, may only be used with
           branched off socket descriptors (see Section 2.8.2).
           Note, if an application calls a send function with no user data and no ancillary data the
           SCTP implementation should reject the request with an appropriate error message. An
           implementation is NOT allowed to send a Data chunk with no user data.
           These two functions encapsulate most parameters in struct msghdr, flags has the same
           meaning of flags in send(). We have introduced the structure of msghdr in 2.5.1.1. . When
                                                     DOCUMENTTYPE                              16 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
           Applications can use read() and write() to send and receive data to and from peer. They
           have the same semantics as send() and recv() except that the flags parameter cannot be
           used.
           Note, these calls, when used in the one to many style model, may only be used with
           branched off socket descriptors .
2.6.4 getsockname()
              address - On return, one locally bound address (chosen by the SCTP stack) is stored in
                        this buffer. If the socket is an IPv4 socket, the address will be IPv4. If the
                        socket is an IPv6 socket, the address will be either an IPv6 or IPv4 address.
              len    - The caller should set the length of address here. On return, this is set to the
                      length of the returned address.
           If the actual length of the address is greater than the length of the supplied sockaddr
           structure, the stored address will be truncated.
           If the socket has not been bound to a local name, the value stored in the object pointed to
           by address is unspecified.
                                                      DOCUMENTTYPE                                17 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
           Applications use setsockopt() and getsockopt() to set or retrieve socket options. Socket
           options are used to change the default behavior of sockets calls. They are described in
           Section 2.7.
7. SCTP_PARTIAL_DELIVERY_EVENT (sctp_partial_delivery_event):
8. SCTP_ADAPTION_INDICATION (sctp_adaption_layer_event):
           To receive any ancillary data or notifications, first the application registers it's interest by
           calling the SCTP_EVENTS setsockopt() with the following structure.
             struct sctp_event_subscribe{
                u_int8_t sctp_data_io_event;
                u_int8_t sctp_association_event;
                                                        DOCUMENTTYPE                               18 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                        TypeDateHere
                  u_int8_t sctp_address_event;
                  u_int8_t sctp_send_failure_event;
                  u_int8_t sctp_peer_error_event;
                  u_int8_t sctp_shutdown_event;
                  u_int8_t sctp_partial_delivery_event;
                  u_int8_t sctp_adaption_layer_event;
             };
           sctp_association_event - Setting this flag to 1 will enable the reception of association event
           notifications. Setting the flag to 0 will disable association event notifications.
           sctp_address_event - Setting this flag to 1 will enable the reception of address event
           notifications. Setting the flag to 0 will disable address event notifications.
           sctp_send_failure_event - Setting this flag to 1 will enable the reception of send failure
           event notifications. Setting the flag to 0 will disable send failure event notifications.
           sctp_peer_error_event - Setting this flag to 1 will enable the reception of peer error event
           notifications. Setting the flag to 0 will disable peer error event notifications.
           sctp_shutdown_event - Setting this flag to 1 will enable the reception of shutdown event
           notifications. Setting the flag to 0 will disable shutdown event notifications.
           sctp_adaption_layer_event - Setting this flag to 1 will enable the reception of adaption layer
           notifications. Setting the flag to 0 will disable adaption layer event notifications.
memset(&event,0,sizeof(event));
event.sctp_data_io_event = 1;
……
SCTP_SNDRCV);
                  ……
                                                    DOCUMENTTYPE                              19 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
             if (msg->msg_controllen != controllen) {
                      printf("Got control structure of length %d, not %d\n",
                                 msg->msg_controllen, controllen);
                      DUMP_CORE;
             }
             if (controllen > 0 && event != CMSG_FIRSTHDR(msg)->cmsg_type) {
                      printf("Wrong kind of event: %d, not %d\n",
                      CMSG_FIRSTHDR(msg)->cmsg_type, event);
                      DUMP_CORE;
             }
return 1;
} /* test_check_message() */
           All those test functions we have examples in /noklksctp/test/funutil.c. Users clould use it as
           a guide.
            Programming with ancillary socket data contains some subtleties and pitfalls, which are
           discussed below.
           Multiple ancillary data items may be included in any call to sendmsg() or recvmsg(); these
           may include multiple SCTP or non-SCTP items, or both. The ordering of ancillary data
           items (either by SCTP or another protocol) is not significant and is implementation-
           dependent, so applications must not depend on any ordering.
            SCTP_SNDRCV items must always correspond to the data in the msghdr's msg_iov
           member. There can be only a single SCTP_SNDRCV info for each sendmsg() or
           recvmsg() call.
           Applications can infer the presence of data or ancillary data by examining the msg_iovlen
           and msg_controllen msghdr members, respectively. Implementations may have different
           padding quirements for ancillary data, so portable applications should make use of the
           macros CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_SPACE, and
                                                    DOCUMENTTYPE                              20 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
           CMSG_LEN. See RFC2292 and your SCTP implementation's documentation for more
           information. Following is an example, from RFC2292, demonstrating the use of these
           macros to access ancillary data:
           The information conveyed via SCTP_SNDRCV events will often be fundamental to the
           correct and sane operation of the sockets application. This is particularly true of the one-to-
           many semantics, but also of the one-ton-one semantics. For example, if an application
           needs to send and receive data on different SCTP streams, SCTP_SNDRCV events are
           indispensable.
           Given that some ancillary data is critical, and that multiple ancillary data items may appear
           in any order, applications should be carefully written to always provide a large enough
           buffer to contain all possible ancillary data that can be presented by recvmsg(). If the buffer
           is too small, and crucial data is truncated, it may pose a fatal error condition.
           Although lksctp has data structures in linux kernel, all the data structures should be
           included in a .h file, the files name could be named by the programmer, while the .h file
           must be clearly indicated its directory in the makefile.
           The implementation supplies various SCTP level socket options that are common to both
           models. SCTP associations can be multi-homed. Therefore, certain option parameters
           include a sockaddr_storage structure to select which peer address the option should be
           applied to.
           For the one to many style sockets, an sctp_assoc_t structure (association ID) is used to
           identify the the association instance that the operation affects. So it must be set when
           using this model.
           For the one to one style sockets and branched off one to one style sockets (see Section
           2.8) this association ID parameter is ignored. In the cases noted below where the
           parameter is ignored, an application can pass to the system a corresponding option
           structure similar to those described below but without the association ID parameter, which
           should be the last field of the option structure. This can make the option setting/getting
           operation more efficient. If an application does this, it should also specify an appropriate
           optlen value (i.e. sizeof (option parameter) - sizeof (struct sctp_assoc_t)).
                                                       DOCUMENTTYPE                             21 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
             Note that socket or IP level options is set or retrieved per socket. This means that for one to
             one style sockets, those options will be applied to all associations belonging to the socket.
             And for TCP-style model, those options will be applied to all peer addresses of the
             association controlled by the socket. Applications should be very careful in setting those
             options.
                                              Corresponding
               Option event                                                   Option function
                                                structure
                                                                           Modifiy and examine
        SCTP_RTOINFO                              sctp_rtoinfo           retransmission timeout
                                                                                parameters
                                                                            Modify and examine
        SCTP_ASSOCINFO                        sctp_associnfo            association and endpoint
                                                                                parameters
                                                                            Modify and examine
        SCTP_INITMSG                              sctp_initmsg
                                                                       initialization parameters
                                                                            Perform SCTP ABORT
        SO_LINGER(TCP only)                          Linger
                                                                                 primitive
                                            (no corresponding
                                                                       Turn on/off any nagle-like
        SCTP_NODELAY                         structure only a
                                                                                algorithm
                                                parameter)
                                            (no corresponding
        SO_RCVBUF                            structure only a           Sets receive buffer size
                                                parameter)
                                            (no corresponding
        SO_SNDBUF                            structure only a             Sets send buffer size
                                                parameter)
                                            (no corresponding                Perform wether the
        SCTP_AUTOCLOSE(UDP only)             structure only a             association could auto
                                                parameter)                          close.
                                                                      Requests that the peer mark
        SCTP_SET_PEER_PRIMARY               Sctp_setpeerprim          the enclosed address as the
                                                                      association primary.
                                                                         Requests that the local
                                                                      SCTP stack use the enclosed
        SCTP_PRIMARY_ADDR                         sctp_setprim
                                                                               peer address as
                                                                           the association primary.
                                                                         Requests that the local
                                                                       endpoint set the specified
                                                                                Adaption Layer
        SCTP_ADAPTION_LAYER                 sctp_setadaption
                                                                           Indication parameter for
                                                                        all future INIT and INIT-
                                                                                ACK exchanges.
                                            (no corresponding
                                                                       Turn on/off fragments of a
        SCTP_DISABLE_FRAGMENTS               structure only a
                                                                                 message
                                                parameter)
        SCTP_PEER_ADDR_PARAM                 sctp_paddrparams               enable or disable
                                                                         heartbeats for any peer
                                                                       address of an association,
                                                                           modify an address's
                                                                      heartbeat interval, force a
                                                                            heartbeat to be sent
                                                                      immediately, and adjust the
                                                                            address's maximum
                                                                                  number of
                                                       DOCUMENTTYPE                            22 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
                                                                              retransmissions
                                                                        specify a default set of
         SCTP_DEFAULT_SEND_PARAM                sctp_sndrcvinfo
                                                                                  parameters
                                                                              specify various
                                                   Each event
                                                                             notifications and
         SCTP_EVENTS                           correspond a data
                                                                           ancillary data the user
                                                    structure
                                                                            wishes to receive.
                                               (no corresponding          Turn on/off whether v4
         SCTP_I_WANT_MAPPED_V4_ADDR             structure only a        address can be mapped v6
                                                   parameter)                       address
                                               (no corresponding       specifies the maximum size
         SCTP_MAXSEG                            structure only a          to put in any outgoing
                                                   parameter)                   SCTP DATA chunk.
                                                                          etrieve current status
         SCTP_STATUS(read only)                   sctp_status
                                                                                 information
                                                                       retrieve information about
         SCTP_GET_PEER_ADDR_INFO                sctp_paddrinfo           a specific peer address
                                                                               of an association
2.10.1 sctp_bindx()
              If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. If the sd is an IPv6
              socket, the addresses passed can either be IPv4 or IPv6 addresses.
              addrs is a pointer to an array of one or more socket addresses. Each address is contained
              in a struct sockaddr_storage, so each address is a fixed length. The caller specifies the
              number of addresses in the array with addrcnt.
              On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns -1, and sets errno to
              the appropriate error code.
              For SCTP, the port given in each socket address must be the same, or sctp_bindx() will fail,
              setting errno to EINVAL.
              The flags parameter is formed from the bitwise OR of zero or more of the following currently
              defined flags:
SCTP_BINDX_ADD_ADDR
              SCTP_BINDX_REM_ADDR
                                                    DOCUMENTTYPE                              23 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
2.10.2 sctp_peeloff()
           This is particularly desirable when, for instance, the application wishes to have a number of
           sporadic message senders/receivers remain under the original UDP-style socket but branch
           off those associations carrying high volume data traffic into their own separate socket
           descriptors.
           The application uses sctp_peeloff() call to branch off an association into a separate socket
           (Note the semantics are somewhat changed from the traditional TCP-style accept() call).
           the original UDP-style socket descriptor returned from the socket() system call (see Section
           3.1.1).
           the specified identifier of the association that is to be branched off to a separate file
           descriptor (Note, in a traditional TCP-style accept() call, this would be an out parameter, but
           for the UDP-style call, this is an in parameter).
2.10.3 sctp_getpaddrs()
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
           On return, addrs will point to a dynamically allocated array of struct sockaddr_storages, one
           for each peer address. The caller should use sctp_freepaddrs() to free the memory. addrs
           must not be NULL.
           If sd is an IPv4 socket, the addresses returned will be all IPv4 addresses. If sd is an IPv6
           socket, the addresses returned can be a mix of IPv4 or IPv6 addresses.
           For UDP-style sockets, id specifies the association to query. For TCP-style sockets, id is
           ignored.
2.10.4 sctp_freepaddrs()
2.10.5 sctp_getladdrs()
sctp_getladdrs() returns all locally bound address on a socket. The syntax is,
           On return, addrs will point to a dynamically allocated array of struct sockaddr_storages, one
           for each local address. The caller should use sctp_freeladdrs() to free the memory. addrs
           must not be NULL.
           If sd is an IPv4 socket, the addresses returned will be all IPv4 addresses. If sd is an IPv6
           socket, the addresses returned can be a mix of IPv4 or IPv6 addresses.
           For UDP-style sockets, id specifies the association to query. For TCP-style sockets, id is
           ignored.
           If the id field is set to the value '0' then the locally bound addresses are returned without
           regard to any particular association.
           On success, sctp_getladdrs() returns the number of local addresses bound to the socket. If
           the socket is unbound, sctp_getladdrs() returns 0, and the value of *addrs is undefined. If
           an error occurs, sctp_getladdrs() returns -1, and the value of *addrs is undefined.
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
2.10.6 sctp_freeladdrs()
2.10.7 sctp_sendmsg()
    ssize_t sctp_sendmsg(int s,
                const void *msg,
                size_t len,
                struct sockaddr *to,
                socklen_t tolen,
                uint32_t ppid,
                uint32_t flags,
                uint16_t stream_no,
                uint32_t timetolive,
                uint32_t context)
2.10.8 sctp_recvmsg()
    ssize_t sctp_recvmsg(int s,
               void *msg,
               size_t *len,
               struct sockaddr *from,
               socklen_t *fromlen
               struct sctp_sndrcvinfo *sinfo
               int *msg_flags)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
Notes: The four interfaces getpaddrs(),freepaddrs(), getladdrs(),freeladdrs() are non-system call API.
             These APIs of the sctp are not part of the standard set of system calls in linux kernel. For
             that reason, these functions are plemented with the use of other system calls to interface
             kernel back-end from the user-level front-end. So any application that is to make use of
             these functions has to have sctpulib.c source file as its part. Header file is sctpulib.h.
              These files:
              sctpulib.c
              sctpulib.h
3. INSTALLATION GUIDE
Reference http://www.sourceforge.net/
Give the userid to project manager and add you to noklksctp developer list.
$ cd noklksctp
$ mkdir linux_sctp
$ cd tools
              $ ./mklinux_sctp.sh
                                                    DOCUMENTTYPE                                 27 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
$ ./updatelinux_sctp.sh
TypeUnitOrDepartmentHere
TypeYourNameHere                                        TypeDateHere
              cd linux_sctp
              make xconfig
                              code materity -> yes
                              Networking -> IPv6 -> Module
                              Networking -> SCTP -> Module
              make dep
              make bzImage;
              su -
              cp arch/i386/boot/bzImage /boot/vmlinuz-sctp
              vi /etc/grub.conf
                            title Red Hat Linux (sctp)
                            root (hd0,0)
                            kernel /boot/vmlinuz-sctp ro root=/dev/hda1
              reboot
              make modules; make modules_install
              insmod ipv6
              insmod sctp
4. REFFERENCE
1. rfc2960.txt
2. draft-ietf-tsvwg-sctpsocket-05.txt
3. project webpage
http://www.china.nokia.com/nokia/www/cnrdait.nsf/document/BE045C55X4?OpenDocument
5. EXAMPLES
5.1 Server
              In this TCP style example, server finish the function of socket(), bind(), listen(), accept() and
              close().
#include    <stdio.h>
#include    <stdlib.h>
#include    <sys/types.h>
#include    <sys/socket.h>               /* needed by linux/sctp.h */
#include    <sys/uio.h>
#include    <netinet/in.h>               /* for sockaddr_in */
#include    <sys/errno.h>
#include    <errno.h>
#include    <sctp.h>
int
main(void)
{
                                             DOCUMENTTYPE                       29 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                             TypeDateHere
           int sk;
           int pf_class;
           sockaddr_storage_t loopSer;
           int newsk;
           struct sockaddr newAddr;
printf("Listening ...\n");
           notAccepted = 1;
           while(notAccepted) {
                      newsk = accept(sk, (struct sockaddr *)&newAddr, &len);
                      notAccepted = 0;
                        if (0 >= newsk) {
                                   printf("Can not open as new socket...\n");
                                   exit(1);
                        }
                        printf("Socket is opened.\n");
           }
sleep (3);
           if (0 != close(sk) ||
               0 != close(newsk)) {
                                                     DOCUMENTTYPE                            30 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
return 0;
5.2 Client
Note: in this TCP style example(which corresponding to the above, it shows the function of socket(),
bind(), connect(), setsockopt(), getsockopt(). )
#include   <stdio.h>
#include   <stdlib.h>
#include   <sys/types.h>
#include   <sys/socket.h>              /* needed by linux/sctp.h */
#include   <sys/uio.h>
#include   <netinet/in.h>              /* for sockaddr_in */
#include   <sys/errno.h>
#include   <errno.h>
#include   <sctp.h>
int
main(void)
{
             int sk;
             int pf_class;
             sockaddr_storage_t loopClt, loopSer;
             struct sctp_assocparams asocparam,setparam;
             struct sctp_initmsg initmsg, reinitmsg;
             int   error;
             int   optlen;
             int   nodelay = 0 , renodelay = 0;
             int   sbuf, resbuf;
#if TEST_V6
           pf_class = PF_INET6;
           loopClt.v6.sin_family = AF_INET6;
           loopClt.v6.sin_port = htons(C_PORT);
           loopSer.v6.sin_family = AF_INET6;
            loopSer.v6.sin_port = htons(S_PORT);
           inet_aton(SERVER, &loopSer.v6.sin_addr);
            inet_aton(CLIENT, &loopClt.v6.sin_addr);
#else
           pf_class = PF_INET;
           loopClt.v4.sin_family = AF_INET;
           loopClt.v4.sin_port = htons(C_PORT);
           loopSer.v4.sin_family = AF_INET;
            loopSer.v4.sin_port = htons(S_PORT);
           inet_aton(SERVER, &loopSer.v4.sin_addr);
           inet_aton(CLIENT, &loopClt.v4.sin_addr);
#endif
TypeUnitOrDepartmentHere
TypeYourNameHere                           TypeDateHere
        if (sk == -1) {
                printf("Can not creat a socket\n");
                exit(-1);
        }
printf("Connecting ...\n");
TypeUnitOrDepartmentHere
TypeYourNameHere                           TypeDateHere
        if (error != 0) {
                      printf("set socket option error!\n");
                      printf("errno is :%s\n", sys_errlist[errno]);
                      exit(1);
           }else{
                      printf("set socket option asocmaxrtx = 4.\n");
                      printf("set socket option cookie_life = 1000000.\n");
           }
TypeUnitOrDepartmentHere
TypeYourNameHere                           TypeDateHere
        if ((initmsg.sinit_num_ostreams != reinitmsg.sinit_num_ostreams)||
               (initmsg.sinit_max_instreams != initmsg.sinit_max_instreams)||
            (initmsg.sinit_max_attempts != initmsg.sinit_max_attempts )||
            (initmsg.sinit_max_init_timeo !=initmsg.sinit_max_init_timeo))
        {
                printf("Test case 11.2 for SCTP_INITMSG Fail.\n\n");
                      exit(-1);
        }else{
                printf("Test case 11.2 for SCTP_INITMSG passes!\n\n");
        }
        /* End of TEST case 11.3: SCTP_INITMSG socket option.*/
TypeUnitOrDepartmentHere
TypeYourNameHere                           TypeDateHere
        if (renodelay == nodelay){
                printf("Test case 11.5 for SCTP_NODELAY passes!\n\n\n");
        }else{
                printf("Test case 11.5 for SCTP_NODELAY Fail.\n\n\n");
        }
           if (0 != close(sk)) {
                      printf("Error closing ...\n");
                      return -1;
           }
return 0;
}
                                                      DOCUMENTTYPE                               35 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
6. SCTP IN FLEXISERVER
           The general instructions in the previous chapters apply. In case of any conflicts, the
           instructions in this chapter override the instructions elsewhere in this document.
           netinet/sctp.h is included in source modules normally. However, in order to get the correct
           version of sctp.h, $(SCTP_INC) must be added to include paths in makefile. Note that it
           should be the first include path in the list in order to override other sctp.h files found in any
           other include paths.
           Example:
                  INCFLAGS = \
                          -I$(SCTP_INC) \
                          -I$(SRCDIR) \
                          -I$(TTEN_HOME)/include
           Or if INCFLAGS doesn't place SCTP_INC sufficiently close to the start of the compiler
           command, just put it in CXXLOCALOPTS:
                  CXXLOCALOPTS = -I$(SCTP_INC) -O3 -Wall
           The SCTP Library, libsctp, provides the following functions for the SCTP user:
                  unsigned long bindx(int fd, struct sockaddr_storage *bindx_addr,
                                      int addrcnt, int flags);
                  int sctp_peeloff(int fd, sctp_assoc_t *associd);
                  int sctp_sendmsg(int s,
                                   const void *msg,
                                   int len,
                                   struct sockaddr *to,
                                   int tolen,
                                   uint32_t ppid,
                                   uint32_t flags,
                                   uint32_t stream_no,
                                   uint32_t timetolive,
                                   uint32_t context);
                  int sctp_recvmsg(int s,
                                   void *msg,
                                   int *len,
                                   struct sockaddr *from,
                                   int *from_len,
                                                    DOCUMENTTYPE                              36 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
           These are documented in the SCTP Sockets API Draft (IETF), and also in this document,
           Section 2.10.
           libsctp is a static library that resides in SS_LibSS7Stack/sctp. The library is not related to
           SS_LibSS7Stack as such, the subsystem acts simply as a storage place for libsctp. libsctp
           is used like any other library in FlexiServer. Source modules that use any of the functions
           listed above, must include sctp_lib.h. The following settings must be added in makefile in
           order to compile and link with libsctp:
                  INCFLAGS = -I$(DIR_SS_LIBSS7STACK)/sctp/src/
                  LIBRARIES = $(DIR_SS_LIBSS7STACK)/sctp/build/libsctp.a
                  APPLIBS = -L$(DIR_SS_LIBSS7STACK)/sctp/build -lsctp
           An LBSCTP (Load Balancer SCTP) socket is a special kind of SCTP socket specific to the
           FlexiServer IPD kernel. LBSCTP sockets are used in the IPD for handling multiplexed
           associations to internal nodes. For load balancing purposes, FlexiServer Recovery Groups
           have virtual IPs, that is, all Recovery Units of an Recovery Group in all nodes are
           addressed with the same IP. Hence, in order to address a specific node, the node's MAC
           address is required in addition to the IP. LBSCTP sockets are used exactly like normal
           SCTP sockets, with the exceptions explained below.
           The user code must define the following: AF_INET6 and SOCK_STREAM are also valid
           with LBSCTP sockets just like they are valid with normal SCTP sockets.
                  #ifndef IPPROTO2LB
                  #define IPPROTO2LB(arg) ((arg) | 0x100)
                  #define LB2IPPROTO(arg) ((arg) & ~0x100)
                  #define IPPROTO_LBSCTP IPPROTO2LB(IPPROTO_SCTP)
                  #endif /* !IPPROTO2LB */
                  #ifndef AF_LBHWADDR
                  #define AF_LBHWADDR 30
                  #define PF_LBHWADDR AF_LBHWADDR
                  #endif /* !AF_LBHWADDR */
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
           All calls involving the peer address (the address of an internal node) must include the MAC
           address in addition to the virtual IP address. For this purpose, the user code should define
           an address structure:
                  struct
                    {
                      struct sockaddr mac_addr; /* MAC */
                      struct sockaddr_in ip_addr; /* virtual IP (in this case IPv4) */
                    } address;
           After the address structure is filled, it can be used in any calls requiring the peer address,
           such as connect() and sendmsg(). recvmsg() works similarly, the address structure is of
           course filled by the recvmsg() call. Prior to the recvmsg() call the address structure must be
           filled with zeroes. An example connect() call:
                  connect(fd, &address, sizeof(address));
           The size of the address structure must include the MAC as well as the IP. Hence,
           sizeof(address) instead of just sizeof(sockaddr_in).
           All of the above is valid for IPv6 also, with sockaddr_in6 instead of sockaddr_in and
           AF_INET6 instead of AF_INET.
           An LBSCTP socket can also be used as a server socket in IPD, listening to connections
           from the internal nodes. Such a server socket must be bound to IPADDR_ANY and a given
           port. The server socket will then accept connections from the internal nodes to any IP
           address, as long as the connection is made using the given port and the client socket in the
           internal node is bound to a virtual IP. The idea is that an application in an internal node
           attempts to form an SCTP association to an external peer. Regardless of the external
           peer's IP address, the association is in fact formed to a server process in IPD. Effectively,
           the association is "hijacked" by a loadbalancer process in IPD and the IPD poses as the
           external peer for the application in the internal node. After a new association has been
           formed using an LBSCTP server socket, an sctp_getladdr() call for that association will
           return the IP to which the association was being formed to from the internal node. In other
           words, the IP address of the external peer. For one-to-one LBSCTP sockets in IPD,
           getpeername() returns struct address (including MAC and IP) containing the address of the
           internal node. There is no parameter in getpeername() to specify an association in a one-
           to-many socket, so getpeername() does not support one-to-many sockets. Since recvmsg()
           returns the address of the peer in msg_name member of struct msghdr, the server process
           in IPD can get the internal node's address from the COMM_UP notification when the
           association is formed. This is what the SS7 Load Balancer does.
                                                       DOCUMENTTYPE                         38 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
APPENDIX A
             PF_INET only support Ipv4 address, while PF_INET6 can support both IPv4 and IPv6
             address. SCTP allow a mapped IPv6 address communicate with a host which has IPv4
             address.
ssize_t sendmsg(int socket, const struct msghdr *message, int flag s);
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
             nam - the address structure (either struct sockaddr_in or struct sockaddr_in6 defined       in
             [RFC 2553]).
1.using bind()
             Once all bind() calls are complete on a UDP-style socket, the application can begin sending
             and receiving data using the sendmsg()/recvmsg() or sendto()/recvfrom() calls, without
             going through any explicit association setup procedures (i.e., no connect() calls required).
2. without bind()
             Whenever sendmsg() or sendto() is called and the SCTP stack at the sender finds that
             there is no association existing between the sender and the intended receiver (identified by
             the address passed either in the msg_name field of msghdr structure in the sendmsg() call
             or the dest_addr field in the sendto() call), the SCTP stack will automatically setup an
             association to the intended receiver.
             Some SCTP users might want to avoid blocking when they call socket interface function.
             Whenever the user which want to avoid blocking must call select() before calling
             sendmsg()/sendto() and recvmsg()/recvfrom(), and check the socket status is writable or
             readable. Once all bind() calls are complete on a UDP-style socket, the application must
             set the non-blocking option by a fcntl() (such as O_NONBLOCK). In order to shutdown the
             association gracefully, the user must call sendmsg() with no data and with the MSG_EOF
             flag set.
             This model enables existing applications using connection oriented protocols to be ported
             to SCTP with very little effort. Note that some new SCTP features and some new SCTP
             socket options can only be utilized through the use of sendmsg() and recvmsg() calls.
TypeUnitOrDepartmentHere
TypeYourNameHere                                        TypeDateHere
             PF_INET only support Ipv4 address, while PF_INET6 can support both IPv4 and IPv6
             address. SCTP allow a mapped IPv6 address communicate with a host which has IPv4
             address.
             backlog - this specifies the max number of outstanding associations allowed in the socket's
             accept queue. These are the associations that have finished the four-way initiation
             handshake (see Section 5 of [SCTP]) and are in the ESTABLISHED state. Note, a backlog
             of '0' indicates that the caller no longer wishes to receive new.
             SHUT_RD
                                                     DOCUMENTTYPE                               41 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
Note:
                         Socket who calls the shutdown(sd, SHUT_RD): it could not receive messages
                         and datas any more even the peer continuously sends messages and datas,
                         while it could sends messages and datas. After call shutdown(sd, SHUT_RD),
                         each time the socket call recv, 0 will be returned indicating EOF.
                         Socket who receive the shutdown signal: nothing else will be different with the
                         socket.
SHUT_WR
Disables further send operations, and initiates the SCTP shutdown sequence.
Note:
                         Socket who receives the shutdown ack: if it receives shutdown signal, call
                         recv() on the socket will not return error, instead it will return 0 indicating EOF.
SHUT_RDWR
                         Disables further send and receive operations and initiates the SCTP
                         shutdown sequence.
Note:
                         Neither of the sockets could send messages or datas; neither of them could
                         receive any messages and datas. If recv() is called, 0 will be returned; if
                         send() or sendto() will be called, an error will returnd.
            The semantics is similar to those used in the UDP-style model (section 2.3.1.4), with the
            following differences:
                1) When sending, the msg_name field in the msghdr is not used to specify the intended
            receiver, rather it is used to indicate a different peer address if the sender does not want to
            send the message over the primary address of the receiver. If the transport address given
            is not part of the current association, the data will not be sent and a SCTP_SEND_FAILED
            event will be delivered to the application if send failure events are enabled. When receiving,
            if a message is not received from the primary address, the SCTP stack will fill in the
            msg_name field on return so that the application can retrieve the source address
            information of the received message.
TypeUnitOrDepartmentHere
TypeYourNameHere                                     TypeDateHere
A.2.1.9 getpeername()
            address - On return, the peer primary address is stored in this buffer. If the socket is an
            IPv4 socket, the address will be IPv4. If the socket is an IPv6 socket, the address will be
            either an IPv6 or mapped IPv4 address.
            len - The caller should set the length of address here. On return, this is set to the length
            of the returned address.
                                                       DOCUMENTTYPE                           43 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
APPENDIX B
           The protocol parameters used to initialize and bound retransmission timeout (RTO) are
           tunable. The peer address parameter is ignored for TCP style socket.
             struct sctp_rtoinfo {
                sctp_assoc_t          srto_assoc_id;
                uint32_t           srto_initial;
                uint32_t           srto_max;
                uint32_t           srto_min;
             };
           All parameters are time values, in milliseconds. A value of 0, when modifying the
           parameters, indicates that the current value should not be changed.
           This option is used to both examine and set various association and endpoint parameters.
           The peer address parameter is ignored for TCP style socket.
             struct sctp_assocparams {
                sctp_assoc_t sasoc_assoc_id;
                uint16_t    sasoc_asocmaxrxt;
                uint16_t    sasoc_number_peer_destinations;
                uint32_t    sasoc_peer_rwnd;
                uint32_t    sasoc_local_rwnd;
                uint32_t    sasoc_cookie_life;
             };
              sasoc_asocmaxrxt - This contains the maximum retransmission attempts
                                  to make for the association.
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
               sasoc_local_rwnd - This holds the last reported rwnd that was sent to the peer.
               sasoc_cookie_life - This is the associations cookie life value used when issuing cookies.
               sasoc_assoc_id - (UDP style socket) This is filled in the application, and identifies the
                                 association for this query.
            This information may be examined for either the endpoint or a specific association. To
            examine a endpoints default parameters the association id (sasoc_assoc_id) should must
            be set to the value '0'. The values of the sasoc_peer_rwnd is meaningless when examining
            endpoint information.
SCTP_ASSOCRTXINFO.
            Note: When configuring the SCTP endpoint, the user should avoid having the value of
            'Association.Max.Retrans' larger than the summation of the 'Path.Max.Retrans' of all the
            destination addresses for the remote endpoint. Otherwise, all the destination
            addressesmay become inactive while the endpoint still considers the peer endpoint
            reachable.
            Applications can specify protocol parameters for the default association initialization. The
            structure used to access and modify these parameters is defined in Section 2.5.2.1). The
            option name argument to setsockopt() and getsockopt() is SCTP_INITMSG.
            struct sctp_initmsg {
                          uint16_t sinit_num_ostreams;
                          uint16_t sinit_max_instreams;
                          uint16_t sinit_max_attempts;
                         uint16_t sinit_max_init_timeo;
             };
            This is an integer number representing the number of streams that the application wishes to
            be able to send to. This number is confirmed in the SCTP_COMM_UP notification and
            must be verified since it is a negotiated number with the remote endpoint. The default
            value of 0 indicates to use the endpoint default value.
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
           This value represents the maximum number of inbound streams the application is prepared
           to support. This value is bounded by the actual implementation. In other words the user
           MAY be able to support more streams than the Operating System. In such a case, the
           Operating System limit overrides the value requested by the user. The default value of 0
           indicates to use the endpoint's default value.
           This integer specifies how many attempts the SCTP endpoint should make at resending the
           INIT. This value overrides the system SCTP 'Max.Init.Retransmits' value. The default
           value of 0 indicates to use the endpoint's default value. This is normally set to the system's
           default 'Max.Init.Retransmit' value.
           This value represents the largest Time-Out or RTO value to use in attempting a INIT.
           Normally the 'RTO.Max' is used to limit the doubling of the RTO upon timeout. For the INIT
           message this value MAY override 'RTO.Max'. This value MUST NOT influence 'RTO.Max'
           during data transmission and is only used to bound the initial setup time. A default value of
           0 indicates to use the endpoint's default value. This is normally set to the system's TO.Max'
           value (60 seconds).
B.1.4 SO_LINGER
           An application using the TCP-style socket can use this option to perform the SCTP ABORT
           primitive. The linger option structure is:
             struct linger {
                int l_onoff;            /* option on/off */
                int l_linger;           /* linger time */
             };
           To enable the option, set l_onoff to 1. If the l_linger value is set to 0, calling close() is the
           same as the ABORT primitive. If the value is set to a negative value, the setsockopt() call
           will return an error. If the value is set to a positive value linger_time, the close() can be
           blocked for at most linger_time ms. If the graceful shutdown phase does not finish during
           this period, close() will return but the graceful shutdown phase continues in the system.
B.1.5 SO_NODELAY
           Turn on/off any Nagle-like algorithm. This means that packets are generally sent as soon
           as possible and no unnecessary delays are introduced, at the cost of more packets in the
           network.
           Note that all the current SCTP implementations still have no Nagle like algorithm, including
           our Linux Kernel SCTP. It is need to be extended later.
                                                      DOCUMENTTYPE                               46 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
B.1.6 SO_RCVBUF
           Sets receive buffer size. For SCTP TCP-style sockets, this controls the receiver window
           size. For UDP-style sockets, this controls the receiver window size for all associations
           bound to the socket descriptor used in the setsockopt() or getsockopt() call. The option
           applies to each association's window size separately. Expects an integer or uint32_t.
B.1.7 SO_SNDBUF
           Sets send buffer size. For SCTP TCP-style sockets, this controls the amount of data SCTP
           may have waiting in internal buffers to be sent. This option therefore bounds the maximum
           size of data that can be sent in a single send call. For UDP-style sockets, the effect is the
           same, except that it applies to all associations bound to the socket descriptor used in the
           setsockopt() or getsockopt() call. The option applies to each association's window size
           separately. Expects an integer or uint32_t.
           This socket option is applicable to the UDP-style socket only. When set it will cause
           associations that are idle for more than the specified number of seconds to automatically
           close. An association being idle is defined an association that has NOT sent or received
           user data. The special value of '0' indicates that no automatic close of any associations
           should be performed. The option expects an integer defining the number of seconds of idle
           time before an association is closed.
           Requests that the peer mark the enclosed address as the association primary. The
           enclosed address must be one of the association's locally bound addresses. The following
           structure is used to make a set primary request:
             struct sctp_setprim {
                sctp_assoc_t        ssp_assoc_id;
                struct sockaddr_storage ssp_addr;
             };
               ssp_addr         The address to set as primary
              ssp_assoc_id       (UDP style socket) This is filled in by the application, and identifies
                                 the association for this request.
           Requests that the local SCTP stack use the enclosed peer address as the association
           primary. The enclosed address must be one of the association peer's addresses. The
           following structure is used to make a set peer primary request:
             struct sctp_setpeerprim {
                                                       DOCUMENTTYPE                               47 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                       TypeDateHere
                 sctp_assoc_t        sspp_assoc_id;
                 struct sockaddr_storage sspp_addr;
            };
           Requests that the local endpoint set the specified Adaption Layer Indication parameter for
           all future INIT and INIT-ACK exchanges.
                 struct sctp_setadaption {
                    u_int32_t ssb_adaption_ind;
                 };
                 ssb_adaption_ind     The adaption layer indicator that will be included in any outgoing
                                      Adaption Layer Indication parameter.
           This option requests that the requested stream apply a default time-out for messages in
           queue. The default value is used when the application does not specify a timeout in the
           sendrcvinfo structure (sinfo_timetolive element see Section 2.5.2.2).
            struct sctp_setstrm_timeout {
               sctp_assoc_t ssto_assoc_id;
               u_int32_t     ssto_timeout;
               u_int16_t     ssto_streamid_start;
               u_int16_t     ssto_streamid_end;
            };
                 ssto_assoc_id      (UDP style socket) This is filled in by the application, and identifies
                                   the association for this request.
                 ssto_timeout     The maximum time in milliseconds that messages should be held
                                   inqueue before failure.
                 ssto_streamid_start The beginning stream identifier to apply this default against.
                 ssto_streamid_end The ending stream identifier to apply this default against.
           Note that the current SCTP implementations still don`t support the time-out for messages in
           queue. It is within the PR-SCTP extension, and need to be extended later.
           This option is an on/off flag. If enabled no SCTP message fragmentation will be performed.
           Instead if a message being sent exceeds the current PMTU size, the message will NOT be
           sent and instead a error will be indicated to the user.
                                                   DOCUMENTTYPE                            48 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                   TypeDateHere
           Applications can enable or disable heartbeats for any peer address of an association,
           modify an address's heartbeat interval, force a heartbeat to be sent immediately, and adjust
           the address's maximum number of retransmissions sent before an address is considered
           unreachable. The following structure is used to access and modify an address's
           parameters:
            struct sctp_paddrparams {
               sctp_assoc_t        spp_assoc_id;
               struct sockaddr_storage spp_address;
               uint32_t          spp_hbinterval;
               uint16_t          spp_pathmaxrxt;
            };
             spp_assoc_id   - (UDP style socket) This is filled in the application, and identifies the
                              association for this query.
             spp_address - This specifies which address is of interest.
             spp_hbinterval - This contains the value of the heartbeat interval, in milliseconds. A
                              value of 0, when modifying the parameter, specifies that the heartbeat
                              on this address should be disabled. A value of UINT32_MAX
                              (4294967295), when modifying the parameter, specifies that a
                              heartbeat should be sent immediately to the peer address, and the
                              current interval should remain unchanged.
              spp_pathmaxrxt - This contains the maximum number of retransmissions before this
                              address shall be considered unreachable.
           Applications that wish to use the sendto() system call may wish to specify a default set of
           parameters that would normally be supplied through the inclusion of ancillary data. This
           socket option allows such an application to set the default sctp_sndrcvinfo structure. The
           application that wishes to use this socket option simply passes in to this call the
           sctp_sndrcvinfo structure defined in Section 2.5.2.2) The input parameters accepted by this
           call include sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, sinfo_timetolive.
            struct sctp_sndrcvinfo {
               uint16_t sinfo_stream;
               uint16_t sinfo_ssn;
               uint16_t sinfo_flags;
               uint32_t sinfo_ppid;
               uint32_t sinfo_context;
               uint32_t sinfo_timetolive;
               uint32_t sinfo_tsn;
               uint32_t sinfo_cumtsn;
               sctp_assoc_t sinfo_assoc_id;
            };
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
           For sendmsg() this value holds the stream number that the application wishes to send this
           message to. If a sender specifies an invalid stream number an error indication is returned
           and the call fails.
           This value in sendmsg() is an opaque unsigned value that is passed to the remote end in
           each user message. Please note that byte order issues are NOT accounted for and this
           information is passed opaquely by the SCTP stack from one end to the other.
           This value is an opaque 32 bit context datum that is used in the sendmsg() function. This
           value is passed back to the upper layer if a error occurs on the send of a message and is
           retrieved with each undelivered message (Note: if a endpoint has done multiple sends, all
           of which fail, multiple different sinfo_context values will be returned. One with each user
           data message).
           This field may contain any of the following flags and is composed of a bitwise OR of these
           values.
              sendmsg() flags:
               MSG_ADDR_OVER - This flag, in the UDP model, requests the SCTP stack to
                                override the primary destination address with the address found
                                with the sendto/sendmsg call.
                MSG_EOF         - Setting this flag invokes the SCTP graceful shutdown procedures on
                                        the specified association. Graceful shutdown assures that all
                                        data enqueued by both endpoints is successfully transmitted
                                        before closing the association (UDP-style only).
           For the sending side, this field contains the message time to live in milliseconds. The
           sending side will expire the message within the specified time period if the message as not
           been sent to the peer within this time period. This value will override any default value set
           using any socket option. Also note that the value of 0 is special in that it indicates no
           timeout should occur on this message.
                                                      DOCUMENTTYPE                              50 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                      TypeDateHere
            The association handle field, sinfo_assoc_id, holds the identifier for the association
            announced in the SCTP_COMM_UP notification. All notifications for a given association
            have the same identifier. Ignored for TCP-style sockets.
            The user must provide the sinfo_assoc_id field in to this call if the caller is using the UDP
            model.
            This socket option is used to specify various notifications and ancillary data the user wishes
            to receive.
             struct sctp_event_subscribe{
                u_int8_t sctp_data_io_event;
                u_int8_t sctp_association_event;
                u_int8_t sctp_address_event;
                u_int8_t sctp_send_failure_event;
                u_int8_t sctp_peer_error_event;
                u_int8_t sctp_shutdown_event;
                u_int8_t sctp_partial_delivery_event;
                u_int8_t sctp_adaption_layer_event;
             };
Please see Section 2.7.3 for a full description of this option and its usage.
             struct sctp_status {
                sctp_assoc_t sstat_assoc_id;
                int32_t      sstat_state;
                uint32_t      sstat_rwnd;
                uint16_t      sstat_unackdata;
                uint16_t      sstat_penddata;
                uint16_t      sstat_instrms;
                                                    DOCUMENTTYPE                              51 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
                 uint16_t     sstat_outstrms;
                 uint32_t     sstat_fragmentation_point;
                 struct sctp_paddrinfo sstat_primary;
            };
sstat_state - This contains the association's current state one of the following values:
                                          SCTP_CLOSED
                                          SCTP_BOUND
                                          SCTP_LISTEN
                                          SCTP_COOKIE_WAIT
                                          SCTP_COOKIE_ECHOED
                                          SCTP_ESTABLISHED
                                          SCTP_SHUTDOWN_PENDING
                                          SCTP_SHUTDOWN_SENT
                                          SCTP_SHUTDOWN_RECEIVED
                                          SCTP_SHUTDOWN_ACK_SENT
             sstat_rwnd - This contains the association peer's current receiver window size.
             sstat_unackdata - This is the number of unacked data chunks.
             sstat_penddata - This is the number of data chunks pending receipt.
             sstat_primary - This is information on the current primary peer address.
             sstat_assoc_id - (UDP style socket) This holds the an identifier for the association. All
                              notifications for a given association have the same association
                              identifier.
sstat_instrms - The number of streams that the peer will be using inbound.
sstat_outstrms - The number of streams that the endpoint is allowed to use outbound.
           To access these status values, the application calls getsockopt() with the option name
           SCTP_STATUS. The sstat_assoc_id parameter is ignored for TCP style socket.
            struct sctp_paddrinfo {
               sctp_assoc_t spinfo_assoc_id;
               struct sockaddr_storage spinfo_address;
               int32_t     spinfo_state;
               uint32_t     spinfo_cwnd;
               uint32_t     spinfo_srtt;
               uint32_t     spinfo_rto;
               uint32_t     spinfo_mtu;
            };
                                                    DOCUMENTTYPE                             52 (52)
TypeUnitOrDepartmentHere
TypeYourNameHere                                    TypeDateHere
               spinfo_address - This is filled in the application, and contains the peer address of
           interest.