msg.controllen 0 только на ipv6 - PullRequest
0 голосов
/ 17 апреля 2020

Я внедряю IPv6 в сетевой движок. Я на функции для получения пакета с UDP. Эта функция извлекает IP-адрес назначения также со структурой cmsghdr. У меня есть следующий код

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. Функция sendto одинакова для IPv4 / IPv6:

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 равен 0 на IPv6?

Большое спасибо!

1 Ответ

0 голосов
/ 20 апреля 2020

Я решил это. Я использовал IPV6_PKTINFO вместо IPV6_RECVPKTINFO в моем setsockopt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...