Moving targets

I’ve been working on SCTP (Stream Control Transmission Protocol) for a while now. Much error and learning involved. One of the things I discovered (or better said; learned the hard way) is that some functions needed by SCTP are deprecated in the last 12 months. My knowledge was based on the excellent Unix Networking Programming book (also known as UNP). And sctp.h in FreeBSD 8.2. However in December 2011 RFC 6458 got published. This document describes the mapping of SCTP into a sockets API.

The functions I used most: sctp_sendmsg() and sctp_recvmsg() are now replaced by sctp_sendv() and sctp_recvv(). (As of FreeBSD 8.3/9.0) But more interestingly the default way to send and receive messages can now be done with recvmsg() and sendmsg(). These two functions, according to UNP (14.5 p390), are the most general of all the I/O functions.

A quick look reveals these methods are in existence for a very long time.

So I’ve started reading RFC 6458, upgraded to FreeBSD 9 and am getting familiar with the sendmsg() and recvmsg() functions.

Olivier

Advertisements

One-to-one or one-to-many? That is the question!

Overview

There are two models of programming in SCTP, one-to-one and one-to-many. The one-to-many comes with all SCTP has to offers, the one-to-one model only a limited set of features can be implemented. However implementing the one-to-one model is very similar to how you would implement the same functionality in TCP. This makes migrating an existing application a relatively painless exercise. If you want to upgrade your existing TCP application to an one-to-many SCTP application significant retooling is needed [1].

Spot the difference

The easiest way to spot the difference between the two is by looking at how the endpoint for communication is created:

One-to-One style

sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);

SOCK_STREAM stands for stream socket, the data stream is clearly associated with one socket.

One-to-Many style

sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);

SOCK_SEQPACKET stands for sequenced packet stream. The data stream is sequenced but there is no mention of a socket in the name.

The slightly less obvious way to see the difference is the way the connection between the client and server is set up.

Program Flow

Here is the one-to-one abstraction model:

One to One TCP lookalike

The server creates a passive socket with a listen() followed by an accept() and waits for a connection to come in.  The client creates an active socket and establishes a connection with a connect(). The moment accept() gets a connection request it creates a new socket and allocates a new file descriptor. The association between the two systems gets created explicitly and incoming connections are handled iteratively.

This is the one-to-many model:

One to many, full on SCTP

After the listen() a connection can come in from multiple clients. The association between the systems will be set up implicitly as soon as the client sends a message. As soon as the client closes the association the server releases the association resources too.

So what’s the difference?

Sending data during connection setup

Only the one-to-many is capable of sending data on the third leg of the four-way handshake SCTP does during connection setup [3].  This speeds up data transmission.

Iterative or Concurrent? (another question)

With the one-to-many model multiple associations can transport data over the same socket. The different connections are handled iteratively. With the sctp_peeloff() function an association can be detached in its own separate socket and/or thread. So if you want to you can use a concurrent model.

Connection State

Because of the connectionless nature of the one-to-many mode a lot of the connection state gets handled by the underlying SCTP transport stack and is of no concern for the application.

Conclusion

The one-to-many model has many advantages; it gives you a clear choice on how to handle your connections. It is even possible to combine an iterative server model with a concurrent one. Data can already be sent whilst setting up the association. And last but not least the application has less connection state to maintain.

The one-to-one model on the other hand not only gives you an easy migration path from an existing TCP application it also makes it easy to switch between TCP and SCTP in the same application; the only difference is the socket() call and maybe a setsockopt().

In a following post I will get into more detail on how to implement this. A good book with lots of examples and detailed explanation on how SCTP (and other protocols) work is Unix Network Programming, well worth a read.

References

[1][2] W. R. Stevens, B. Fenner, and A. M. Rudoff, Unix Network Programming: Sockets Networking API v. 1, 3rd ed. Addison Wesley, 2003. p.267, p271

[3] “sctp,” FreeBSD Man Pages. [Online]. Available: http://www.freebsd.org/cgi/man.cgi?query=sctp&manpath=FreeBSD+8.2-RELEASE. [Accessed: 24-Dec-2011].