- Packets and Streams
- Connections and Circuits
- Moving Networks
- New Socket Interfaces
- Summary
New Socket Interfaces
The one down side of SCTP is that it provides so many new features that it can't be trivially shoehorned into the existing socket APIs. The send(), sendmsg(), and sendto() calls are adequate for TCP and UDP, but they don't provide anything like the information required to send a message over an SCTP connection. Instead, some new calls are introduced, such as this one:
ssize_t sctp_sendmsg(int s, const void *msg, size_t len, const struct sockaddr *to, socklen_t tolen, uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context);
This sends a message. Note that this is the simple version; there is another variant sctp_sendmsgx(), which allows sending to multiple endpoints. The first three arguments are similar to the existing socket calls. They specify the socket and the data. The next two arguments provide the destination address.
The ppid argument is an identifier that is passed to the receiving end. This is useful for things like sequence identifiers. You automatically get this identifier retrieved and placed outside the retrieve buffer, so you can use it for things like out-of-band message sequencing or message types for dispatching the buffer that you retrieve to the handler.
There are a number of different things defined for the flags field already. The most interesting are SCTP_UNORDERED and SCTP_SENDALL. The first allows the packet to be sent out of order, meaning that it will not be delayed if packets sent before it needs retransmitting. The second is more interesting; it will send the packet to every associated endpoint.
Currently, this is relatively inefficient. It will only copy the data into the kernel once, but it will generate one packet for every destination. In future, however, the SCTP standard will probably incorporate multicast. Support for multicast is a required part of IPv6, so when more ISPs have deployed IPv6 this will be very attractive. When it does, this will only require a single packet to be sent.
At the receiving end, you have a similar function for getting the next message:
ssize_t sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr * restrict from, socklen_t * restrict fromlen, struct sctp_sndrcvinfo *sinfo, int *flags);
Again, this is similar to the existing recvmsg() function, but with a few more parameters. The sinfo argument contains most of the parameters that were passed in when the message was sent. This includes the stream, so you can then dispatch the received data to the correct handler. This is the sort of thing that libdispatch is perfect for: allowing you to easily push the handling off to a different work queue for each stream.
If you look on the sctp(4) man page on a system that supports SCTP, then you will find a more detailed description of the changes introduced to the socket API to support SCTP.