Sir,
I am trying to demonstrate the multihoming feature of SCTP using two systems.
I am binding two ip addresses to one system using sctp_bindx() and one ip address to other system.
I am sending data from the system with two ip addresses to the system with one ip address.During data transfer I am disconnecting the primary path.But the data is not getting transmitted through the secondary path.Can you suggest what can be the problem?
When the primary path get disconnected, will SCTP automatically choose the secondary path or do we have to manually change the primary path depending on the notifications from the peer transport endpoint?
Can you give me some sample codes (both client and server) that demonstrates the multihoming feature of SCTP?
I am herewith sending the code that I have written to demonstrate multihoming feature.
/ /---------------------------------------------------------------------- ------------------------------------------
//Multihome Server
//Binds multiple ip addresses and sends data through three independent streams
/ /---------------------------------------------------------------------- ------------------------------------------
void multihome_server()
{
int sock_fd,msg_flags,count0,count1,count2,fd0,fd1,fd2,i;
int flag0=1,flag1=1,flag2=1;
void *addr_buf,*buf_ptr;
char readbuf[BUFFSIZE];
char *str[] = {"aa","bb","cc"};
struct sockaddr_in *servaddr1,*servaddr2,cliaddr,servaddr;
struct sctp_sndrcvinfo sri;
struct sctp_event_subscribe evnts;
char buf0[BUFFSIZE],buf1[BUFFSIZE],buf2[BUFFSIZE];
socklen_t len;
size_t rd_sz,length;
addr_buf = malloc(2*(sizeof(struct sockaddr_in)));
buf_ptr = addr_buf;
servaddr1 = (struct sockaddr_in*)buf_ptr;
servaddr1->sin_family = AF_INET;
servaddr1->sin_port = htons(SERV_PORT);
servaddr1->sin_addr.s_addr = inet_addr(SERV_ADDR1);
buf_ptr += sizeof(struct sockaddr_in);
servaddr2 = (struct sockaddr_in*)buf_ptr;
servaddr2->sin_family = AF_INET;
servaddr2->sin_port = htons(SERV_PORT);
servaddr2->sin_addr.s_addr = inet_addr(SERV_ADDR2);
sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
printf("Socket Created.........................\n");
sctp_bindx(sock_fd, (SA *)addr_buf,2,SCTP_BINDX_ADD_ADDR);
printf("binding multiple ip addresses..........\n");
bzero(&evnts, sizeof(evnts));
evnts.sctp_data_io_event = 1;
setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
&evnts, sizeof(evnts));
listen(sock_fd, LISTENQ);
printf("listening...............................\n");
len = sizeof(struct sockaddr_in);
length = sizeof(readbuf);
printf("multihome_server running................\n");
rd_sz = sctp_recvmsg(sock_fd, readbuf, &length,
(SA *)&cliaddr, &len,
&sri,&msg_flags);
printf("%s\n",readbuf);
fd0 = open(str[0],O_RDWR);
fd1 = open(str[1],O_RDWR);
fd2 = open(str[2],O_RDWR);
while(1) {
count0 = read(fd0,buf0,sizeof(buf0));
if(count0 == 0)
flag0 = 0;
else {
if(count0 < 0) {
perror("Error in read\n");
exit(1);
}
sri.sinfo_stream = 0;
sctp_sendmsg(sock_fd, buf0, count0,
(SA *)&cliaddr, len,
sri.sinfo_ppid,
sri.sinfo_flags,
sri.sinfo_stream,
0, 0);
printf("Sending message through stream %d\n",sri.sinfo_stream);
}
count1 = read(fd1,buf1,sizeof(buf1));
if(count1 == 0)
flag1 = 0;
else {
if(count1 < 0) {
perror("Error in read\n");
exit(1);
}
sri.sinfo_stream = 1;
sctp_sendmsg(sock_fd, buf1, count1,
(SA *)&cliaddr, len,
sri.sinfo_ppid,
sri.sinfo_flags,
sri.sinfo_stream,
0, 0);
printf("Sending message through stream %d\n",sri.sinfo_stream);
}
count2 = read(fd2,buf2,sizeof(buf2));
if(count2 == 0)
flag2 = 0;
else {
if(count2 < 0) {
perror("Error in read\n");
exit(1);
}
sri.sinfo_stream = 2;
sctp_sendmsg(sock_fd, buf2, count2,
(SA *)&cliaddr, len,
sri.sinfo_ppid,
sri.sinfo_flags,
sri.sinfo_stream,
0, 0);
printf("Sending message through stream %d\n",sri.sinfo_stream);
}
if((flag0|flag1|flag2) == 0)
break;
}
close(fd0);
close(fd1);
close(fd2);
close(sock_fd);
}
/ /---------------------------------------------------------------------- ------------------------------------------
//Multihome Client
/ /---------------------------------------------------------------------- ------------------------------------------
void multihome_client(GtkButton *wasclicked,gpointer data)
{
struct sockaddr_in servaddr,mh_peeraddr;
char mh_recvline[BUFFSIZE],recvbuf[BUFFSIZE] = "hello";
int mh_cli_sock_fd,mh_cli_len,mh_cli_lengh,mh_cli_msg_flags;
mh_cli_sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
prinf("Socket Created..........................\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR1);
servaddr.sin_port = htons(SERV_PORT);
mh_cli_length = sizeof(mh_recvline);
mh_cli_len = sizeof(mh_peeraddr);
printf("multihome_client running...................\n");
sctp_sendmsg(mh_cli_sock_fd,recvbuf,strlen(recvbuf),
(SA *)&servaddr,sizeof(servaddr),0,0,1,0,0);
printf("Client send msg............................\n");
while(1) {
if((rd_sz = sctp_recvmsg(mh_cli_sock_fd, mh_recvline, &mh_cli_length,
(SA *)&mh_peeraddr, &mh_cli_len,
&mh_sri_client,&mh_cli_msg_flags)) < 0) {
perror("Error in Receive fn\n");
exit(1);
}
if(mh_cli_msg_flags != MSG_NOTIFICATION) {
printf("From host:%s\n",inet_ntoa(mh_peeraddr.sin_addr));
printf("From str:%d seq:%d (assoc:0x%x):",
mh_sri_client.sinfo_stream,mh_sri_client.sinfo_ssn,
(u_int)mh_sri_client.sinfo_assoc_id);
printf("%d %s\n",rd_sz,mh_recvline);
}
else {
union sctp_notification *sn;
sn = (union sctp_notification *)mh_recvline;
if ((sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) &&
(sn->sn_assoc_change.sac_state
== SCTP_SHUTDOWN_COMP)) {
close(mh_cli_sock_fd);
break;
}
}
}
}
Thanking you,
Gopi
Do you Yahoo!?
Win a $20,000 Career Makeover at Yahoo! HotJobs
Archive powered by MHonArc 2.6.19+.