首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在哪些情况下,在从Linux套接字发送/接收数据包后访问辅助数据时,msg_controllen可以为0?

在哪些情况下,在从Linux套接字发送/接收数据包后访问辅助数据时,msg_controllen可以为0?
EN

Stack Overflow用户
提问于 2019-07-24 23:38:08
回答 1查看 367关注 0票数 2

我正在开发一个非常复杂的C程序,该程序设计为在Linux下运行,它在很大程度上依赖于来自套接字的辅助数据。

我实际上遇到了一种奇怪的行为,顺便说一句,这似乎只发生在我的程序上(其他示例代码,如this one,工作正常)。我通过定义来使用辅助数据:

代码语言:javascript
复制
struct msghdr mhdr;
struct iovec iov;
struct cmsghdr *cmsg = NULL;
struct sockaddr_ll addrll;
socklen_t addrllLen=sizeof(addrll);
unsigned char packet[PACKET_SIZE_MAX];
char ctrlBuf[CMSG_SPACE(sizeof(struct scm_timestamping))]; // For example, in order to retrieve timestamps

然后,通过设置:

代码语言:javascript
复制
    memset(&mhdr,0,sizeof(mhdr));

    iov.iov_base=packet;
    iov.iov_len=sizeof(packet);

    mhdr.msg_name=&(addrll); // This is a raw socket
    mhdr.msg_namelen=addrllLen; // This is a raw socket

    mhdr.msg_control=ctrlBuf;
    mhdr.msg_controllen=sizeof(ctrlBuf);

    mhdr.msg_iov=&iov;
    mhdr.msg_iovlen=1;

    mhdr.msg_flags=0;

然后,在设置了一些套接字选项以检索有用的辅助数据(例如,通过设置SO_TIMESTAMPING的软件或硬件时间戳)之后,我使用sendto()recvmsg()发送和接收数据。我能够验证我正在打开的套接字是否确实支持这些选项。

当我尝试提取辅助数据时,有时会出现问题,使用类似以下代码的代码,例如,提取带有发送/接收时间戳的struct scm_timestamping

代码语言:javascript
复制
for(cmsg=CMSG_FIRSTHDR(&mhdr);cmsg!=NULL;cmsg=CMSG_NXTHDR(&mhdr, cmsg)) {
    if(cmsg->cmsg_level==SOL_SOCKET && cmsg->cmsg_type==SO_TIMESTAMPING) {
        hw_ts=*((struct scm_timestamping *)CMSG_DATA(cmsg));
    }
}

有时,CMSG_FIRSTHDR(&mhdr)返回一个空指针,返回的mhdr.msg_controllen0,这样我就无法提取任何时间戳。其他时候,在同一台PC上使用同一块网卡,一切都完全正常。

所以,我的问题是:在哪些情况下,返回的mhdr.msg_controllen通常可以为0?这会不会是因为struct msghdr的定义有问题?或者这是由于某种内核问题?

EN

回答 1

Stack Overflow用户

发布于 2019-07-25 12:23:43

您的控制消息缓冲区可能过小,因为它没有对齐,并且第一个对齐边界下的部分将不可用。我不确定设置缓冲区的正确惯用方法是什么(严格来说,使用malloc可能是避免由于对齐和有效类型/“别名”冲突而导致UB的代码的唯一方法),但将_Alignof(max_align_t) (或sizeof(max_align_t))添加到缓冲区大小可能是一种解决方案。不过,我想知道什么是公认的“正确”方式。

cmsg(3) man page似乎建议使用一个联盟来对齐:

union { /\* Ancillary data buffer, wrapped in a union in order to ensure it is suitably aligned \*/ char buf[CMSG\_SPACE(sizeof(myfds))]; struct cmsghdr align; } u;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57186620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档