Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sctp_connectx() gives EINVAL on FreeBSD

Tags:

c

freebsd

sctp

#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'
like image 358
binary01 Avatar asked May 17 '17 15:05

binary01


1 Answers

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:

  1. Explore your socket options whether they are correct with respect to you listener socket.
  2. Check for the errors for functions 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.

like image 143
Pushpendra Avatar answered Nov 01 '22 21:11

Pushpendra