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.
-- users mailing list users@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe or change subscription options: https://admin.fedoraproject.org/mailman/listinfo/users Guidelines: http://fedoraproject.org/wiki/Mailing_list_guidelines