Multiple Associations with Stream Control Transmission Protocol

 in
The elegant way SCTP handles multiple streams makes it ideal for things like chat clients.
Getting the Association ID

Many of the calls that deal with associations take an association ID as a parameter. Whereas in TCP, a connection effectively is represented by the pair of source and destination endpoint IP addresses, in SCTP, the source and destination can both be multihomed, so they will be represented by the set of source and the set of destination addresses. For one-to-many sockets, the source addresses may be shared by many associations, so I need the destination addresses to identify an association properly. For a single association, these destination addresses all belong to a single endpoint computer. The SCTP variation on getsockopt()—that is, sctp_opt_info()—is used to find an association from an address. The reason I cannot simply use getsockopt() is that I need to pass in a socket address, and the return value includes the association value. This in/out semantics is not supported by all implementations of getsockopt(). The code is:


sctp_assoc_t get_associd(int sockfd, struct sockaddr *sa, socklen_t salen) { 
    struct sctp_paddrinfo sp; 
    int sz; 
    
    sz = sizeof(struct sctp_paddrinfo); 
    bzero(&sp, sz); 
    memcpy(&sp.spinfo_address, sa, salen); 
    if (sctp_opt_info(sockfd, 0, SCTP_GET_PEER_ADDR_INFO, &sp, &sz) == -1) 
        perror("get assoc"); 
    return (sp.spinfo_assoc_id); 
}

Note that Unix Network Programming (volume 1, 3rd ed.) by W. Richard Stevens, et al., gives different code: the specification has changed since that book was written, and the above is now the preferred way (and Stevens' code doesn't work under Linux anyway).

Multiple Associations

A server can handle multiple clients in a number of ways: a TCP server can use a single server socket that listens for clients and deals with them sequentially, or it could fork off each new client connection as a separate process or thread, or it could have many sockets and poll or select between them. A UDP server typically will keep no client state and will treat each message in its entirety as a separate entity. SCTP offers another variation, roughly halfway between TCP and UDP.

An SCTP socket can handle multiple long-lived associations to many endpoints simultaneously. It supports the “connection-oriented” semantics of TCP by maintaining an association ID for each association. On the other hand, it is like UDP in that each read usually returns a complete message from a client. SCTP applications use the TCP model by using the one-to-one sockets that I have discussed in the previous two articles. And, it uses a one-to-many model, which is more like UDP by using a one-to-many socket. When you create a socket, you specify whether it is one-to-one or one-to-many. In the first article in this series, I created a one-to-one socket by the call:

sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)

To create a one-to-many socket, I simply change the second parameter:

sockfd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)

A TCP server handles multiple connections simultaneously by essentially using concurrent reads. This is done by using multiple processes, threads, or by poll/select among many sockets. A UDP server typically uses a single read loop, handling each message as it arrives. An SCTP one-to-many server looks like a UDP server: it will bind a socket and listen. Then, instead of blocking on accept(), which would return a new one-to-one socket, it blocks on sctp_rcvmsg(), which returns a message from either a new or existing association. Pseudo-code for such a server is:


sockfd = socket(...); 
bind(sockfd, ...); 
listen(sockfd, ...); 
while (true) { 
    nread = sctp_rcvmsg(sockfd, ..., buf, ..., &info); 
    assoc_id = sinfo.sinfo_assoc_id; 
    stream = sinfo.sinfo_stream; 
    handle_message(assoc_id, stream, buf, nread); 
}

A client also can use the one-to-many socket model. After binding to a port (probably an ephemeral one), it can use the single socket to connect to many other endpoints and use this single socket to send messages to any of them. It even can do away with an explicit connect operation and just start sending to new endpoints (an implicit connection is done if no existing association exists).

Peeled-Off Sockets

One-to-one sockets follow the TCP model; one-to-many sockets follow the UDP model. Is it possible to have both at once? Yes, it is, to some extent. For example, you may have a server that you can talk to in two modes: ordinary user and superuser. Messages from ordinary users may be handled in UDP style, reading and just responding, while superuser connections may need to be treated differently. SCTP allows a connection on a one-to-many socket to be “peeled off” and become a one-to-one socket. This one-to-one socket may then be treated in TCP-style, while all other associations remain on the one-to-many socket.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

help to compile n run

rams's picture

i m currently working in redhat version 5. I read ur article n want to run the program u have provided in SCTP. During run time what r the additional parameter required except ./chat_server.c. Should i reserve the port. Please reply me.

error :: SCTP_SENDALL;

kkk's picture

i am using linux kernel 2.6.25 and as mentation in linux journal that SCTP_SENDALL is not suported by 2.6.21 but still i am getting an error in line

"sinfo.sinfo_flags |= SCTP_SENDALL;"

kaushal

SCTP_SENDALL Related

kaushal's picture

Dear Sir,

I have installed latest 2.6.22 kernels. of sctp but stiil my code is giving error (see below). please help me out

# cc chat_server.c -o chat_server -L /usr/lib -lsctp
chat_server.c: In function ‘main’:
chat_server.c:60: error: ‘SCTP_SENDALL’ undeclared (first use in this function)
chat_server.c:60: error: (Each undeclared identifier is reported only once
chat_server.c:60: error: for each function it appears in.)

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix