SCTP Application Guide

70
DOCUMENTTYPE 1 (70) TypeUnitOrDepartmentHere TypeYourNameHere TypeDateHere SCTP Application Guide Document type: User’s Guide Creator: Zhao Kai Reviewer: Huang Hui Approver: Date approved: 2002-12-6 Function: Version History

Transcript of SCTP Application Guide

Page 1: SCTP Application Guide

DOCUMENTTYPE 1 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

SCTP Application Guide

Document type: User’s GuideCreator: Zhao KaiReviewer: Huang HuiApprover:Date approved: 2002-12-6Function:

Version History

Version Date Handled by Version history

1.0 2002-12-16 Zhao kai Skeleton

1.1 2002-12-16 Zhao kai 3, 4

1.2 2002-12-17 Zhao kai 2.5

1.21. 2002-12-20 Nie Sen 2.2-2.4

Shijinyang/ Moltchanov Vladimir

2.6-2.8

1.3 2002-12-30 WangLan Change 2.3,2.4,2.7 as appendix2.3, 2.4 is newgive explainings and examples in 2.5, 2.6, 2.7complete part 2.8give function table of socket options in 2.9complete part 2.10give an compared integrated examples in 5

1.4 18.8.2004 J Leppänen Added Chapter 6.

Page 2: SCTP Application Guide

DOCUMENTTYPE 2 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

Table of Contents

1. INTRODUCTION.............................................................................................................................41.1 Purpose....................................................................................................................................41.2 Scope.......................................................................................................................................41.3 Glossary...................................................................................................................................4

1.3.1 Abbreviations.....................................................................................................................42. Socket API......................................................................................................................................4

2.1 Objectives.................................................................................................................................42.1.1 Maintain consistency with existing sockets APIs:..............................................................42.1.2 Support a one to many style interface...............................................................................42.1.3 Support a one to one style interface..................................................................................4

2.2 Data Types...............................................................................................................................52.3 How to program........................................................................................................................52.4 Basic socket functions..............................................................................................................6

2.4.1 introduction........................................................................................................................62.4.2 socket address..................................................................................................................62.4.3 byte-order..........................................................................................................................62.4.4 socket operations..............................................................................................................72.4.5 Non-blocking mode.........................................................................................................10

2.5 Header data structures and event data structures.................................................................102.5.1 The msghdr and cmsghdr Structures..............................................................................102.5.2 SCTP msg_control Structures.........................................................................................112.5.3 SCTP Events and Notifications in /include/net/sctp/sctp_user.h.....................................12

2.6 Super socket operations for Both Styles................................................................................142.6.1 send(), recv(), sendto(), recvfrom().................................................................................142.6.2 sendmsg() and recvmsg()...............................................................................................152.6.3 read() and wirte().............................................................................................................162.6.4 getsockname().................................................................................................................162.6.5 setsockopt(), getsockopt()...............................................................................................17

2.7 The function of event and how to use.....................................................................................172.8 Ancillary Data Considerations and Semantics........................................................................19

2.8.1 Multiple Items and Ordering............................................................................................192.8.2 Accessing and Manipulating Ancillary Data....................................................................192.8.3 Control Message Buffer Sizing........................................................................................202.8.4 How to use data structures when programming..............................................................20

2.9 Socket Options.......................................................................................................................202.9.1 table of socket options’ functions....................................................................................21

2.10 New Interfaces....................................................................................................................222.10.1 sctp_bindx().................................................................................................................222.10.2 sctp_peeloff()...............................................................................................................232.10.3 sctp_getpaddrs()..........................................................................................................232.10.4 sctp_freepaddrs().........................................................................................................242.10.5 sctp_getladdrs()...........................................................................................................242.10.6 sctp_freeladdrs()..........................................................................................................252.10.7 sctp_sendmsg()...........................................................................................................252.10.8 sctp_recvmsg()............................................................................................................25

3. Installation Guide..........................................................................................................................263.1 account in isource.nokia.com.................................................................................................263.2 Create the source tree (based on Linux Kernel 2.4.18).........................................................263.3 File list....................................................................................................................................273.4 Compile..................................................................................................................................27

3.4.1 Compile lksctp in kernel..................................................................................................27

Page 3: SCTP Application Guide

DOCUMENTTYPE 3 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

3.4.2 Compile lksctp as a kernel..............................................................................................284. Refference.....................................................................................................................................285. Examples......................................................................................................................................28

5.1 Server.....................................................................................................................................285.2 Client......................................................................................................................................30

6. SCTP in FlexiServer......................................................................................................................356.1 Configuration, Installation and Storage..................................................................................356.2 The SCTP Header..................................................................................................................356.3 The SCTP Library...................................................................................................................356.4 LBSCTP Sockets....................................................................................................................36

APPENDIX A......................................................................................................................................38A.1 UDP-style Interface.....................................................................................................................38

A.1.1 Basic Operation...................................................................................................................38A.1.2 Implicit Association Setup....................................................................................................39A.1.3 Non-blocking mode..............................................................................................................39

A.2 TCP-style Interface.....................................................................................................................39A.2.1 Basic Operation...................................................................................................................39

APPENDIX B........................................................................................................................................43B.1 Read / Write Options..................................................................................................................43

B.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO)..................................................43B.1.2 Association Parameters (SCTP_ASSOCINFO).................................................................43B.1.3 Initialization Parameters (SCTP_INITMSG).......................................................................44B.1.4 SO_LINGER........................................................................................................................45B.1.5 SO_NODELAY....................................................................................................................45B.1.6 SO_RCVBUF.......................................................................................................................46B.1.7 SO_SNDBUF.......................................................................................................................46B.1.8 Automatic close of associations (SCTP_AUTOCLOSE).....................................................46B.1.9 Set Primary Address (SCTP_SET_PRIMARY_ADDR).......................................................46B.1.10 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR).................................46B.1.11 Set Adaption Layer Indicator (SCTP_SET_ADAPTION_LAYER)....................................47B.1.12 Set default message time outs (SCTP_SET_STREAM_TIMEOUTS)...............................47B.1.13 Enable/Disable message fragmentation(SCTP_DISABLE_FRAGMENTS)......................47B.1.14 Peer Address Parameters (SCTP_SET_PEER_ADDR_PARAMS)..................................48B.1.15 Set default send parameters (SET_DEFAULT_SEND_PARAM)......................................48B.1.16 Set notification and ancillary events (SCTP_SET_EVENTS)............................................50

B.2 Read only options.......................................................................................................................50B.2.1 Association Status (SCTP_STATUS)..................................................................................50B.2.2 Peer Address Information (SCTP_GET_PEER_ADDR_INFO)...........................................51

Page 4: SCTP Application Guide

DOCUMENTTYPE 4 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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

SCTP Stream Control Transmission Protocol

LKSCTP Linux Kernel SCTP

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.

There are three basic design objectives:

2.1.1 Maintain consistency with existing sockets APIs:

We define a sockets mapping for SCTP that is consistent with other sockets API protocol mappings (for instance, UDP, TCP, IPv4, and IPv6).

2.1.2 Support a one to many style interface

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.

2.1.3 Support a one to one style interface

This interface supports the same basic semantics as sockets for connection-oriented protocols, such as TCP.

Page 5: SCTP Application Guide

DOCUMENTTYPE 5 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

A mechanism is defined to convert a UDP-style SCTP association into a TCP-style socket.

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.

2.2 Data Types

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.

2.3 How to program

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.

Why files are included:

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.

Page 6: SCTP Application Guide

DOCUMENTTYPE 6 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

2.4 Basic socket functions

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.

2.4.2 socket address

Socket of linux operating system is a universal network programming interface. It support several protocols. Each protocol used different socket address format. In order to keepparameters’ consistency when calling socket functions, linux has defined a common socket

address in <linux/socket.h>.

struct sockaddr{

unsigned short sa_family; /* type of address, AF_**** */char sa_data[14]; /*address */

};

e.g. we use AF_INET and AF_INET6 for TCP/IP protocol cluster.

SCTP/IP uses the address of TCP/IP protocol cluster. It is:

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

there are four libaray functions to provide change or byte-order.#include <netinet/in.h>unsigned short in htons(unsigned short int hostshort);unsigned long in htonl(unsigned long int hostlong);unsigned short in ntohs(unsigned short int hostshort);unsigned long in ntohl(unsigned long int hostlong);

note: (1) h---host; n---network; s---short; l---long;

Page 7: SCTP Application Guide

DOCUMENTTYPE 7 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

(2) when programming, it had better use these functions while not depending on special machines.

2.4.4 socket operations

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()

Style Description Elaberation

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()

Style Description Elaberation

UDP bind(int sd, struct sockaddr *addr, socklen_t addrlen)

TCP bind(int sd, struct sockaddr *addr, socklen_t addrlen)

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.

Page 8: SCTP Application Guide

DOCUMENTTYPE 8 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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()

Style Description Elaberation

UDP listen(int socket, int backlog)

TCP listen(int socket, int backlog)

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()

Style Description Elaberation

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

Function: it belongs to clients action which to apply a connection.

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()

Style Description Elaberation

UDP --- ----

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.

Page 9: SCTP Application Guide

DOCUMENTTYPE 9 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

Difference: It is clear that UDP do not support accept(), while it has similar operation which is named peel off().

close()

Style Description Elaberation

UDP close(int sd) 2.4.1.5

TCP close(int sd) 2.5.1.6

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.

No difference between TCP and UDP.

shutdown()

Style Description Elaberation

UDP ----- ----

TCP shutdown(int socket, int how) 2.4.1.7

Fuction: gracefully shutdown when necessary. It could be called whenever the program want. While close() always be called after finishing of communication.

Difference: only used by TCP style.TCP style in SCTP has some different points with TCP, which are described in appendix A.

getsockname() & getpeername()

Style Description Elaberation

UDP getsockname(int socket, struct sockaddr *address, socklen_t *len);

TCP getpeername(int socket, struct sockaddr *address, socklen_t *len);

getsockname(int socket, struct sockaddr *address, socklen_t *len);

Page 10: SCTP Application Guide

DOCUMENTTYPE 10 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

Difference :getpeername() is TCP only.

2.4.5 Non-blocking mode

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.

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.

2.5 Header data structures and event data structures

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.

2.5.1 The msghdr and cmsghdr Structures

2.5.1.1 struct msghdr in /include/linux/socket.h

struct msghdr {void *msg_name; /* Socket name*/int msg_namelen; /* Length of name*/struct iovec * msg_iov; /* Data blocks*/

Page 11: SCTP Application Guide

DOCUMENTTYPE 11 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

__kernel_size_t msg_iovlen; /* Number of blocks*/void *msg_control; /* Per protocol magic

(eg BSD file descriptor passing) */__kernel_size_t msg_controllen; /* Length of cmsg list */unsigned msg_flags;

};

struct iovec {void iov_base; /* beginning address of buffer. */size_t iov_len; /* the size of the buffer. */

}

2.5.1.2 struct cmsghdr in /include/linux/socket.h

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.

2.5.1.3 struct SCTP_cmsghdr in /include/net/sctp/sctp_user.h

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;};

This structure provides classification of control message header. cmsg_level is IPPROTO_SCTP in SCTP protocol; cmsg_type has two options, one is SCTP_INIT, sctp_cmsg_data_t corresponding to sctp_sctp_initmsg strucure; the other is SCTP_SNDRCV, sctp_cmsg_data_t corresponding to sctp_sndrcvinfo structure. Programmers use it according to situation.

2.5.2 SCTP msg_control Structures

Defined in struct msghdr (2.5.1.1)

2.5.2.1 SCTP Initiation Structure (SCTP_INIT) in /include/net/sctp/sctp_user.h

/ * cmsg_level cmsg_type cmsg_data[] * ------------ ------------ ---------------------- * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg */struct sctp_initmsg { uint16_t sinit_num_ostreams; uint16_t sinit_max_instreams; uint16_t sinit_max_attempts;

Page 12: SCTP Application Guide

DOCUMENTTYPE 12 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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().

2.5.2.2 Header Information Structure (SCTP_SNDRCV) in /include/net/sctp/sctp_user.h

/* cmsg_level cmsg_type cmsg_data[] * ------------ ------------ ---------------------- * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo*/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;

};

This cmsghdr structure specifies SCTP options for sendmsg() and describes SCTP header information about a received message through recvmsg().

2.5.3 SCTP Events and Notifications in /include/net/sctp/sctp_user.h

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;

Page 13: SCTP Application Guide

DOCUMENTTYPE 13 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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;

};

When a destination address on a multi-homed peer encounters a change an interface details enent is sent by this structure.

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.

Page 14: SCTP Application Guide

DOCUMENTTYPE 14 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

2.6 Super socket operations for Both Styles

2.6.1 send(), recv(), sendto(), recvfrom()

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.

The syntax is:

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);

sd - the socket descriptor of an SCTP endpoint.

Page 15: SCTP Application Guide

DOCUMENTTYPE 15 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

msg - the message to be sent. len - the size of the message or the size of buffer. to - one of the peer addresses of the association to be used to send the message. tolen - the size of the address. buf - the buffer to store a received message. from - the buffer to store the peer address used to send the received message. fromlen - the size of the from address flags - (described below).

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.

2.6.2 sendmsg() and recvmsg()

ssize_t sendmsg(int socket, const struct msghdr *message, int flags);

ssize_t recvmsg(int socket, struct msghdr *message, int flags);

socket - the socket descriptor of the endpoint

message - pointer to the msghdr structure which contains a single user message and possibly some ancillary data.

flags - No new flags are defined for SCTP at this level.

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

Page 16: SCTP Application Guide

DOCUMENTTYPE 16 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

programming, msg_name and msg_namelen record the address of peer. In fact, msg_name is a pointer which point at a variable of struct sockaddr, msg_namelen is the length of the address. Recvmsg() store the address of receiver in these two fields. The following is an example:

struct msghdr hdr;struct sockaddr_in addr;……addr.sin_family = AF_INET;……hdr.msg_name = (struct sockaddr *)&addr;hdr.msg_namelen = sizeof(addr);……sendmsg(sockfd, &hdr, 0);

2.6.3 read() and wirte()

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()

Applications use getsockname() to retrieve the locally-bound socket address of the specified socket. This is especially useful if the caller let SCTP chose a local port. This call is for where the endpoint is not multi-homed. It does not work well with multi-homed sockets. See Section 8.5 for a multi-homed version of the call.

The syntax is:

int getsockname(int socket, struct sockaddr *address, socklen_t *len);

sd - the socket descriptor to be queried.

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.

Page 17: SCTP Application Guide

DOCUMENTTYPE 17 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

2.6.5 setsockopt(), getsockopt()

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.

The syntax is:

ret = getsockopt(int sd, int level, int optname, void *optval, size_t *optlen); ret = setsockopt(int sd, int level, int optname, const void *optval, size_t optlen);

sd - the socket descript. level - set to SOL_SCTP for all SCTP options. optname - the option name. optval - the buffer to store the value of the option. optlen - the size of the buffer (or the length of the option returned).

2.7 The function of event and how to use

Applications can receive per-message ancillary information and notifications of certain SCTP events with recvmsg().

The following optional information is available to the application:

1. SCTP_SNDRCV (sctp_data_io_event): Per-message information (i.e.stream number, TSN, SSN, etc. described in Section 2.5.2.2).

2. SCTP_ASSOC_CHANGE (sctp_association_event): (described in Section 2.5.3.1)

3. SCTP_PEER_ADDR_CHANGE (sctp_address_event): (described in Section 2.5.3.2)

4. SCTP_SEND_FAILED (sctp_send_failure_event): (described in Section 2.5.3.4)

5. SCTP_REMOTE_ERROR (sctp_peer_error_event): (described in Section 2.5.3.3)

6. SCTP_SHUTDOWN_EVENT (sctp_shtudown_event): (described in Section2.5.3.5)

7. SCTP_PARTIAL_DELIVERY_EVENT (sctp_partial_delivery_event):

(described in Section 2.5.3.7)

8. SCTP_ADAPTION_INDICATION (sctp_adaption_layer_event):

(described in section 2.3.5.6).

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;

Page 18: SCTP Application Guide

DOCUMENTTYPE 18 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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_data_io_event - Setting this flag to 1 will cause the reception of SCTP_SNDRCV information on a per message basis. The application will need to use the recvmsg() interface so that it can receive the event information contained in the msg_control field. Setting the flag to 0 will disable reception of the message control information.

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_partial_delivery_event - Setting this flag to 1 will enable the reception of partial delivery notifications. Setting the flag to 0 will disable partial delivery 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.

The following is an example.

struct sctp_event_subscribe event;

memset(&event,0,sizeof(event));

event.sctp_data_io_event = 1;

setsockopt (fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event));

……

error = recvmsg(fd, &inmessage, MSG_WAITALL);

/* this will receive a notification. */

test_check_message(&inmessage, CMSG_SPACE(sizeof(struce sctp_sndrcvinfo)),

SCTP_SNDRCV);

……

Page 19: SCTP Application Guide

DOCUMENTTYPE 19 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

note: function test_check_message() will be included in another file which could be written like the following.

inttest_check_message(struct msghdr *msg, int controllen,

sctp_cmsg_t event){

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.

2.8 Ancillary Data Considerations and Semantics

Programming with ancillary socket data contains some subtleties and pitfalls, which are discussed below.

2.8.1 Multiple Items and Ordering

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.

2.8.2 Accessing and Manipulating Ancillary Data

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

Page 20: SCTP Application Guide

DOCUMENTTYPE 20 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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:

struct msghdr msg; /* fill in msg */ struct cmsghdr *cmsgptr; /* call recvmsg() */ for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { u_char *ptr; ptr = CMSG_DATA(cmsgptr); /* process data pointed to by ptr */ }

}

2.8.3 Control Message Buffer Sizing

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.

2.8.4 How to use data structures when programming

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.

2.9 Socket Options

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)).

Page 21: SCTP Application Guide

DOCUMENTTYPE 21 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

2.9.1 table of socket options’ functions

Option event Corresponding structure

Option function

SCTP_RTOINFO sctp_rtoinfoModifiy and examine

retransmission timeout parameters

SCTP_ASSOCINFO sctp_associnfoModify and examine

association and endpoint parameters

SCTP_INITMSG sctp_initmsg Modify and examine initialization parameters

SO_LINGER(TCP only) Linger Perform SCTP ABORT primitive

SCTP_NODELAY(no corresponding structure only a

parameter)

Turn on/off any nagle-like algorithm

SO_RCVBUF(no corresponding structure only a

parameter)Sets receive buffer size

SO_SNDBUF(no corresponding structure only a

parameter)Sets send buffer size

SCTP_AUTOCLOSE(UDP only)(no corresponding structure only a

parameter)

Perform wether the association could auto

close.

SCTP_SET_PEER_PRIMARY Sctp_setpeerprimRequests that the peer mark the enclosed address as the association primary.

SCTP_PRIMARY_ADDR sctp_setprim

Requests that the local SCTP stack use the enclosed

peer address as the association primary.

SCTP_ADAPTION_LAYER sctp_setadaption

Requests that the local endpoint set the specified

Adaption Layer Indication parameter for all future INIT and INIT-

ACK exchanges.

SCTP_DISABLE_FRAGMENTS(no corresponding structure only a

parameter)

Turn on/off fragments of a message

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

Page 22: SCTP Application Guide

DOCUMENTTYPE 22 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

retransmissions

SCTP_DEFAULT_SEND_PARAM sctp_sndrcvinfo specify a default set of parameters

SCTP_EVENTSEach event

correspond a data structure

specify various notifications and

ancillary data the user wishes to receive.

SCTP_I_WANT_MAPPED_V4_ADDR(no corresponding structure only a

parameter)

Turn on/off whether v4 address can be mapped v6

address

SCTP_MAXSEG(no corresponding structure only a

parameter)

specifies the maximum size to put in any outgoing SCTP DATA chunk.

SCTP_STATUS(read only) sctp_status etrieve current status information

SCTP_GET_PEER_ADDR_INFO sctp_paddrinforetrieve information about a specific peer address of an association

2.10 New Interfaces

2.10.1 sctp_bindx()

The syntax of sctp_bindx() is,

int sctp_bindx(int sd, struct sockaddr_storage *addrs, int addrcnt, int flags);

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.

A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see Section 2.3.1.2 for this usage.

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

Page 23: SCTP Application Guide

DOCUMENTTYPE 23 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the association, and SCTP_BINDX_REM_ADDR directs SCTP to remove the given addresses from the association. The two flags are mutually exclusive; if both are given, sctp_bindx() will fail with EINVAL. A caller may not remove all addresses from an association; sctp_bindx() will reject such an attempt with EINVAL.

An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate additional addresses with an endpoint after calling bind(). Or use sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening socket is associated with so that no new association accepted will be associated with those addresses. If the endpoint supports dynamic address a SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause a endpoint to send the appropriate message to the peer to change the peers address lists.

This interface is implemented as a system call.

2.10.2 sctp_peeloff()

After an association is established on a UDP-style socket, the application may wish to branch off the association into a separate socket/file descriptor.

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 syntax is:

new_sd = sctp_peeloff(int sd, sctp_assoc_t *assoc_id);

the new socket descriptor representing the branched-off association.

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).

This interface is implemented as a system call.

2.10.3 sctp_getpaddrs()

sctp_getpaddrs() returns all peer addresses in an association. The syntax is,

int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr_storage **addrs);

Page 24: SCTP Application Guide

DOCUMENTTYPE 24 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

On success, sctp_getpaddrs() returns the number of peer addresses in the association. If there is no association on this socket, sctp_getpaddrs() returns 0, and the value of *addrs is undefined. If an error occurs, sctp_getpaddrs() returns -1, and the value of *addrs is undefined.

This interface is implemented as a library function.

2.10.4 sctp_freepaddrs()

sctp_freepaddrs() frees all resources allocated bysctp_getpaddrs(). Its syntax is,

void sctp_freepaddrs(struct sockaddr_storage *addrs);

addrs is the array of peer addresses returned by sctp_getpaddrs().

This interface is implemented as a library function.

2.10.5 sctp_getladdrs()

sctp_getladdrs() returns all locally bound address on a socket. The syntax is,

int sctp_getladdrs(int sock, sctp_assoc_t id, struct sockaddr_storage **ss);

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.

This interface is implemented as a library function.

Page 25: SCTP Application Guide

DOCUMENTTYPE 25 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

2.10.6 sctp_freeladdrs()

sctp_freeladdrs() frees all resources allocated by sctp_getladdrs(). Its syntax is,

void sctp_freeladdrs(struct sockaddr_storage *addrs);

addrs is the array of peer addresses returned by sctp_getladdrs().

2.10.7 sctp_sendmsg()

sctp_sendmsg(). Its syntax is,

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)

s - is the socket descriptor msg - is the message to be sent. len - is the length of the message. to - is the destination address of the message. tolen - is the length of the destination address. ppid - is the same as sinfo_ppid flags - is the same as sinfo_flags stream_no - is the same as sinfo_stream timetolive - is the same as sinfo_timetolive context - is the same as sinfo_context

2.10.8 sctp_recvmsg()

sctp_recvmsg(). Its syntax is,

ssize_t sctp_recvmsg(int s, void *msg, size_t *len, struct sockaddr *from, socklen_t *fromlen struct sctp_sndrcvinfo *sinfo int *msg_flags)

s - is the socket descriptor msg - is a message buffer to be filled.

Page 26: SCTP Application Guide

DOCUMENTTYPE 26 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

len - is the length of the message buffer. from - is a pointer to a address to be filled with the sender of this messages address. fromlen - is the from length. sinfo - A pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the message. msg_flags - A pointer to a integer to be filled with any message flags (e.g. MSG_NOTIFICATION).

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.csctpulib.h

3. INSTALLATION GUIDE

3.1 account in isource.nokia.com

Reference http://www.sourceforge.net/

Create a account for yourself in http://isource.nokia.com/ ,

Give the userid to project manager and add you to noklksctp developer list.

3.2 Create the source tree (based on Linux Kernel 2.4.18)

$ tar xvfz noklksctp.tgz

$ cvs [email protected]:/isource/cvsroot/noklksctp co noklksctp [email protected]'s password: cvs server: Updating noklksctpU noklksctp/CHANGEScvs server: Updating noklksctp/docscvs server: Updating noklksctp/docs/withdrawncvs server: Updating noklksctp/sctp_cvscvs server: Updating noklksctp/sctp_cvs/includecvs server: Updating noklksctp/sctp_cvs/include/linuxcvs server: Updating noklksctp/sctp_cvs/include/netcvs server: Updating noklksctp/sctp_cvs/include/net/sctp……

$ cd noklksctp

$ mkdir linux_sctp

$ cd tools

$ ./mklinux_sctp.sh

Page 27: SCTP Application Guide

DOCUMENTTYPE 27 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

$ ./updatelinux_sctp.sh

3.3 File list

COPYING If you haven't seen this, you probably want to startwith some other program...

README README file. Read this before developing.ANNOUNCEMENT The original announcement of the Developers' Release.BUGS An empty file :-). These are bugs not documented in

the code itself.CHANGES What has changed since the last release?STORIES This is the current set of XP stories we've identified.

sctp_cvs/ This directory hierarchy contains the bulk of our code including the modified files from the stock linux kernel source tree.

sctp_cvs/include/net/sctp/ All the SCTP-specific headers. sctp_cvs/net/sctp All the SCTP-specific source files.

docs/ All the relevant Internet Drafts and RFC's.docs/states.txt This is a detailed state table for SCTP. It makes a

pretty good index for RFC2960 too...test/ Find the functional tests, the unit tests, and the

user space test frame here. Use the Makefile in thisdirectory to run all the automated tests.

test/linux/include This include heirarchy includes special versions ofkernel include files needed by the user-space testframe.

test/libc/include This include hierarchy contains header files needed by the user-space SCTP test programs.

tools/mklinux_sctp.sh This script creates linux_sctp directory formed by merging stock 2.4.18 kernel from linux directoryand the SCTP specific files from sctp_cvs directory.

tools/updatesctp_cvs.sh This script pulls the modified SCTP specific files from linux_sctp and updates the corresponding files in sctp_cvs.

tools/updatelinux_sctp.sh This script pushes the modified SCTP specific files from sctp_cvs to linux_sctp.

tools/mklinks.sh This script creates links from linux into the linux_sctpdirectory and is called by the above mklinux_sctp.sh.

3.4 Compile

3.4.1 Compile lksctp in kernel

$ cd test;make chicken;cd ../linux_sctp $ make xconfig

Code Maturity->Development->Yes,Networking->IP: Enable SCTP->Yes.

make depmake bzImage; su -cp arch/i386/boot/bzImage /boot/vmlinuz-sctpvi /etc/grub.conf

Page 28: SCTP Application Guide

DOCUMENTTYPE 28 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

title Red Hat Linux (sctp)root (hd0,0)

kernel /boot/vmlinuz-sctp ro root=/dev/hda1reboot

3.4.2 Compile lksctp as a kernel

cd linux_sctpmake xconfig

code materity -> yesNetworking -> IPv6 -> ModuleNetworking -> SCTP -> Module

make depmake bzImage; su -cp arch/i386/boot/bzImage /boot/vmlinuz-sctpvi /etc/grub.conf

title Red Hat Linux (sctp)root (hd0,0)

kernel /boot/vmlinuz-sctp ro root=/dev/hda1rebootmake modules; make modules_installinsmod ipv6insmod 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>

intmain(void){

Page 29: SCTP Application Guide

DOCUMENTTYPE 29 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

int sk;int pf_class;sockaddr_storage_t loopSer;

int newsk;struct sockaddr newAddr;

int len, notAccepted;int error = 0;

#if TEST_V6pf_class = PF_INET6;loopSer.v6.sin_family = AF_INET6;

loopSer.v6.sin_port = htons(S_PORT); inet_aton(SERVER, &loopSer.v6.sin_addr);#else

pf_class = PF_INET;loopSer.v4.sin_family = AF_INET;loopSer.v4.sin_port = htons(S_PORT);inet_aton(SERVER, &loopSer.v4.sin_addr);

#endif

sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);if (sk == -1) {

printf("Can not creat a socket!\n");exit(1);

}

error = bind(sk, (struct sockaddr *)&loopSer.sa, sizeof(loopSer)); if (0 != error) { printf("\n\n\t\tFailure: %s.\n\n\n", sys_errlist[errno]); exit(1); }

error = listen(sk, 1);if (0 != error) {

printf("\n\n\t\tFailure: %s.\n\n\n", sys_errlist[errno]); exit(1);

}

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)) {

Page 30: SCTP Application Guide

DOCUMENTTYPE 30 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

printf("Can not close connections ...\n");return -1;

}else{printf("Socket is closed.\n");

}

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>

intmain(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_V6pf_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

sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);

Page 31: SCTP Application Guide

DOCUMENTTYPE 31 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

if (sk == -1) { printf("Can not creat a socket\n"); exit(-1); }

error = bind(sk, (struct sockaddr *)&loopClt.sa, sizeof(loopClt));if (0 != error) {

printf("bind to port %d error\n",3000);exit(-1);

}

printf("Connecting ...\n");

error = connect(sk, &loopSer.sa, sizeof(loopSer));if (error != 0) {

printf("Error connecting!\n");printf("%s\n", sys_errlist[errno]);printf("error is: %d\n",error);exit(1);

}

// test case 11.2 /* TEST #7.1.2: SCTP_ASSOCINFO socket option. */ memset(&asocparam, 0x00, sizeof(struct sctp_assocparams)); asocparam.sasoc_assoc_id = 0; optlen = sizeof(struct sctp_assocparams); error = getsockopt(sk, SOL_SCTP, SCTP_ASSOCINFO, (char *)&asocparam, &optlen); if (error != 0) {

printf("set socket option error!\n");exit(1);

}

/* check the option value.*/ printf("This is default value!\n The endpoint: uint16_t sasoc_asocmaxrxt:%d\n uint16_t sasoc_number_peer_destinations:%d\n uint32_t sasoc_peer_rwnd:%d\n uint32_t sasoc_local_rwnd:%d\n uint32_t sasoc_cookie_life:%d milliseconds\n\n", asocparam.sasoc_asocmaxrxt,/* 10? for ep*/ asocparam.sasoc_number_peer_destinations,/*0? for ep */ asocparam.sasoc_peer_rwnd,/* nothing for ep*/ asocparam.sasoc_local_rwnd,/* DEFAULT_MAX_WINDOW? for ep*/ asocparam.sasoc_cookie_life);/* DEFAULT? for ep */

/* We change the endpoint default AsocRtxInfo parameters.*//* The asocmaxrtx should be less than 5,

*which is Summation of path.max.retrans */ setparam.sasoc_assoc_id = 0;/* ignored */ setparam.sasoc_asocmaxrxt = 4; /* another */ setparam.sasoc_number_peer_destinations = 0;/* ignored*/ setparam.sasoc_peer_rwnd = 0;/* ignored*/ setparam.sasoc_local_rwnd = 0;/* ignored*/ setparam.sasoc_cookie_life = 1000000;/* 1 second */ error = setsockopt(sk, SOL_SCTP, SCTP_ASSOCINFO, (char *)&setparam, sizeof(struct sctp_assocparams));

Page 32: SCTP Application Guide

DOCUMENTTYPE 32 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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");

}

/*== We check the association AsocRtxInfo parameters.*/ memset(&asocparam, 0x00, sizeof(struct sctp_assocparams)); asocparam.sasoc_assoc_id = 0; optlen = sizeof(struct sctp_assocparams); error = getsockopt(sk, SOL_SCTP, SCTP_ASSOCINFO, (char *)&asocparam, &optlen); if (error != 0) {

printf("get socket option error!\n");exit(1);

}

/* check the option value.*/ printf("\n The association 1: uint16_t sasoc_asocmaxrxt:%d\n uint16_t sasoc_number_peer_destinations:%d\n uint32_t sasoc_peer_rwnd:%d\n uint32_t sasoc_local_rwnd:%d\n uint32_t sasoc_cookie_life:%d milliseconds\n\n", asocparam.sasoc_asocmaxrxt,/* 8? */ asocparam.sasoc_number_peer_destinations,/*1? */ asocparam.sasoc_peer_rwnd,/* ? */ asocparam.sasoc_local_rwnd,/* DEFAULT_MAX_WINDOW? */ asocparam.sasoc_cookie_life);/* 1000000? */

printf("Test case 11.2 for SCTP_ASSOCINFO passes!\n\n\n");

/* test case 11.3 *//* draft socket api 7.1.3 */

memset(&reinitmsg, 0x00, sizeof(struct sctp_initmsg)); optlen = sizeof(struct sctp_initmsg); error = getsockopt(sk, SOL_SCTP, SCTP_INITMSG, (char *)&reinitmsg, &optlen); if (error != 0) {

printf("get socket option error!");exit(-1);

}

/* Set socket option*/ memset(&initmsg, 0x00, sizeof(struct sctp_initmsg)); initmsg.sinit_num_ostreams = 9; initmsg.sinit_max_instreams = 9; initmsg.sinit_max_attempts = 4; initmsg.sinit_max_init_timeo = 100; error = setsockopt(sk, SOL_SCTP, SCTP_INITMSG, (char *)&initmsg, sizeof(struct sctp_initmsg)); if (error != 0) {

printf("get socket option error!"); exit(-1);

Page 33: SCTP Application Guide

DOCUMENTTYPE 33 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

}

/* Get the parameters*/ memset(&reinitmsg, 0x00, sizeof(struct sctp_initmsg)); optlen = sizeof(struct sctp_initmsg); error = getsockopt(sk, SOL_SCTP, SCTP_INITMSG, (char *)&reinitmsg, &optlen); if (error != 0) {

printf("get socket option error!"); exit(-1);

}

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.*/

/* TEST case 11.5: SCTP_NODELAY socket option. */ /* Get the parameters of nodelay*/

renodelay = 1; optlen = sizeof(int); error = getsockopt(sk, SOL_SCTP, SCTP_NODELAY, (char *)&renodelay, &optlen); if (error != 0) {

printf("get socket option error.\n");exit(-1);

}

printf("\nSCTP_NODELAY is set to be %d by default.\n",renodelay); /* Set socket option */ nodelay = 1; error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY, (char *)&nodelay, sizeof(int)); if (error != 0) { printf("get socket option error.\n"); exit(-1);

}

/* Get the parameters of nodelay*/ renodelay = 0; optlen = sizeof(int); error = getsockopt(sk, SOL_SCTP, SCTP_NODELAY, (char *)&renodelay, &optlen); if (error != 0) {

printf("set socket option error.\n"); exit(-1);

}

printf("SCTP_NODELAY is set to be %d now.\n",renodelay);

Page 34: SCTP Application Guide

DOCUMENTTYPE 34 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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"); }

/* TEST case 11.7: SO_SNDBUF socket option. ---*//* test draft socket api 7.1.6 */

resbuf = 0; optlen = sizeof(uint32_t); error = getsockopt(sk, SOL_SCTP, SO_SNDBUF, (char *)&resbuf, &optlen); sbuf = resbuf * 2; error = setsockopt(sk, SOL_SCTP, SO_SNDBUF, (char *)&sbuf, sizeof(uint32_t));

if (error != 0) { printf("set socket option Fail.\n"); exit(-1); } resbuf = 0; optlen = sizeof(uint32_t); /* Get the skn's rcvbuf and check */ error = getsockopt(sk, SOL_SCTP, SO_SNDBUF, (char *)&resbuf, &optlen);

if (error != 0) {printf("get socket option Fail.\n");

exit(-1);}

if (resbuf != sbuf){ printf("\n\n\t\tSO_SNDBUF Fail.\n\n"); exit(-1); }else{ printf("SO_SNDBUF is %d!\n",sbuf);

printf("Test case 11.6 passes!\n\n");}

if (0 != close(sk)) {printf("Error closing ...\n");return -1;

}

return 0;

}

Page 35: SCTP Application Guide

DOCUMENTTYPE 35 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

6. SCTP IN FLEXISERVER

6.1 Configuration, Installation and Storage

There are no user or operator configurable parameters in SCTP. The implementation is an integral part of the FlexiOS kernel and it is statically linked in the kernel. The source code is part of the kernel source code and resides in net/sctp/ directory in the kernel source tree. If you're running FlexiOS, you have SCTP support.

6.2 The SCTP Header

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

6.3 The SCTP Library

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,

Page 36: SCTP Application Guide

DOCUMENTTYPE 36 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

struct sctp_sndrcvinfo *sinfo, int *msg_flags);

int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr_storage **addrs);int sctp_freepaddrs(struct sockaddr_storage *addrs);int sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr_storage **addrs);int sctp_freeladdrs(struct sockaddr_storage *addrs);

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.aAPPLIBS = -L$(DIR_SS_LIBSS7STACK)/sctp/build -lsctp

6.4 LBSCTP Sockets

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 */

An LBSCTP socket is created with the socket() call, using IPPROTO_LBSCTP:

fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_LBSCTP)

Page 37: SCTP Application Guide

DOCUMENTTYPE 37 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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;

Fill the address structure:

address.mac_addr.sa_family = AF_LBHWADDR;memcpy(&address.mac_addr.sa_data, mac_addr, 6); /* 6 bytes */address.ip_addr.sin_family = AF_INET;memcpy(&address.ip_addr.sin_addr, ip_addr, sizeof(*ip_addr));address.ip_addr.sin_port = port;

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.

Page 38: SCTP Application Guide

DOCUMENTTYPE 38 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

APPENDIX A

A.1 UDP-style Interface

The UDP-style interface has the following characteristics:A) Outbound association setup is implicit.B) Messages are delivered in complete messages (with one notable exception).C) There is a 1 to MANY relationship between socket and association.

A.1.1 Basic Operation

A.1.1.1 socket() - UDP Style Syntax

sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); or,sd = socket(PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);

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.

A.1.1.2 bind() - UDP Style Syntax

ret = bind(int sd, struct sockaddr *addr, int addrlen);

sd - the socket descriptor returned by socket().addr - the address structure (struct sockaddr_in or struct sockaddr_in6 [RFC 2553]),addrlen - the size of the address structure.

A.1.1.3 listen() - UDP Style Syntax

int listen(int socket, int backlog);

socket - the socket descriptor of the endpoint.

backlog - ignored for UDP-style sockets.

A.1.1.4 sendmsg() and recvmsg() - UDP Style Syntax

ssize_t sendmsg(int socket, const struct msghdr *message, int flag s);

ssize_t recvmsg(int socket, struct msghdr *message, int flags);

socket - the socket descriptor of the endpoint

message - pointer to the msghdr structure which contains a single user message and possibly some ancillary data.

flags - No new flags are defined for SCTP at this level.

A.1.1.5 close() - UDP Style Syntax

ret = close(int sd);

Page 39: SCTP Application Guide

DOCUMENTTYPE 39 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

sd - the socket descriptor of the associations to be closed.

A.1.1.6 connect() - UDP Style Syntax

ret = connect(int sd, const struct sockaddr *nam, int len);

sd - the socket descriptor to have a new association added to.

nam - the address structure (either struct sockaddr_in or struct sockaddr_in6 defined in [RFC 2553]).

len - the size of the address.

A.1.2 Implicit Association Setup

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.

A.1.3 Non-blocking mode

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.

A.2 TCP-style Interface

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.

A.2.1 Basic Operation

A.2.1.1 socket() - TCP Style Syntax

int socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); or,int socket(PF_INET6, SOCK_STREAM, IPPROTO_SCTP);

Page 40: SCTP Application Guide

DOCUMENTTYPE 40 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

A.2.1.2 bind() - TCP Style Syntax

int bind(int sd, struct sockaddr *addr, int addrlen);

sd - the socket descriptor returned by socket() call.addr - the address structure (either struct sockaddr_in or struct sockaddr_in6 defined in [RFC 2553]).addrlen - the size of the address structure.

A.2.1.3 listen() - TCP Style Syntax

int listen(int sd, int backlog);

sd - the socket descriptor of the SCTP endpoint.

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.

A.2.1.4 accept() - TCP Style Syntax

new_sd = accept(int sd, struct sockaddr *addr, socklen_t *addrlen);

new_sd - the socket descriptor for the newly formed association.sd - the listening socket descriptor.addr - on return, will contain the primary address of the peer endpoint.addrlen - on return, will contain the size of addr.

A.2.1.5 connect() - TCP Style Syntax

int connect(int sd, const struct sockaddr *addr, int addrlen);

sd - the socket descriptor of the endpoint.addr - the peer's address.addrlen - the size of the address.

A.2.1.6 close() - TCP Style Syntax

int close(int sd);

sd - the socket descriptor of the association to be closed.

A.2.1.7 shutdown() - TCP Style Syntax

int shutdown(int socket, int how);

sd - the socket descriptor of the association to be closed.how - Specifies the type of shutdown. The values are as follows:

SHUT_RD

Page 41: SCTP Application Guide

DOCUMENTTYPE 41 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

Disables further receive operations. No SCTP protocol action is taken.

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 calls the shutdown(sd, SHUT_WR): it still could receive messages or datas from the peer until it receives shutdown ack signal, but it could not send any messages or datas.

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.

A.2.1.8 sendmsg() and recvmsg() - TCP Style Syntax

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.

2) An application must use close() to gracefully shutdown an association, or use SO_LINGER option with close() to abort an association(2.7.1.4). It must not use the

Page 42: SCTP Application Guide

DOCUMENTTYPE 42 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

MSG_ABORT or MSG_EOF flag in sendmsg(). The system returns an error if an application tries to do so.

A.2.1.9 getpeername()

int getpeername(int socket, struct sockaddr *address, socklen_t *len);

sd - the socket descriptor to be queried.

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.

Page 43: SCTP Application Guide

DOCUMENTTYPE 43 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

APPENDIX B

B.1 Read / Write Options

B.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO)

The protocol parameters used to initialize and bound retransmission timeout (RTO) are tunable. The peer address parameter is ignored for TCP style socket.

The following structure is used to access and modify these parameters:

struct sctp_rtoinfo { sctp_assoc_t srto_assoc_id; uint32_t srto_initial; uint32_t srto_max; uint32_t srto_min; };

srto_initial - This contains the initial RTO value.srto_max and srto_min - These contain the maximum and minimum bounds for all

RTOs.srto_assoc_id - (UDP style socket) This is filled in the application, and identifies the

association for this query. If this parameter is missing (on a UDP style socket), then the change effects the entire endpoint.

All parameters are time values, in milliseconds. A value of 0, when modifying the parameters, indicates that the current value should not be changed.

To access or modify these parameters, the application should call getsockopt or setsockopt() respectively with the option name SCTP_RTOINFO.

B.1.2 Association Parameters (SCTP_ASSOCINFO)

This option is used to both examine and set various association and endpoint parameters. The peer address parameter is ignored for TCP style socket.

The following structure is used to access and modify this parameters:

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.

sasoc_number_peer_destinations - This is the number of destination address that the peer considers valid.

sasoc_peer_rwnd - This holds the current value of the peers rwnd (reported in the last SACK) minus any outstanding data (i.e. data inflight).

Page 44: SCTP Application Guide

DOCUMENTTYPE 44 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

The values of the sasoc_asocmaxrxt and sasoc_cookie_life may be set on either an endpoint or association basis. The rwnd and destination counts (sasoc_number_peer_destinations, sasoc_peer_rwnd,sasoc_local_rwnd) are NOT settable and any value placed in these is ignored.

To access or modify these parameters, the application should call getsockopt or setsockopt() respectively with the option name

SCTP_ASSOCRTXINFO.

The maximum number of retransmissions before an address is considered unreachable is also tunable, but is address-specific, so it is covered in a separate option. If an application attempts to set the value of the association maximum retransmission parameter to more than the sum of all maximum retransmission parameters, setsockopt() shall return an error.

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.

B.1.3 Initialization Parameters (SCTP_INITMSG)

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;

};

sinit_num_ostreams: 16 bits (unsigned integer)

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.

sinit_max_instreams: 16 bits (unsigned integer)

Page 45: SCTP Application Guide

DOCUMENTTYPE 45 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

sinit_max_attempts: 16 bits (unsigned integer)

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.

sinit_max_init_timeo: 16 bits (unsigned integer)

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).

Setting initialization parameters is effective only on an unconnected socket (for UDP-style sockets only future associations are effected by the change). With TCP-style sockets, this option is inherited by sockets derived from a listener socket.

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.

Expects an integer boolean flag.

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.

Page 46: SCTP Application Guide

DOCUMENTTYPE 46 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

The option name argument to setsockopt() and getsockopt() is SO_NODELAY.

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.

B.1.8 Automatic close of associations (SCTP_AUTOCLOSE)

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.

B.1.9 Set Primary Address (SCTP_SET_PRIMARY_ADDR)

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.

This functionality is optional, within the extension. In our implementation, it is a set-only option, the getsockopt operation is not supported. The option name argument to setsockopt() is SCTP_SET_PRIMARY_ADDR.

B.1.10 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)

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 {

Page 47: SCTP Application Guide

DOCUMENTTYPE 47 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

sctp_assoc_t sspp_assoc_id; struct sockaddr_storage sspp_addr; };

sspp_addr The address to set as primarysspp_assoc_id (UDP style socket) This is filled in by the application, and identifies

the association for this request.

B.1.11 Set Adaption Layer Indicator (SCTP_SET_ADAPTION_LAYER)

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.

B.1.12 Set default message time outs (SCTP_SET_STREAM_TIMEOUTS)

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.

The option name argument to setsockopt() and getsockopt() is SCTP_SET_STREAM_TIMEOUTS.

B.1.13 Enable/Disable message fragmentation(SCTP_DISABLE_FRAGMENTS)

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.

Page 48: SCTP Application Guide

DOCUMENTTYPE 48 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

B.1.14 Peer Address Parameters (SCTP_SET_PEER_ADDR_PARAMS)

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.

B.1.15 Set default send parameters (SET_DEFAULT_SEND_PARAM)

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; };

sinfo_stream: 16 bits (unsigned integer)

Page 49: SCTP Application Guide

DOCUMENTTYPE 49 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

sinfo_ssn: 16 bits (unsigned integer)

This parameter is ignored.

sinfo_ppid: 32 bits (unsigned integer)

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.

sinfo_context: 32 bits (unsigned integer)

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).

sinfo_flags: 16 bits (unsigned integer)

This field may contain any of the following flags and is composed of a bitwise OR of these values. sendmsg() flags:

MSG_UNORDERED - This flag requests the un-ordered delivery of the message. If this flag is clear the datagram is considered an ordered send.

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_ABORT - Setting this flag causes the specified association to abort by sending an ABORT message to the peer (UDP-style only). The ABORT chunk will contain an error cause 'User Initiated Abort' with cause code 12. The cause specific information of this error cause is provided in msg_iov.

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).

sinfo_timetolive: 32 bit (unsigned integer)

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.

Page 50: SCTP Application Guide

DOCUMENTTYPE 50 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

sinfo_tsn: 32 bit (unsigned integer)

This parameter is ignored.

sinfo_cumtsn: 32 bit (unsigned integer)

This parameter is ignored.

sinfo_assoc_id: sizeof (sctp_assoc_t)

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.

B.1.16 Set notification and ancillary events (SCTP_SET_EVENTS)

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.

B.2 Read only options

B.2.1 Association Status (SCTP_STATUS)

Applications can retrieve current status information about an association, including association state, peer receiver window size, number of unacked data chunks, and number of data chunks pending receipt. This information is read-only. The following structure is used to access this information:

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;

Page 51: SCTP Application Guide

DOCUMENTTYPE 51 (52)

TypeUnitOrDepartmentHereTypeYourNameHere 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.

sstat_fragmentation_point - The size at which SCTP fragmentation will occur.

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.

B.2.2 Peer Address Information (SCTP_GET_PEER_ADDR_INFO)

Applications can retrieve information about a specific peer address of an association, including its reachability state, congestion window, and retransmission timer values. This information is read-only. The following structure is used to access this information:

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; };

Page 52: SCTP Application Guide

DOCUMENTTYPE 52 (52)

TypeUnitOrDepartmentHereTypeYourNameHere TypeDateHere

spinfo_address - This is filled in the application, and contains the peer address of interest.

On return from getsockopt():

spinfo_state - This contains the peer addresses's state (either SCTP_ACTIVE or SCTP_INACTIVE).

spinfo_cwnd - This contains the peer addresses's current congestion window. spinfo_srtt - This contains the peer addresses's current smoothed round-trip time

calculation in milliseconds. spinfo_rto - This contains the peer addresses's current retransmission timeout value

in milliseconds. spinfo_mtu - The current P-MTU of this address. spinfo_assoc_id - (UDP style socket) This is filled in the application, and identifies the

association for this query.