我将git日志检查为https://patchwork.sourceware.org/patch/12453/。此修改似乎解决了特定平台上的问题。 但我不明白为什么要在struct sockaddr_storage中交换__ss_align和__ss_padding。 我正在开发的Qualcomm平台有如下大量的类型。
struct sockaddr_storage prefix_addr
(struct sockaddr_in6 *)&(prefix_addr)->sin6_addr.s6_addr
在我们的Cortex A7平台上,struct alignment如下:
在glibc2.23之前:
struct sockaddr_in6
{
sin6_family; //0th byte
sin6_port; //2nd byte
sin6_flowinfo; //4th byte
sin6_addr; //8th byte
};
struct sockaddr_storage
{
ss_family; //0th byte
__ss_align; //4th byte
__ss_padding; //8th byte
};
glibc2.23之后:
struct sockaddr_storage
{
ss_family; //0th byte
__ss_padding; //2nd byte
__ss_align; //124th byte
};
glibc改变了struct sockaddr_storage,但是struct sockaddr_in6没有改变,所以这个修改会在我们的平台上引起很多对齐问题,导致IPV6地址错误。
答案 0 :(得分:1)
请参阅Florian的回复:
在09/01/2017 12:07 PM,honan li写道:
定义SASTORAGE_DATA(addr)(addr).__ ss_padding
typedef struct qcmap_cm_nl_prefix_info_s { boolean prefix_info_valid; unsigned char prefix_len; unsigned int mtu; struct sockaddr_storage prefix_addr; struct ifa_cacheinfo cache_info; } qcmap_cm_nl_prefix_info_t;
void QCMAP_Backhaul :: GetIPV6PrefixInfo(char * devname, qcmap_cm_nl_prefix_info_t * ipv6_prefix_info) { struct sockaddr_in6 * sin6 = NULL;
...
sin6 =(struct sockaddr_in6 *)& ipv6_prefix_info-> prefix_addr; 的memcpy(SASTORAGE_DATA(ipv6_prefix_info-> prefix_addr), RTA_DATA(RTA) 的sizeof(sin6-> sin6_addr)); ... }
目前可在此公开:
我希望应用程序可以这样做:
struct sockaddr_in6 sin6; memset(& sin6,0,sizeof(sin6));
sin6.sin6_family = AF_INET6; memcpy(& sin6.sin6_addr,RTA_DATA (rta),sizeof(sin6.sin6_addr));的memcpy (& ipv6_prefix_info-> prefix_addr,& sin6,sizeof(sin6));这可以避免任何别名问题和对内部的依赖 struct sockaddr_storage(仅用于分配a的方式) 通用结构sockaddr足够大小和对齐)。它也是 初始化套接字地址的其他组件(例如 端口号和流标签)。
谢谢,Florian
结论是高通公司对sockaddr_storage的使用是不正确的。
答案 1 :(得分:0)
我不确定这是glibc中产生对齐警告的变化:此更改对您显示的源代码没有影响。
相反,我认为高通正在使用clang,从clang 4.x开始,有一个新的对齐警告,我已经看到生成误报关于对齐的警告,具体取决于编写代码的方式:-Waddress-of-packed-member
。
您应该检查您使用的clang版本是否已更改,因为glibc已更改。如果是这种情况,这肯定可以解释您的问题。
使用临时变量会使这些警告消失。
而不是像以下那样打电话:
my_function(((struct sockaddr_in6 *)&prefix_addr)->sin6_addr.s6_addr)
只写:
struct sockaddr_in6 p = *(struct sockaddr_in6 *) &prefix_addr;
my_function(p.sin6_addr.s6_addr);
这可能会避免对齐警告。