Exploring Head-of-Line Blocking
A stream in SCTP is not a stream of bytes (as in TCP), but a sequence of messages that is ordered within the association. These sub-ordered streams are used to avoid the head-of-line blocking found in TCP.
Head-of-line blocking occurs when a TCP segment is lost and a subsequent TCP segment arrives out of order. That subsequent segment is held until the first TCP segment is retransmitted and arrives at the receiver. Delaying delivery of the subsequent segment assures that the receiving application sees all data in the order in which the sending application sent it. This delay to achieve complete ordering is quite useful, but it has a downside. Assume that semantically independent messages are being sent over a single TCP connection.
#include "unp.h"
void sctpstr_client_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
{
struct sockaddr_in peeraddr;
struct sctp_sndrcvinfo sri;
char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
socklen_t len;
int rd_sz, i, strsz;
int msg_flags;
bzero(sendline, sizeof(sendline));
bzero(&sri, sizeof(sri));
while(fgets(sendline,SCTP_MAXLINE-9, fp)!=NULL)
{
strsz=strlen(sendline);
if(sendline[strsz-1]=='\n')
{
sendline[strsz-1]='\0';
strsz--;
}
for(i=0;i<SERV_MAX_SCTP_STRM;i++)
{
snprintf(sendline+strsz, sizeof(sendline)-strsz,".msg. %d",i);
Sctp_sendmsg(sock_fd, sendline, sizoef(sendline),to, tolen,0,0,i,0,0);
}
for(i=0;i<SERV_MAX_SCTP_STRM;i++)
{
len=sizeof(peeraddr);
rd_sz=Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), (SA *)&peeraddr, &len, &sri, &msg_flags);
printf("From str:%d seq:%d (assoc: 0X%X) :", sri.sinfo_stream, sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id);
printf("%.*s\n", rd_sz,recvline);
}
}
}
sctp_strcliecho
for(i=0;i<SERV_MAX_SCTP_STRM;i++)
{
snprintf(sendline+strsz, sizeof(sendline)-strsz,".msg. %d",i);
Sctp_sendmsg(sock_fd, sendline, sizoef(sendline),to, tolen,0,0,i,0,0);
snprintf(sendline+strsz, sizeof(sendline)-strsz, ".msg.%d 2",i);
Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), to, tolen, 0,0,i,0,0);
}
for(i=0;i<SERV_MAX_SCTP_STRM;i++)
{
len=sizeof(peeraddr);
sctp_strcliecho modifications
Controlling the Number of Streams
if(argc==2)
stream_increment=atoi(argv[1]);
sock_fd=Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
bzero(&initm,sizeof(initm));
initm.sinit_num_ostreams=SERV_MORE_STRMS_SCTP;
Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initm,sizeof(initm));
Requesting more streams in our server