1 This document describes the OpenSS7 API in detail.
6 OpenSS7 defines two types of services, UDP style and TCP style. How OpenSS7
7 distinguishes the two styles is by the way in which the data is presented to
8 the application. In OpenSS7, data is presented as byte streams or datagrams.
9 The stream style is considered the TCP style socket, and the datagram is
10 considered the UDP style socket. The UDP style socket does not represent a one
11 to many mapping of file descriptors to associations as the IETF compatible
14 Instead of adding new system calls, OpenSS7 decided to modify some of the
15 existing system calls to play nicely with multi-homing. So, to bind to
16 multiple addresses, you pass in an array of struct sockaddr* structures and the
17 total length in bytes of the array. Also, when accepting connections from a
18 peer, you would pass in a pointer to an array of struct sockaddr* and the
19 length of the array in bytes.
22 Building ACE/TAO with support for OpenSS7 SCTP
23 ==============================================
25 - apply OpenSS7's SCTP patch (see OpenSS7's readme for details)
27 - compile kernel with the following kernel variables (.config file)
29 + CONFIG_SCTP_TCP_COMPATIBLE=y
30 + CONFIG_SCTP_HMAC_SHA1=y
31 + CONFIG_SCTP_HMAC_MD5=y
32 + CONFIG_SCTP_ADLER_32=y
33 + CONFIG_SCTP_CRC_32C=y
35 - install header file (sctp.h) into /usr/local/include/sctp.h
37 - make ACE/TAO with "sctp=openss7" -- ie. "make sctp=openss7"
42 There are a few common calls which have the same semantics no matter which
43 interface you are using (UDP style or TCP style). So, the usual calls used in
53 while the usual calls for a server are as follows:
62 The previous example mimics the way in which the TCP protocol is used.
63 There are some exceptions to the above sequence which we will get into a little
64 later. So, let's talk about the system calls above.
68 The socket() call creates a file descriptor for the application to use to
69 communicate with the SCTP stack. The signature of socket() is as follows:
71 int socket(int network, int service, int proto)
73 network - AF_INET or AF_INET6 (AF_INET6 is not currently supported)
74 service - SOCK_SEQPACKET which gives us the UDP style interface
75 SOCK_STREAM which gives us the TCP style interface
76 proto - IPPROTO_SCTP which is the SCTP protocol number(132)
80 The bind() call is used to attach the socket descriptor to the given array of
81 addresses. bind() may only be called once. The address structures sent in as
82 arguments to bind must have the same port number. That is, you may have
83 multiple addresses, but only 1 port number. The signature of bind() is as
86 int bind(int fd, struct sockaddr* addrs, socklen_t addrs_len)
88 fd - A SCTP socket descriptor
89 addrs - An array of struct sockaddr* which have the same port number
90 addrs_len - The total length in bytes of the addrs array
92 If an address structure is sent in with the address of INADDR_ANY, then SCTP
93 will bind to all the addresses on the host and either pick an ephemeral port or
94 use the one specified in the address structure.
98 The setsockopt() call is used to adjust many different parameters to the SCTP
99 protocol. Please see the sctp(7) man page for more details.
103 The connect() call can be used to initialize a connection with a peer SCTP
104 machine. A connection can be initialized in 2 ways. The first is this
105 call(connect()). The second way is to allow implicit initialization when the
106 application calls sendmsg or sendto with the address of the remote host
107 specified. To allow data to be piggybacked with the COOKIE_ECHO chunk, you
108 must use the second initialization technique. The signature of connect is as
111 int connect(int fd, struct sockaddr* r_addr, socklen_t r_addr_len)
113 fd - An SCTP socket descriptor
114 r_addr - A single address structure with the address of the remote host
115 r_addr_len - Length in bytes of the the address structure
117 Note that only one address is sent into the connect call. The SCTP protocol
118 will negotiate the valid IP addresses to use with multi-homing.
122 The listen() call prepares the SCTP socket to accept new associations. The
123 signature is as follows:
125 int listen(int fd, int backlog)
127 fd - An SCTP socket descriptor
128 backlog - The maximum number of unaccepted connections
132 The accept() call allows the application to explicitly accept an incoming
133 association initialization attempt. accept() returns a new file descriptor
134 which can be used to send data to the client. accept() has a slightly
135 different semantic which allows it to take an array of address structures.
136 This gives the application the chance to get a specified number of addresses
137 from the peer on initialization. The signature of accept() is as follows:
139 int accept(int fd, struct sockaddr* r_addr, socklen_t *r_addr_len)
141 fd - A SCTP socket descriptor
142 r_addr - An array of address structures which will be filled with the
143 addresses of the remote host
144 r_addr_len - The length of the array of address structures passed in.
146 accept() will only put as many addresses in the address array as is specified
147 by the r_addr_len argument.
151 Start the association shutdown sequence. The signature is as follows:
155 fd - A SCTP socket descriptor
159 This section describes the sending and receiving of data on an SCTP socket.
160 This is where the differences between the TCP style and UDP style sockets
161 shows. SCTP uses the standard pairs of calls:
164 2) sendmsg()/recvmsg()
165 3) sendto()/readfrom()
169 When the SCTP socket is opened as a UDP style socket, data is presented to the
170 application as datagrams. This means that calls to the receive class of system
171 calls returns only datagrams. For example, assume a sender sends 2 100 byte
172 datagrams. Now assume that the receiver calls one of the receive routines with
173 a max buffer size of 120 bytes. Assuming no errors are encountered, only 100
174 bytes are returned to the receiver (only 1 datagram), leaving the last 20 bytes
175 empty in the receivers buffer. When the last of a datagram is read, the
176 MSG_EOR flag is returned, and if the datagram is too big to fit into the
177 specified buffer, the MSG_TRUNC flag is returned.
179 With TCP styles sockets, the data is presented to the application as a stream
180 of bytes (like TCP). For example, assume the sender sends 2 100 byte
181 datagrams. Now assume that the receiver calls one of the receive routines with
182 a max buffer size of 120. Assuming no errors are encountered, 120 bytes are
183 returned (100 from the first datagram and 20 from the next datagram), leaving
184 80 bytes in the second datagram. MSG_EOR and MSG_TRUNC are never returned.
188 The send/recv interface is one of the easiest ways of sending data back and
189 forth between peers. When send/recv is called, data is sent/read from the
190 default stream. The signature of send/recv is as follows:
192 int send(int fd, void *data, size_t d_len, int flags)
194 fd - A SCTP socket descriptor
195 data - Data to be sent to the peer
196 d_len - The length of the data in bytes
197 flags - Possible flags to be sent to be passed to the SCTP stack
202 The sendmsg/recvmsg interface is the most powerful and hard to use interface
203 in the SCTP stack. This interface allows the specification of which stream to
204 send data out or receive data from. It also allows the sending of data with a
205 specified protocol payload identifier. The signature is as follows:
207 int sendmsg(int fd, struct msghdr *msg, int flags)
209 fd - A SCTP socket descriptor
210 msg - A struct msghdr structure which holds miscellaneous information
211 flags - Possible flags to be passed to the SCTP stack
214 The msg argument holds the data to be sent to the peer. It also can take an
215 address to send the data to. So, for example, if you had an association with 2
216 addresses for the peer and the default path used the first address, and you
217 wanted to send data to the other address, you could specify that address in the
218 msg structure. If this address field is NULL, then data is sent out the
221 This interface also allows other functions by using the ancillary data field
222 in the msg structure. By using the ancillary data field, you may send data out
223 a different stream by using the SCTP_SID control message. This type of control
224 message would take an integer representing the stream to send data out as it's
225 data. Another option is to use the SCTP_PPI control message which allows the
226 setting of the protocol payload identifier to the specified integer argument.
227 Both of these options only set their values for the current data being sent out.
231 The sendto/recvfrom interface allows the specification of which remote address
232 to send data. The signature of sendto/recvfrom is as follows:
234 int sendto(int fd, void *data, size_t d_len, int flags,
235 struct sockaddr* r_addr, socklen_t r_addr_len)
237 fd - A SCTP socket descriptor
238 data - Data to send to peer
239 d_len - Length of the data to be sent
240 flags - Possible flags to be passed to the SCTP stack
241 r_addr - Address of peer to send data to
242 r_addr_len - Length of peer address
246 This interface is the simplest way of sending data to a peer. When this
247 interface is used, data is sent/received through the default stream (as set by
248 SCTP_SID). The signature is as follows:
250 int write(int fd, void *data, size_t d_len)
252 fd - A SCTP socket descriptor
253 data - Data to be sent to peer
254 d_len - Length of data
258 This interface allows the sending of multiple buffers of data in one system
259 call. This call places all the buffers into one SCTP data chunk. The signature is as follows:
261 int writev(int fd, struct iovec *iov, int ct)
263 fd - A SCTP socket descriptor
264 iov - An array of iovec structures. The order they are in the array is the
265 order they are placed in the data chunk
266 ct - The number of iovec structures to send