辅助套接字数据,对齐问题?

时间:2013-12-31 15:33:44

标签: c sockets

在来自freebsd的ping的源代码中,当代码处理来自timestamp套接字选项的SO_TIMESTAMP的控制数据时,我注意到了这一点:

这里的例子:

            #ifdef SO_TIMESTAMP
            if (cmsg->cmsg_level == SOL_SOCKET &&
                cmsg->cmsg_type == SCM_TIMESTAMP &&
                cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) {
                /* Copy to avoid alignment problems: */
                memcpy(&now, CMSG_DATA(cmsg), sizeof(now));
                tv = &now;
            }
            #endif

作者想到的对齐问题是什么,为什么只保存指向CMSG_DATA(cmsg)的指针是不够的?

在处理相同情况时,我自己复制辅助数据是否重要?

完整的源代码在这里:(See docs

1 个答案:

答案 0 :(得分:2)

cmsgstruct cmsghdr,它是一个可变长度结构,由开头的几个字段组成,后跟从cmsg_data开始的任意字节。由于在编译时不知道任意字节的结构,因此字节开始的位置可能无法使结构中的字段正确对齐。 (有关背景信息,请参阅http://en.wikipedia.org/wiki/Data_structure_alignment。)

所以这里发生的事情是if语句中的表达式是在运行时检查任意字节实际上是什么类型的数据。如果级别,类型和长度指示数据是struct timeval,则将字节(通过CMSG_DATA宏)复制到堆栈上正确对齐的结构中。