msg.controllen 仅在 ipv6 上为 0
msg.controllen is 0 only on ipv6
我在网络引擎中实现了 IPv6。我正在使用 UDP 接收数据包的功能。此函数还使用 cmsghdr
结构检索目标 ip。我有以下代码
int UDPSocket::read_from_to(string& paquet, string& from, string& to, struct timeval *time_kernel /* = NULL */) {
char buffer[65535];
iovec i;
i.iov_base = buffer; // PACKET BUFFER
i.iov_len = 65535;
// A struct for the source IP address
sockaddr_in sa;
sockaddr_in6 sa_ipv6;
if (CompatibilityIPv4::Instance()->canIPv6()) {
bzero((char *) &sa_ipv6, sizeof(sa_ipv6));
sa_ipv6.sin6_family = AF_INET6;
} else {
bzero((char *) &sa, sizeof(sa));
sa.sin_family = AF_INET;
}
// Some place to store the destination address, see man cmsg
int cmsgsize = 0;
if (CompatibilityIPv4::Instance()->canIPv6()) {
cmsgsize = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(struct timeval));
} else {
cmsgsize = CMSG_SPACE(sizeof(struct in_pktinfo)) + CMSG_SPACE(sizeof(struct timeval));
}
char cmsg[cmsgsize];
// The actual structure for recvmsg
msghdr m;
bzero(&m,sizeof(m));
if (CompatibilityIPv4::Instance()->canIPv6()) {
m.msg_name = &sa_ipv6;
m.msg_namelen = sizeof(sa_ipv6);
} else {
m.msg_name = &sa; // SOURCE IP
m.msg_namelen = sizeof(sa);
}
m.msg_iov = &i; // PACKET BUFFER, indirect
m.msg_iovlen = 1;
m.msg_control = cmsg; // FOR DESTINATION IP
m.msg_controllen = sizeof(cmsg);
// <<<< ACTUAL SYSTEM CALL >>>>
int p=recvmsg(fd, &m, 0);
std::cout << m.msg_controllen << std::endl;
在 IPv4 中,最后 m.msg_controllen
的值大于 0,但在 IPv6 中它始终为 0,因此我无法获取目标 IP。 IPv4/IPv6 的 sendto 函数相同:
if (CompatibilityIPv4::Instance()->canIPv6()) {
sockaddr_in6 sa;
bzero((char *) &sa, sizeof(sa));
sa.sin6_family = AF_INET6;
inet_pton(AF_INET6, k[0].c_str(), &sa.sin6_addr);
sa.sin6_port = htons(port);
p = sendto(fd,paquet.c_str(),paquet.size(),0,(sockaddr*)&sa, sizeof(sa));
} else {
sockaddr_in sa;
bzero((char *) &sa, sizeof(sa));
sa.sin_family = AF_INET;
inet_aton(k[0].c_str(),&sa.sin_addr);
sa.sin_port = htons(port);
p = sendto(fd,paquet.c_str(),paquet.size(),0,(sockaddr*)&sa, sizeof(sa));
}
你知道为什么我的 m.msg_controllen
在 IPV6 上是 0 吗?
非常感谢!
我已经解决了。我在 setsockopt 中使用 IPV6_PKTINFO
而不是 IPV6_RECVPKTINFO
。
我在网络引擎中实现了 IPv6。我正在使用 UDP 接收数据包的功能。此函数还使用 cmsghdr
结构检索目标 ip。我有以下代码
int UDPSocket::read_from_to(string& paquet, string& from, string& to, struct timeval *time_kernel /* = NULL */) {
char buffer[65535];
iovec i;
i.iov_base = buffer; // PACKET BUFFER
i.iov_len = 65535;
// A struct for the source IP address
sockaddr_in sa;
sockaddr_in6 sa_ipv6;
if (CompatibilityIPv4::Instance()->canIPv6()) {
bzero((char *) &sa_ipv6, sizeof(sa_ipv6));
sa_ipv6.sin6_family = AF_INET6;
} else {
bzero((char *) &sa, sizeof(sa));
sa.sin_family = AF_INET;
}
// Some place to store the destination address, see man cmsg
int cmsgsize = 0;
if (CompatibilityIPv4::Instance()->canIPv6()) {
cmsgsize = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(struct timeval));
} else {
cmsgsize = CMSG_SPACE(sizeof(struct in_pktinfo)) + CMSG_SPACE(sizeof(struct timeval));
}
char cmsg[cmsgsize];
// The actual structure for recvmsg
msghdr m;
bzero(&m,sizeof(m));
if (CompatibilityIPv4::Instance()->canIPv6()) {
m.msg_name = &sa_ipv6;
m.msg_namelen = sizeof(sa_ipv6);
} else {
m.msg_name = &sa; // SOURCE IP
m.msg_namelen = sizeof(sa);
}
m.msg_iov = &i; // PACKET BUFFER, indirect
m.msg_iovlen = 1;
m.msg_control = cmsg; // FOR DESTINATION IP
m.msg_controllen = sizeof(cmsg);
// <<<< ACTUAL SYSTEM CALL >>>>
int p=recvmsg(fd, &m, 0);
std::cout << m.msg_controllen << std::endl;
在 IPv4 中,最后 m.msg_controllen
的值大于 0,但在 IPv6 中它始终为 0,因此我无法获取目标 IP。 IPv4/IPv6 的 sendto 函数相同:
if (CompatibilityIPv4::Instance()->canIPv6()) {
sockaddr_in6 sa;
bzero((char *) &sa, sizeof(sa));
sa.sin6_family = AF_INET6;
inet_pton(AF_INET6, k[0].c_str(), &sa.sin6_addr);
sa.sin6_port = htons(port);
p = sendto(fd,paquet.c_str(),paquet.size(),0,(sockaddr*)&sa, sizeof(sa));
} else {
sockaddr_in sa;
bzero((char *) &sa, sizeof(sa));
sa.sin_family = AF_INET;
inet_aton(k[0].c_str(),&sa.sin_addr);
sa.sin_port = htons(port);
p = sendto(fd,paquet.c_str(),paquet.size(),0,(sockaddr*)&sa, sizeof(sa));
}
你知道为什么我的 m.msg_controllen
在 IPV6 上是 0 吗?
非常感谢!
我已经解决了。我在 setsockopt 中使用 IPV6_PKTINFO
而不是 IPV6_RECVPKTINFO
。