#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
struct sockaddr_in remoteAddr;
int clientSock = socket(PF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
if(clientSock == -1) {
perror("socket");
return 1;
}
memset(&remoteAddr,0,sizeof remoteAddr);
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_len = sizeof remoteAddr;
remoteAddr.sin_port = htons(5555);
remoteAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sctp_assoc_t assoc_id = 0;
if(sctp_connectx(clientSock,(struct sockaddr*)&remoteAddr,1, &assoc_id)!= 0) {
perror("sctp_connectx");
return 1;
}
printf("Connected! Assoc ID %d\n",(int)assoc_id);
return 0;
}
When run, this code fails:
$ clang -Wall sctp_connect.c
$ ./a.out
sctp_connectx: Invalid argument
$ uname -rp
11.0-RELEASE-p9 amd64
But I cannot figure out what's wrong. The sctp_connectx() manpage says it will fail with EINVAL if an address with invalid family or no addresses was provided - but that seems not to be the case from the code.
The sctp_connectx() has several parts where it can fail with EINVAL, but truss
shows it gets to the setsockopt() call, so it's the kernel that fails the call:
socket(PF_INET,SOCK_SEQPACKET,132) = 3 (0x3)
mmap(0x0,2097152,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34374418432 (0x800e00000)
setsockopt(0x3,0x84,0x8007,0x800e16000,0x14) ERR#22 'Invalid argument'
I think answer is there in your query. If we follow the truss
trace then as you said it fails on setsockopt()
.
So the error EINVAL is returned by setsockopt()
. And as per FreeBSD setsockopt()
manual:
[EINVAL]: Installing an accept_filter(9) on a non-listening socket was attempted.
is the description of the error. So I think you should do below things:
htons()
and inet_addr()
And my suggestion is that you should not use inet_addr(), for more details see man pages, as per that:
Use of this function is problematic because -1 is a valid address (255.255.255.255). Avoid its use in favor of inet_aton(), inet_pton(3), or getaddrinfo(3), which provide a cleaner way to indicate error return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With