sctp_connectx()在FreeBSD上给出了EINVAL

bin*_*y01 13 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;   
}
Run Code Online (Sandbox Code Playgroud)

运行时,此代码失败:

$ clang  -Wall sctp_connect.c 
$ ./a.out 
sctp_connectx: Invalid argument
$ uname -rp
11.0-RELEASE-p9 amd64
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚出了什么问题.该sctp_connectx()手册页说,这将失败,如果EINVAL得到了无效的家人或没有地址的地址-但是,这似乎并没有被从代码的情况.

sctp_connectx()有几个部分地方可能会失败,EINVAL,但truss表示它会使用setsockopt()调用,所以它的失败呼叫的内核:

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'
Run Code Online (Sandbox Code Playgroud)

Pus*_*dra 1

我认为答案就在您的查询中。如果我们跟踪truss跟踪,那么正如您所说,它会失败setsockopt()

因此返回错误EINVALsetsockopt()。根据 FreeBSDsetsockopt()手册:

[EINVAL]:尝试在非监听套接字上安装accept_filter(9) 。

是错误的描述。所以我认为你应该做以下事情:

  1. 探索您的套接字选项,它们对于您的侦听器套接字是否正确。
  2. htons()检查功能和错误inet_addr()

我的建议是您不应该使用 inet_addr(),有关更多详细信息,请参阅手册页,如下所示:

使用此函数是有问题的,因为 -1 是有效地址 (255.255.255.255)。避免使用它,而应使用 inet_aton()、inet_pton(3) 或 getaddrinfo(3),它们提供了一种更简洁的方式来指示错误返回。