Regarding support of SCTP in Fedora 14

Vishwas Dubey dubey.vishwas at gmail.com
Mon Sep 19 10:38:16 UTC 2011


Hi,

It would be really great if anyone could let me know if the SCTP Protocol
(EXPERIMENTAL) module present in the kernel-2.6.35.6-45.fc14.i686 is in full
compliant with RFC 4960.

Also, I have compiled and built the kernel-2.6.35.6-45.fc14.i686 with SCTP
as a built in module. I am successfully able to compile the kernel and load
my machine with the newly built kernel. I am also able to load the sctp
module via modprobe sctp command. When I try to run a simple sctp client and
sctp server program I get the following error message:-

socket created...
setsockopt succeeded...
After bind errno: 13
Description: : Permission denied

This is the error I get when I try to start the server.

I am copy pasting the sample code for server and client for ready reference.

SERVER PROGRAM

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define RECVBUFSIZE             4096
#define PPID                    1234

int main(int argc, char *argv[]) {
       int SctpScocket, n, flags;
       socklen_t from_len;

       //forget about memset(,0,)
       struct sockaddr_in addr = {0};
       struct sctp_sndrcvinfo sinfo = {0};
       struct sctp_event_subscribe event = {0};
       char pRecvBuffer[RECVBUFSIZE + 1] = {0};

       char * szAddress;
       int iPort;
       char * szMsg;
       int iMsgSize;

       if (argc < 3)
       {
         printf("Use parameters: bind_to_address port response\n");
         return 0;
       }

       //get the arguments
       szAddress = argv[1];
       iPort = atoi(argv[2]);
       szMsg = argv[3];
       iMsgSize = strlen(szMsg);
       if (iMsgSize > 1024)
       {
               printf("Message is too big for this test\n");
               return 0;
       }

       //here we may fail if sctp is not supported
if ((SctpScocket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0)
       {
               printf("After socket errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("socket created...\n");

       //make sure we receive MSG_NOTIFICATION
       if (setsockopt(SctpScocket, IPPROTO_SCTP, SCTP_EVENTS, &event,
sizeof(struct sctp_event_subscribe)) < 0)
       {
               printf("After setsockopt errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("setsockopt succeeded...\n");

       addr.sin_family = AF_INET;
       addr.sin_port = htons(iPort);
       addr.sin_addr.s_addr = inet_addr(szAddress);

       //bind to specific server address and port
       if (bind(SctpScocket, (struct sockaddr *)&addr, sizeof(struct
sockaddr_in)) < 0)
       {
               printf("After bind errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("bind succeeded...\n");

       //wait for connections
       if (listen(SctpScocket, 1) < 0) {
               printf("After listen errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("listen succeeded...\n");

       while(true)
       {
               //each time erase the stuff
               flags = 0;
               memset((void *)&addr, 0, sizeof(struct sockaddr_in));
               from_len = (socklen_t)sizeof(struct sockaddr_in);
               memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
n = sctp_recvmsg(SctpScocket, (void*)pRecvBuffer, RECVBUFSIZE,
(struct sockaddr *)&addr, &from_len, &sinfo, &flags);
               if (-1 == n)
               {
                       printf("Error with sctp_recvmsg: -1... waiting\n");
                       printf("errno: %d\n", errno);
                       perror("Description: ");
                       sleep(1);
                       continue;
               }

               if (flags & MSG_NOTIFICATION)
               {
                       printf("Notification received!\n");
                       printf("From %s:%u\n", inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port));
               }
               else
               {
                       printf("Received from %s:%u on stream %d, PPID %d.:
%s\n",
                               inet_ntoa(addr.sin_addr),
                               ntohs(addr.sin_port),
                               sinfo.sinfo_stream,
                               ntohl(sinfo.sinfo_ppid),
                               pRecvBuffer
                       );
               }

               //send message to client
               printf("Sending to client: %s\n", szMsg);
               if (sctp_sendmsg(SctpScocket, (const void *)szMsg, iMsgSize,
(struct
sockaddr *)&addr, from_len, htonl(PPID), 0, 0 /*stream 0*/, 0, 0) < 0)
               {
                       printf("After sctp_sendmsg errno: %d\n", errno);
                       perror("Description: ");
                       return 0;
               }

               //close server when exit is received
               if (0 == strcmp(pRecvBuffer, "exit"))
               {
                       break;
               }
       }//while

       printf("exiting...\n");

       if (close(SctpScocket) < 0) {
               perror("close");
 }
       return (0);
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

CLIENT PROGRAM

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define RECVBUFSIZE     4096
#define PPID            1234

int main(int argc, char * argv[])
{
       int SctpScocket, in, flags;
       socklen_t opt_len;
       char * szAddress;
       int iPort;
       char * szMsg;
       int iMsgSize;

       //forget about memset(,0,);
       struct sockaddr_in servaddr = {0};
       struct sctp_status status = {0};
       struct sctp_sndrcvinfo sndrcvinfo = {0};
       struct sctp_event_subscribe events = {0};
       struct sctp_initmsg initmsg = {0};
       char * szRecvBuffer[RECVBUFSIZE + 1] = {0};
       socklen_t from_len = (socklen_t) sizeof(struct sockaddr_in);

       if (argc < 3)
       {
               printf("Use parameters: send_to_address port message\n");
               return 0;
       }

       //get the arguments
       szAddress = argv[1];
       iPort = atoi(argv[2]);
       szMsg = argv[3];
       iMsgSize = strlen(szMsg);
       if (iMsgSize > 1024)
       {
         printf("Message is too big for this test\n");
         return 0;
//here we fail when Linux does not support SCTP
       if ((SctpScocket = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
               printf("After socket errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("socket created...\n");

       //set the association options
       initmsg.sinit_num_ostreams = 1;  //number of output streams can be
greater
       if (setsockopt( SctpScocket, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
sizeof(initmsg))<0 )
       {
               printf("After setsockopt errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("setsockopt succeeded...\n");

       //other endpoint to make association with
       bzero( (void *)&servaddr, sizeof(servaddr) );
       servaddr.sin_family = AF_INET;
       servaddr.sin_port = htons(iPort);
       servaddr.sin_addr.s_addr = inet_addr( szAddress );

       //establish SCTP association
       if (connect( SctpScocket, (struct sockaddr *)&servaddr,
sizeof(servaddr) ) < 0)
       {
               printf("After connect errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }
       printf("connect succeeded...\n");

       //check status
       opt_len = (socklen_t) sizeof(struct sctp_status);
       if (getsockopt(SctpScocket, IPPROTO_SCTP, SCTP_STATUS, &status,
&opt_len) < 0)
       {
               printf("After getsockopt errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }else
       {
               printf("Association ID\t\t= %d\n", status.sstat_assoc_id );
               printf("Receiver window size\t= %d\n", status.sstat_rwnd );
       }

       //send message to server
       printf("Sending to server: %s\n", szMsg);
       if (sctp_sendmsg(SctpScocket, (const void *)szMsg, iMsgSize, NULL, 0,
htonl(PPID), 0, 0 /*stream 0*/, 0, 0) < 0)
       {
               printf("After sctp_sendmsg errno: %d\n", errno);
               perror("Description: ");
               return 0;
       }

       //read response from test server
       in = sctp_recvmsg(SctpScocket, (void*)szRecvBuffer, RECVBUFSIZE,
(struct sockaddr *)&servaddr, &from_len, &sndrcvinfo, &flags);
       if (in > 0 && in < RECVBUFSIZE - 1)
       {
               szRecvBuffer[in] = 0;
               printf("Received from server: %s\n", szRecvBuffer);
               return 0;
       }
       else
       {
               printf("After sctp_recvmsg errno: %d\n", errno);
               perror("Description: ");
               printf("Return: %d\n", in);
       }

       if (close(SctpScocket) < 0) {
               printf("After close errno: %d\n", errno);
               perror("Description: ");
       }

       printf("exiting...\n");

       //cleanup
       close(SctpScocket);
       return 0;
}

Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.fedoraproject.org/pipermail/users/attachments/20110919/2758672f/attachment.html 


More information about the users mailing list