One document matched: draft-stewart-sctpsocket-sigtran-00.txt
Network Working Group R. R. Stewart
INTERNET-DRAFT Cisco
Q. Xie
L Yarroll
Motorola
J. Wood
K. Poon
Sun Microsystems
expires in six months July 13,2000
SCTP Sockets Mapping
<draft-stewart-sctpsocket-sigtran-00.txt>
Status of This Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of [RFC2026]. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
Abstract
This document describes a mapping of the Stream Control
Transmission Protocol (SCTP) [SCTP] into a sockets API. The
benefits of this mapping include compatibility for TCP applications,
access to new SCTP features and a consolidate error and event
notification scheme.
1. Introduction
This document describes a mapping of the Stream Control
Transmission Protocol (SCTP) [SCTP] into a sockets API. The
benefits of this mapping include compatibility for TCP applications,
access to new SCTP features and a consolidate error and event
notification scheme.
The sockets API has provided a standard mapping of the Internet Protocol
suite to many operating systems. Both TCP [TCP] and UDP [UDP] have
benefited from this standard representation and access method across many
diverse platforms. SCTP is a new protocol that provides many of the
characteristics of TCP but also try to incorporate semantics more
akin to UDP. This document will attempt to define a methodology to
map the existing sockets API for use with SCTP, providing a base for
access to new features but also a compatibility so that many existing
TCP applications can be migrated to SCTP with few (if any) changes.
There are three basic design goals:
1. Define a sockets mapping for SCTP that is consistent with other
protocol mappings (for instance, UDP, TCP, IPv4, and IPv6) to
the API.
2. The mapping should provide the same semantics as sockets for
connection-oriented protocols, such as TCP, so that existing
applications for these protocols can be ported to use SCTP with
very little effort, and developers familiar with that semantics
can easily adapt to SCTP. At the same time, the mapping should
provide mechanisms to exploit new features of SCTP.
3. Provide new semantics that map more closely to SCTP. These
semantics are similar to the those defined for conntionless
protocols, such as UDP. Note that SCTP is connection-oriented
in nature. It does not support broadcast or multicast
communications, as UDP does.
Goals two and three are not compatible, so this document defines two
modes of mapping. They share some common structures but provide two
different programming models. Section 6 defines structures
common to both modes. Section 4 defines the connectionless
mode. Section 5 defines the connection-oriented mode.
2. Conventions
The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when they
appear in this document, are to be interpreted as described in
RFC 2119 [RFC2119].
3. Data Structures
The primary sockets interface method used by SCTP is the sendmsg(), recvmsg()
system calls. These calls require the following format:
ssize_t recvmsg(int socket, struct msghdr *message,int flags);
ssize_t sendmsg(int socket, struct msghdr *message,int flags);
socket: 32 bits (signed integer)
This is the integer value returned from the socket call that
established this endpoint.
For a defintion of msghdr please refer to [STEVENS]. Scatter/gather
buffers, or I/O vectors (the msg_iov field in the msghdr structure)
are treated as a single SCTP data chunk, rather than multiple chunks,
for both sendmsg and recvmsg.
The flags within the msghdr structure is used to communicate one
of the following:
SYNCHRONOUS - This flag indicates that the application wishes
the call to be blocking. If the association is
not up the function will block until it has been
created.
A_SYNCHRONOUS_IO - This flag indicates that the application
wishes the function call to be non blocking
and return immediately.
3.1 The SCTP_msgcontrol structure
A key element to all SCTP extensions is the ability to specify
various command options on each send or to find out specific
information from each receive. The msg_control structure is
the primary mechanism for this communication and is defined
as in the form of cmsghdrs. Each cmsghdr contains a data
portion (see [STEVENS] appendix A for details of there useage).
The following subsections dictate the allowable structures
that may be passed in a cmsghdr to/from the SCTP protocol
stack.
Note, when processing the SCTP ancillary data structures defined
here it is also possible to receive other ancillary data (e.g.
IPv6 structures). A application should be prepared to handle
other types of data besides that passed by SCTP.
3.1.1 The INIT structure.
The following details the structure used when implicitly starting
a new association with a sendmsg() operation.
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 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)
This value represents the maximum number of 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 will override the value
requested by the user. The default value of 0 indicates to
use the endpoints default value.
sinit_max_attempts: 16 bits (unsigned integer)
This integer is used to specify how many attempts the
SCTP endpoint should make at resending the INIT when
no response is obtained. This value overrides the
system SCTP 'Max.Init.Retransmits' value. The default
value of 0 indicates to use the endpoints default value
normally set to the systems 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 time-out. For the INIT
message this value MAY override this 'RTO.Max'. This value
MUST NOT influence 'RTO.Max' during data transmission and
is only used to bound the initial setup time an application
is willing to wait. A default value of 0 indicates to use
the endpoints default value normally set to the systems
'RTO.Max' value (60 seconds).
3.1.2 the SND_RCV structure.
Whenever a datagram is sent specific options may need
to be specified by the sending application. To do this
the SND_RCV structure is filled appropriately with the
requested characteristics. The structure has the following
format:
struct sctp_sndrcvinfo {
uint32_t sinfo_tsn;
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_delivery_num;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint8_t sinfo_tos;
};
sinfo_tsn:32 bits (unsigned integer)
For the recvmsg() call this value will contain the TSN
number that the remote endpoint placed in the DATA chunk.
For fragmented messages it is implementation dependent
on which TSN number appears in this location. The sendmsg()
call will ignore this parameter.
sinfo_stream: 16 bits (unsigned integer)
For the recvmsg() call this value will contain the
stream number that this message was sent to. For
the sendmsg() call this value will hold the stream
number that the application wishes to send this message
to. If a sender specifies an invalid stream number an
error indication will be returned and the call will fail.
sinfo_ssn: 16 bits (unsigned integer)
For the recvmsg() call this value will contain the stream
sequence number that the remote endpoint placed in the DATA chunk.
For fragmented messages this will be the same number for
all deliveries of the message (if more than one recvmsg() call
is needed to read the message). The sendmsg()
call will ignore this parameter.
sinfo_delivery_num: 16 bits (unsigned integer)
This value holds the delivery number used by the partial delivery
mechanism. In some cases the SCTP endpoint will need to deliver
a large message in pieces. When this occurs, the delivery number
will be incremented with each subsequent delivery. The delivery
number is set to 0 on the first delivery. The sendmsg() call
ignores this field.
sinfo_ppid:32 bits (unsigned integer)
This value in the sendmsg() is a opaque unsigned value that is
passed to the remote end in each user message. In the recvmsg()
call this value is the same information that was passed by the
upper layer in the peer application. 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 information that is
used in the sendmsg() function. This value will be passed
back to the upper layer if a error occurs on the send of
a message and will be retrieved with each unsent 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.
recvmsg() flags:
MORE_DATA - This flag is present if a subsequent delivery
will be following. Subsequent recvmsg() calls will
retrieve further piece(s) of the message.
MSG_EOR - This flag is present in the last piece of
a message.
UNORDERED - This flag is present when the message was
sent with the non-ordered flag.
sendmsg() flags:
UNORDERED - This flag is present to request the un-ordered
delivery of the message. If this flag is not
present the datagram is considered to be an
ordered send.
ABORT - The setting of this flag causes the specified
association to be aborted by sending an ABORT
message to the peer.
SHUTDOWN - The setting of this flag invoke the SCTP graceful
shutdown procedures which will assure that all data
in-queued by both endpoints are successfully transmitted
before closing the association.
TOS: 8 bits (unsigned integer)
This field is available to change th TOS value in
the outbound IP packet. The default value of this
field is 0. Note only 6 bits of this byte are
used, the upper 2 bits are not part of the TOS field
any setting within these upper 2 bits are ignored.
3.2 Events
A SCTP application will need to be able to understand and
process a number of events and errors that happen on
the SCTP stack. These events include networks status
changes, association startups, and undeliverable datagrams.
All of these are essential for the application to process.
When a SCTP application layer does a recvmsg() most often
the message read will be a Data message from a peer
endpoint. However when the SCTP stack wishes to communicate
a event notification to the application it will set msg_flags
in the msghdr to IS_EVENT. The msg_control structure will be
overwritten with a cmsghdr structure that will define what
type of event is being communicated. The data portion of
the msghdr i.e. the msg_iov will contain the information
communicated with the event or error.
3.2.1 The cmsghdr structure
For a definition of the cmsghdr structure and its used
please refer to [STEVENS]. For SCTP the cmsg_level field will
be encoded with IPPROTO_SCTP.
3.2.2 SCTP Notification and Event types
The following table illustrates the SCTP notification
and event types.
Name Description Value
--------- --------------------------- ------
SCTP_DATA_IO_EVENT This indicates a normal User 1
Data message is being sent
and or received. Special
options and directions are
also included in the
SCTP_msgcontrol structure as
defined in 3.
SCTP_ASSOC_CHANGE This indication is passed 2
to indicate that a association
has either been opened or
closed. The data found in the
msg_iov section is detailed in
3.2.2.1.
SCTP_INTF_CHANGE This indication is passed 3
to indicate that a address that
is part of an existing
association has experienced a
change of state (i.e. a failure
or return to service of the
reachability of a endpoint
via a specific transport
address). Please see 3.2.2.2
for data structure details.
SCTP_SEND_FAILED The attached datagram (in the 4
msg_iov area) could not
be sent to the remote endpoint.
This structure includes the
original SCTP_DATA_IO_EVENT
that was used in sending this
message i.e. this structure
uses the SCTP_msgcontrol per
section 3.1.
SCTP_REMOTE_ERROR The attached error message (in the 5
msg_iov area) is a Operational
received from the remote peer.
It includes the complete TLV
sent by the remote endpoint.
See section 3.2.2.3 for the detailed
format.
3.2.2.1 Communication notifications
Communication notifications are used to inform the
ULP that a SCTP association has either begun or ended.
The notification information is passed into the
msg_iov data and has the following format:
struct commNotification{
struct socket_storage primaryAddr;
int state;
int errorCode;
};
primaryAddr: variable based on address length
The primaryAddr field holds one of the remote peers addresses. If the
peer is NOT multi-homed the primaryAddr holds the only address of the
peer. The socket_storage structure is found in [RFC2553].
state: 32 bits (signed integer)
This field holds one of a number of values that communicate
the event that happened to the association. They include:
Event Name Value Description
---------------- ----- ---------------
COMMUNICATION_UP 1 A new association is now ready
and data may be exchanged with this
peer.
COMMUNICATION_LOST 2 The association identified by the
address has failed. The association
is now in the closed state.
SHUTDOWN_COMPLETE 3 The association has gracefully closed.
CANT_START_ASSOC 4 The association failed to setup.
errorCode: 32 bits (signed integer)
If the state was reached due to a error condition
(i.e. COMMUNCIATION_LOST) any relevant error information is available
in this field.
3.2.2.2 Interface details
When a destination address on a multi-homed peer encounters
a change in reachability a Interface details event is
sent. The information carried in the msg_iov will hold
the following structure:
struct intefaceEvent{
struct socket_storage primaryAddr;
struct socket_storage affectedAddr;
int state;
int errorCode;
}
primaryAddr: variable based on address length
The primaryAddr field holds the remote endpoints address that was
announced in the COMMUNICATION_UP notification. The socket_storage
structure is found in [RFC2553].
affectedAddr: variable based on address length
The effectedAddr field holds the remote peers addresses of the
association that is encountering the change of state. The
socket_storage structure is found in [RFC2553].
state: 32 bits (signed integer)
This field holds one of a number of values that communicate
the event that happened to the association. They include:
Event Name Value Description
---------------- ----- ---------------
ADDRESS_AVAILABLE 1 This address is now reachable.
ADDRESS_UNREACHABLE 2 The address specified can no
longer be reached. Any data sent
to this address will be rerouted
to an alternate until this address
is considered reachable.
errorCode: 32 bits (signed integer)
If the state was reached due to any error condition
(i.e. ADDRESS_UNREACHABLE) any relevant error information is available
in this field.
3.2.2.3 SCTP Communication error.
A remote peer may send a Operational Error message to its
peer. This message will indicate a variety of error conditions
on an association. This notification will be accompanied by
the complete SCTP TLV in the msg_iov structure. Please refer
to the SCTP specification [SCTP] section 3.3.10 for a complete
list of possible error formats. In general the messages will
have the format:
struct OperationalError{
unsigned short causeCode;
unsigned short causeLength;
unsigned char causeInfo[];
};
causeCode: 16 bits (unsigned integer)
This value represents one of the Operational Error causes
defined in the SCTP specification.
causeLength: 16 bits (unsigned integer)
This value represents the length including the causeCode,
causeLength and any additional information carried in
causeInfo.
causeInfo: variable
This represents the detailed error information sent by
the remote endpoint.
4. Datagram Interface
The datagram interface to SCTP attempts to emulate UDP
more than it does TCP. It does this in a number of ways:
A) Support of implicit association setup.
B) Messages are delivered in complete messages with
one notable exception.
C) Automatic acceptance of a new associations.
IOCTLs do exist to convert a SCTP endpoint into a TCP compatible
socket.
A typical server in this model uses the following socket calls in
sequence to prepare an endpoint for servicing requests:
socket(), bind()
At this point new association's will be discovered by the server
when a EVENT is reported from the SCTP stack via a recvmsg()
recvmsg(), sendmsg()
It may call sendmsg() to terminate this association, passing
in no user DATA but including the appropriate flag in the
ancillary data.
A typical client uses the following calls in sequence to setup an
association with a server to request services:
socket(), sendmsg(), recvmsg()
It may call sendmsg() to terminate this association, passing
in no user DATA but including the appropriate flag in the
ancillary data.
A server or client may wish to branch an association off to
its own socket. It my do this by calling accept(), specifying
one of the addresses of an exisiting association. accept() will
return a new socket which can then be used with recv()/send()
messgage calls.
4.1.1 socket()
Applications use socket() to create a socket descriptor to represent
a SCTP endpoint. The syntax is
sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
Or
sd = socket(PF_INET6, SOCK_SEQAPCKET, IPPROTO_SCTP);
The first one creates an endpoint which can use only IPv4 addresses.
The second one creates an endpoint which can use both IPv6 and IPv4
mapped addresses.
4.1.2 bind()
Applications use bind() to pass addresses associated with a SCTP
endpoint to the system. Those addresses are the eligible transport
addresses for sending and receiving data the endpoint can use to
present to its peers. The syntax is
ret = bind(int sd, struct sockaddr *addr, int addrlen);
sd is the socket descriptor created by socket(), addr is the address
structure (struct sockaddr_in or struct sockaddr_in6 [RFC 2553]),
and addrlen is the size of the address structure. Caller should use
struct sockaddr_storage described in RFC 2553 to represent addr for
portability reason.
If sd is a IPv4 socket, the address has to be a IPv4 address. If sd
is a IPv6 socket,the address can be a IPv4 or IPv6 address.
Applications can call bind() multiple times to associate multiple
addresses to the endpoint.
If the IPv4 address specified is INADDR_ANY or the IPv6 address
specified is in6addr_any, which is normally used by server
applications, the system will associate the endpoint with all its
interfaces. Note that these wildcard addresses can only be used
one and only one time in bind(). This means that it has to be used
in the first bind() call, and the application cannot call bind() on
that endpoint again.
After calling bind(), the SCTP endpoint will accept all SCTP INIT
requests passing the COMMUNICATION_UP notification to the
endpoint upon reception of a valid associaition (i.e. receipt of
a valid COOKIE ECHO).
4.1.3 sendmsg() and recvmsg()
Applications use sendmsg() and recvmsg() to transmit data to and
receive data from its peer. These calls takes the form of:
ssize_t sendmsg(int socket, const struct msghdr *message,
int flags);
ssize_t recvmsg(int socket, struct msghdr *message,
int flags);
socket - Is the socket descriptor of the message,
message - Is the msghdr structure containing the single
message and any ancillary data.
flags - Is the flags field sent/received with the message.
See section 3 for a description of the valid flag
values.
The sendmsg/recvmsg calls can be used to send and recieve
data. Along with this data the ancillary data field in
the msg_control is allowed to carry the sctp_sndrcvinfo
and/or the sctp_initmsg structures to specify various
options for sending.
When sending the msg_name field is filled in with one of the addresses
of an existing association OR the address of a new association to
setup. Upon reception of data the msg_name field is populated with the
source of the data. Note: if the socket is a high bandwidth
socket that only represents one association (see section 4.3) then
the msg_name field is ignored upon sending data.
For this interface style an application SHOULD use the
sendmsg() call to shutdown an association using the
appropriate flags in the ancillary information.
4.1.4 close()
Applications use close() to close down an association or the
main datagram socket. The syntax is
ret = close(int sd);
sd is the socket descriptor of the association to be closed.
For a high bandwidth socket (see 4.3), this will invoke the normal
SCTP Shutdown primitve. If the user attempts to close() the
initial SCTP datagram socket all associations represented
by the socket initiate the SCTP Shutdown primitive.
This is similar to the SHUTDOWN primitive described in [SCTP] section
10.1. The system will gracefully close down the association.
4.2 Sending and receiving data with implicit association setup
Once all binding is complete the endpoint may begin sending
and receiving data using the sendmsg or recvmsg calls. Any
time a new address (i.e. one that an association is NOT set
up with) is specified in the msg_name field of the msghdr
structure sent in sendmsg() call, an implicit association is
begun with that endpoint. No connect() system call is required.
Upon successful association setup a COMMUNICATION_UP notification will
be dispatched to the socket and thus read by the recvmsg() system
call. Note also that if the implementation supports bundling, the
COOKIE ECHO message will be bundled with the data message sent
to the remote endpoint.
When a new association is began implicitly the SCTP_msgcontrol
structure will be consulted for any special options that the
endpoint should be setup with. The init_parameters field is
used to pass this special information. By default when this
information is not present the default endpoint initialization
parameters will be used. These may be set with respective
ioctl calls or left to the system defaults.
A endpoint may identify messages received from an association based on
the msg_name field received in the recvmsg() call. Other information
such as stream number and stream sequence number are also populated in
the SCTP_msgcontrol structure. Likewise, when sending data messages,
the send_recv_parameters structure can be populated with specific
stream number, TOS, flags, context and protocol Id (sinfo_ppid) values
that will effect each specific send.
Use of other calls for sending and receiving (i.e. sendto/recvfrom)
will assume default parameters for all additional things that
would normally be specified in the ancillary data passed to the
sendmsg/recvmsg call. Use of the send/recv calls is restricted
to high bandwidth associations only (section 4.3).
4.3 High bandwidth association
During the life of an endpoint it may be desirable by a
application that a specific association be branched
out into a separate file descriptor. An application may
wish to have a number of sporadic message senders grouped
under the generic SCTP endpoint socket and specific high
volume data associations placed each under there own
respective file descriptor. To do this a datagram mode
SCTP endpoint MAY use the accept() system call. Please
note the semantics for this are somewhat changed from
the traditional meaning. The following is the signature
of the accept system call:
int accept(int socket, struct sockaddr *who, int *who_len)
socket: 32 bits (signed integer)
This is the main SCTP endpoint socket/file descriptor i.e. the one
initially opened by the socket() system call.
who: pointer
This is the specific address of the association that is desired to
be pulled on to a separate file descriptor. In a traditional TCP
call this would be a out parameter, but for the datagram based
SCTP this is a IN parameter and specifies the association that
is to be accepted into its own socket descriptor.
who_len: pointer
This field holds a integer pointer to the size of the sockaddr
structure carried in the who field. In a traditional TCP call this
would be a out parameter, but for the datagram based SCTP this is a IN
parameter.
4.4 Closing - graceful and abortive.
At some point in communication with a peer the upper layer may wish to
close an association. To do this the sendmsg() call will be used.
The sendmsg() call should be made with NO data and the ABORT or
SHUTDOWN flag set in the sinfo_flags.
4.5 An example session
[ To be filled in later ]
5. Connection oriented model
The goal of this model is to follow as closely as possible the
current practice of using sockets interface for a connection
oriented protocol, such as TCP. Because of this, using certain
socket calls, such as send() and recv(), may restrict the caller to
a subset of features SCTP provides. But with this model, existing
applications using connection oriented protocol can be ported to use
SCTP with very little effort. In order to utilize most SCTP
features, new SCTP socket options, sendmsg() and recvmsg() have to
be used. The following is a simple example to illustrate how this
model works.
A typical server in this model uses the following socket calls in
sequence to prepare an endpoint for servicing requests:
socket(), bind(), listen(), accept()
accept() blocks until a new assocation is setup. It returns with a
new socket descriptor. The server then uses the new socket
descriptor to communicate with the client. It may call the
followiing in a loop until it has processed all requests.
recv(), send()
Then it calls close() to terminate this association.
A typical client uses the following calls in sequence to setup an
association with a server to request services:
socket(), connect()
After connect() succeeds, it may call the following in a loop until
it has sent and received all requests.
send(), recv()
Then it calls close() to terminate this association.
5.1 Socket Interface
This section specifies the SCTP socket interface.
Editors Note: [Should we include return code of these calls in the draft
or should it be in a man page of different OSes? We may want to map
special error code for SCTP. EMSGSIZE is used below. And if an app
chooses not to receive event, we need to map some of those events to
an error. We need to figure out the mapping.]
5.1.1 socket()
Applications use socket() to create a socket descriptor to represent
a SCTP endpoint. The syntax is
sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
Or
sd = socket(PF_INET6, SOCK_STREAM, IPPROTO_SCTP);
The first one creates an endpoint which can use only IPv4 addresses.
The second one creates an endpoint which can use both IPv6 and IPv4
mapped addresses.
5.1.2 bind()
Applications use bind() to pass addresses assoicated with a SCTP
endpoint to the system . Those addresses are the eligible transport
addresses for sending and receiving data the endpoint can use to
present to its peers. The syntax is
ret = bind(int sd, struct sockaddr *addr, int addrlen);
sd is the socket descriptor created by socket(), addr is the address
structure (struct sockaddr_in or struct sockaddr_in6 [RFC 2553]),
and addrlen is the size of the address structure. Caller should use
struct sockaddr_storage described in RFC 2553 to represent addr for
portability reason.
If sd is a IPv4 socket, the address has to be a IPv4 address. If sd
is a IPv6 socket,the address can be a IPv4 or IPv6 address.
Applications can call bind() multiple times to associate multiple
addresses to the endpoint.
If the IPv4 address specified is INADDR_ANY or the IPv6 address
specified is in6addr_any, which is normally used by server
applications, the system will associate the endpoint with all its
interfaces. Note that these wildcard addresses can only be used
one and only one time in bind(). This means that it has to be used
in the first bind() call, and the application cannot call bind() on
that endpoint again.
After calling bind(), the SCTP endpoint will accept all SCTP INIT
requests. But it will promptly send an ABORT and discard data
received until a listen(), described below, is performed on the
socket.
5.1.3 listen()
Applications use listen() to inform the system that it is ready to
accept SCTP associations. The syntax is
ret = listen(int sd, int backlog);
sd - is the socket descriptor of a SCTP endpoint, and
backlog - is the number of outstanding associations in the
socket's accept queue. These associations have already
finished the four-way INIT handshake [SCTP] section 5 and
are in ESTABLISHED SCTP state.
5.1.4 accept()
Applications use accept() to remove ESTABLISHED SCTP assocations from
the accept queue. A new socket descriptor is created to represent the
new association. The syntax is:
new_sd = accept(int sd, struct sockaddr *addr, socklen_t *addrlen);
sd - is the listening socket descriptor,
addr - will contain the primary address of the peer endpoint when
accept() returns,
addrlen - will store the size of the address returned.
new_sd - is the socket descriptor of the new association.
5.1.6 connect()
Applications use connect() to initiate an association to a peer. The
syntax is
ret = connect(int sd, const struct sockaddr *addr, int addrlen);
sd is the socket descriptor created by socket(), addr is the peer's
address, and addrlen is the size of the address.
This is similar to the ASSOCIATE primitive described in [SCTP] section
10.1. By default, there is only one outbound stream. To change this,
use the SCTP_INITMSG option described in section 6.
If a bind() is not called prior to the connect() call, the system will
pick an ephemeral port and one of its addresses as the primary address
for the association. If an application wants to utilitize the
multi-homing feature of SCTP, it needs to call bind() before calling
connect().
Editors Note: [Another semantics to consider is without bind(), the
system will use one address from each interface to create the list of
addresses for the association. This automatically enables the fault
tolerant feature for existing applications ported to use SCTP without
any special change. ]
5.1.7 close()
Applications use close() to close does an association. The syntax is
ret = close(int sd);
sd is the socket descriptor of the association to be closed.
This is similar to the SHUTDOWN primitive described in [SCTP] section
10.1. The system will gracefully close down the association.
5.1.8 shutdown()
Applications use shutdown() to abort an association. The syntax is
ret = shutdown(int sd, int how);
sd is the socket descriptor and how does not have meaning.
This is similar to the ABORT primitive described in [SCTP] section
10.1. The system will terminate the association and release the
resources used by it. The value of how does not affect the behavior
of the ABORT. To pass a cause code [SCTP] section 10.1, the caller
should use sendmsg() described below. Note also that a caller can use
the MSG_ABORT flag in sendmsg() to abort an association, without
calling shutdown().
5.1.9 sendmsg() and recvmsg()
Applications use sendmsg() and recvmsg() to transmit data to and
receive data from its peer. The semantics is similar to the Datagram
model described in Section 4. There are several differences.
1. The msg_name field in the msghdr normally is not filled in. When
sending, if the caller wants to send to a different peer address other
than the primary address, it can set the address in the msg_name
field. When receiving, if a message is not received from the primary
address, the system fills in the msg_name field so that the caller can
retrieve the information.
2. The INIT type must not be used in msghdr. To change the default
initialization behavior, the caller can use SCTP_INITMSG socket
option.
3. The caller must use close() to gracefully shutdown an
assocication. If the caller sets the ABORT or SHUTDOWN flag in
sendmsg(), the system will return an error.
5.2 Examples
[To be filled in... ]
6.1 Common calls and operations to both models.
6.1 send(), recv(), sendto(), recvfrom()
Applications can use send() and sendto() to transmit data to the peer
of a SCTP endpoint. recv() and recvfrom() can be used to receive data
from the peer. The syntax is
size = send(int sd, connst void *msg, size_t len, int flags);
size = sendto(int sd, const void *msg, size_t len, int flags,
const struct sockaddr *to, int tolen);
size = recv(int sd, void *buf, size_t len, int flags);
size = recvfrom(int sd, void *buf, size_t len, int flags,
struct sockaddr *from, int *fromlen);
sd - is the socket descriptor of a SCTP endpoint,
msg - is the message to be sent,
len - is the size of the message or the size of buffer,
to - is one of the peer addresses of the association to be used to
send the message,
tolen - is the size of the address,
buf - is the buffer to store a received message,
from - is the buffer to store the peer address used to send the
received message,
fromlen - is the size of the receive buffer,
flags -is described below.
SCTP has the concept of multiple streams in one association. The
above calls do not allow the caller to specify which stream a
message should send to or received from. The system uses stream 0 as
the default stream for the above calls. In all calls listed above
the socket descriptor passed to these calls must represent a single
association.
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(). Or
the caller can use sendmsg() to do that without combining them.
In receiving, if the buffer supplied is not large enough to hold a
complete messaage, the receive call will return a EMSGSIZE error.
Refer to recvmsg() for a method to receive partial message.
The flags parameter is formed by ORing one or more of the following:
UNORDERED
SCTP has a concept of unordered delivery. When sending, caller can
use this flag to tell the system that this message can be delivered
unordered. The caller must set this flag in all calls to transmit
unorderd messages.
Note: that these calls, when used in the datagram mode, may only be
used with high bandwidth socket descriptors (see section 4.3).
6.2 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 6.4.
The syntax is:
ret = getsockopt(int sd, int level, int optname, void *optval,
int *optlen);
ret = setsockopt(int sd, int level, int
optname, const void *optval,
int optlen);
sd - is the socket descript,
level - is IPPROTO_SCTP for all SCTP options,
optname - is the option name,
optval - is the buffer to store the value of the option,
optlen - is the size of the buffer.
6.3 read() and write()
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: that these calls, when used in the datagram mode, may only be
used with high bandwidth socket descriptors (see section 4.3).
6.4 Socket Options
The following sub-section dictates various socket operations
that are common to both models. All optional parameters
include a socket_storage structure. For the datagram model
this MUST be set to identify the association instance that
the operation effects. For the connnection oriented model
and high bandwidth datagram sockets (see section 4.3) this
parameter is ignored.
6.4.1 Read / Write Options
6.4.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO)
The protocol parameters used to initialize and bound retransmission
timeout (RTO) are tunable. See [SCTP] for more information on how
these parameters are used in RTO calculation.
The following structure is used to access and modify these parameters:
struct sctp_rtoinfo {
struct socket_storage srto_address;
uint32_t srto_initial;
uint32_t srto_max;
uint32_t srto_min;
};
srto_address is the identifying address as described in 6.4,
srto_initial contains the initial RTO value, srto_max and srto_min
contain the maximum and minumum bounds for all RTOs.
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.
6.4.1.2 Association Retransmission Parameter (SCTP_ASSOCRTXINFO)
The protocol parameter used to set the number of retransmissions sent
before an association is considered unreachable is tunable. See [SCTP]
for more information on how this parameter is used.
The following structure is used to access and modify this parameters:
struct sctp_assocparams {
struct sockaddr_storage sasoc_address;
uint16_t sasoc_asocmaxrxt;
};
sasoc_address is the identifying address as described in 6.4,
sasoc_asocmaxrxt contains the maximum retransmission attempts
to make for the association.
To access or modify these parameters, the application should call
gesockopt or setsockopt() respectively with the option name
SCTP_ASSOCRTXINFO.
The maximum number of retransmissions before a path is considered
unreachable is also tunable, but is path-specific, so it is covered in
a seperate option. If an application attempts to set the value of the
association maximum retransmission parameter to less than the sum of
all path maximum retransmission parameters, setsockopt() shall return
an error. The reason for this, from [SCTP] section 8.2:
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 addresses may
become inactive while the endpoint still considers the peer endpoint
reachable.
6.4.1.3 Path Parameters (SCTP_PATHPARAMS)
Applications can enable or disable heartbeats for any path, modify a
path's heartbeat interval, and adjust the path's maximum number of
retransmissions sent before a path is considered unreachable. The
following structure is used to access and modify a path's parameters:
struct sctp_pathparams {
struct sockaddr_storage spp_path;
uint32_t spp_interval;
uint16_t spp_pathmaxrxt; };
spp_path specifies which path is of interest (for the datagram model
this also will infer the association in question). spp_interval contains
the value of the heartbeat interval, in milliseconds. A value of 0,
when modifying the parameter, specifies that the heartbeat on this
path should be disabled. spp_pathmaxrxt contains the maximum number of
retransmissions before this path shall be considered unreachable.
To access or modify these parameters, the application should call
gesockopt or setsockopt() respectively with the option name
SCTP_PATHPARAMS.
6.4.1.4 Initialization Parameters (SCTP_INITMSG)
Applications can specify protocol parameters for the default
association intialization. The structure used to access and modify these
parameters is defined in section 3.1.1. The option name argument to
setsockopt() and getsockopt() is SCTP_INITMSG.
Setting initialization parameters is effective only on an
unconnected socket (for the datagram model only future associations
are effected by the change).
6.4.2 Read-Only Options
6.4.2.1 Path Information (SCTP_PATHINFO)
Applications can retrieve information about a path, including its
reachability state, congestion window, and retransmission timer
values. This information is read-only, so only getsockopt() operates
on this option. Calls to setsockopt() on this option will return an
error. The following structure is used to access this information:
struct sctp_pathinfo {
struct sockaddr_storage spath_path;
int spath_state;
uint32_t spath_cwnd;
uint32_t spath_srtt;
uint32_t spath_rto;
};
spath_path is filled in the the application, and contains the path of
interest (for the datagram model this also will infer the association
in question). On return from getsockopt(), spath_state will contain
the path's state (either SCTP_ACTIVE or SCTP_INACTIVE), spath_cwnd the
path's current congestion window, spath_srtt the path's current
smoothed round-trip time calculation, and spath_rto the path's current
retransmission timeout value. spath_srtt and spath_rto are in
milliseconds.
To retrieve this information, use getsockopt() with the option name
set to SCTP_PATHINFO.
6.4.2.2 Peer Endpoint's Set of Addresses (SCTP_PATHCOUNT, SCTP_ALLPATHS)
Applications can retrieve the set of addresses that correspond to a
peer endpoint. Since this set is variable length, two options are
needed to retrieve the information: the first, SCTP_PATHCOUNT, takes
the following structure as its argument to getsockopt:
struct sctp_pathcnt{
struct sockaddr_storage spthc_address;
uint32_t spthc_numpaths
};
srto_address is the identifying address as described in 6.4,
spthc_numpaths if filled in upon return from this call
indicating the number of addresses associated with the
peer. The application can then allocate a buffer large enough to
hold all the peer's addresses, and call getsockopt() with
SCTP_ALLPATHS. For the datagram model, the first address in
the call to SCTP_ALLPATHS MUST be filled in with a valid
address that identifies the association.
On return, each address is represented as a struct sockaddr_storage,
so if n contains the number of peer addresses, the caller must
allocate a buffer of size n * sizeof (struct sockaddr_storage). The
application can retrieve information on each path by enumerating
through the returned list of addresses and calling getsockopt() with
the SCTP_PATHINFO option name. This information is read-only.
6.4.2.3 Association Status (SCTP_STATUS)
Applications can retrieve current status information 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 {
struct sockaddr_storage sstat_address;
int sstat_state;
uint32_t sstat_rwnd;
uint16_t sstat_unackdata;
uint16_t sstat_penddata;
struct sctp_pathinfo sstat_primary;
};
sstat_address - sstat_address is the identifying address as described in 6.4,
sstat_state - contains the association's current state (states TBD),
sstat_rwnd - contains the association peer's current receiver window
size,
sstat_unackdata - the number of unacked data chunks,
sstat_penddata - the number of data chunks pending receipt, and
sstat_primary - information on the current primary path.
To access this status values, the application calls getsockopt() with
the option name SCTP_STATUS.
6.4.3. Ancillary Data Interest Options
Applications can receive notifications of certain SCTP events and
per-message information as ancillary data with recvmsg().
The following optional information is available to the application:
1. SCTP_RECVDATAIOEVNT: Per-message information (i.e. stream number,
TSN, SSN, etc. described in section 3.2.2)
2. SCTP_RECVASSOCEVNT: (described in section 3.2.2)
3. SCTP_RECVPATHEVNT: (described in section 3.2.2)
4. SCTP_RECVSENDFAILEVNT: (described in section 3.2.2)
5. SCTP_RECVPEERERR: (described in section 3.2.2)
To receive any ancillary data, first the application register it's
interest by calling setsockopt() to turn on the corresponding flag:
int on = 1;
setsockopt(fd, IPPROTO_SCTP, SCTP_RECVDATAIOEVNT, &on, sizeof(on));
setsockopt(fd, IPPROTO_SCTP, SCTP_RECVASSOCEVNT, &on, sizeof(on));
setsockopt(fd, IPPROTO_SCTP, SCTP_RECVPATHEVNT, &on, sizeof(on));
setsockopt(fd, IPPROTO_SCTP, SCTP_RECVSENDFAILEVNT, &on, sizeof(on));
setsockopt(fd, IPPROTO_SCTP, SCTP_RECVPEERERR, &on, sizeof(on));
Note that for connectionless mode SCTP sockets, the caller of recvmsg
will receive ancillary data for ALL associations bound to the file
descriptor in use. For connection-oriented SCTP sockets, the caller
will receive ancillary data for only the single association bound to
the file descriptor.
By default the connection oriented socket has all options off.
By default the datagram oriented socket has SCTP_REVCVDATAIOEVENT and
SCTP_RECVASSOCEVNT on and all other options off.
The format of the data structures for each ancillary data item is
given in section 3.2.2.
6.5 Helper Functions
[To be filled in. They are those functions to help application
programmers to deal with msghdr and cmsghdr. ]
7. Security
To be filled in later.
8. Authors' Addresses
Randall R. Stewart Tel: +1-815-479-8536
Cisco Systems, Inc. EMail: rstewart@flashcom.net
Crystal Lake, IL 60012
USA
Qiaobing Xie Tel: +1-847-632-3028
Motorola, Inc. EMail: qxie1@email.mot.com
1501 W. Shure Drive, #2309
Arlington Heights, IL 60004
USA
La Monte Yarrol Tel: +1-847-632-xxxx
Motorola, Inc. EMail: piggy@cig.mot.com
1501 W. Shure Drive, #2309
Arlington Heights, IL 60004
USA
Jonathan Wood
Sun Microsystems, Inc. Email: jonathan.wood@eng.sun.com
901 San Antonio Road
Palo Alto, CA 94303, USA
Kacheong Poon
Sun Microsystems, Inc. Email: kacheong.poon@eng.sun.com
901 San Antonio Road
Palo Alto, CA 94303, USA
9. References
[RFC2026] Bradner, S., "The Internet Standards Process -- Revision 3",
RFC 2026, October 1996.
[SCTP] R. R. Stewart, Q. Xie, K. Morneault, C. Sharp, H. J. Schwarzbauer,
T. Taylor, I. Rytina, M. Kalla, L. Zhang, and, V. Paxson, "Stream
Control Transmission Protocol," <draft-ietf-sigtran-sctp-11.txt>,
July 2000 work in progress.
[STEVENS] W. R. Stevens, M. Thomas, E. Nordmark, "Advanced Sockets API for
IPv6" <draft-ietf-ipngwg-rfc2292bis-01.txt> December 1999 (Work in
progress)
[RFC2553] Basic Socket Interface Extensions for IPv6. R. Gilligan, S.
Thomson, J. Bound, W. Stevens. March 1999.
| PAFTECH AB 2003-2026 | 2026-04-22 23:28:51 |