IPv6 的 getaddrinfo 始终失败,错误代码为 11268096

Posted

技术标签:

【中文标题】IPv6 的 getaddrinfo 始终失败,错误代码为 11268096【英文标题】:getaddrinfo for IPv6 always fails with error code 11268096 【发布时间】:2021-09-26 02:04:57 【问题描述】:

编辑:在检查 IPv6 Test 时,我发现我的 ISP 不提供 IPv6...否则此代码很好

getaddrinfo() 对于 IPv6 总是失败,错误代码为 11268096,但对于 IPv4 是成功的。

设置Hint.ai_family = AF_INET6; 是触发错误的原因,但我不知道为什么。

另外,我如何获得 sin_port/sin6_port 的数字?我总是得到端口 0。(正如@Remy Lebeau 指出的那样,我只要求域的 IP,所以它不会输出端口......)

void GetAddrInfoFromHostNameIPV6(const char* DomainName, addrinfo* Result, bool& IsSuccessful)

    IsSuccessful = false;
    addrinfo Hint;
    addrinfo* Return = nullptr;
    int ErrorCode;

    memset(&Hint, 0, sizeof(Hint));
    Hint.ai_family = AF_INET6;
    Hint.ai_socktype = SOCK_STREAM;
    //Hint.ai_socktype = SOCK_DGRAM;

    ErrorCode = getaddrinfo(DomainName, NULL, &Hint, &Return) << '\n';
    if (ErrorCode != 0)
    
        std::cout << "\n Error GetAddrInfoFromHostNameIPV6() Failed with Error Code: " << ErrorCode << " in GetAddrInfoFromHostName In: NW_P!";
    
    else
    
        *Result = *Return;
        char IpAddress[INET6_ADDRSTRLEN];
        uint16_t Port;
        inet_ntop(AF_INET6, &((sockaddr_in6*)((Result)->ai_addr))->sin6_addr, IpAddress, INET6_ADDRSTRLEN);
        Port = *(&((sockaddr_in6*)(Result->ai_addr))->sin6_port);
        std::cout << "\n IPV6 Address of Domain '" << DomainName << "' Is " << IpAddress << " With Port: " << Port;

        IsSuccessful = true;
    

    if (!IsSuccessful)// For the safe of readability
    
        std::cout << "\n Error GetAddrInfoFromHostName() Failed in NW_P!\n";
    

【问题讨论】:

请查看github.com/Armin-Montigny/SmlParser/blob/master/source/… 及相关信息。它将处理 IPV4 和 IPV6。也许你可以得到一些想法。 . . @ArminMontigny 谢谢!我会调查的! 【参考方案1】:

在将错误代码分配给 ErrorCode 之前,您将其向左移位 10 位。

十进制11268096 是二进制101010111111000000000000。注意到右边所有多余的零了吗?

你需要在getaddrinfo()返回后去掉&lt;&lt; '\n',它不属于那里,因为你没有在那行代码上将错误代码输出到std::cout

去掉位移,真正的错误码是11004(二进制10101011111100)也就是WSANO_DATA

有效名称,没有请求类型的数据记录。请求的名称有效并且在数据库中找到,但它没有正确的关联数据正在解析。常见的示例是使用 DNS(域名服务器)的主机名到地址转换尝试(使用 gethostbynameWSAAsyncGetHostByName)。返回一条 MX 记录,但没有 A 记录——表明主机本身存在,但不可直接访问。

您可以将错误代码传递给gai_strerror(),以便为您的错误消息输出获取人类可读的字符串,例如:

std::cout << "\n Error GetAddrInfoFromHostNameIPV6() Failed with Error Code: " << ErrorCode << " (" << gai_strerror(ErrorCode) << ") in GetAddrInfoFromHostName In: NW_P!";

至于端口号为0,您不是要求getaddrinfo()解析任何服务名称/端口字符串作为输入(pServiceName参数为NULL),您只是要求将域名转换为IP ,所以它不会输出任何端口号。域本身不使用端口号。端口号由在域/IP 指向的服务器上运行的服务(HTTP 等)使用。


附带说明,您正在泄漏getaddrinfo() 输出的addrinfo 列表。使用完列表后,您需要致电freeaddrinfo()

【讨论】:

您好!并感谢您的回答!但是什么“主机本身存在,但不能直接访问”我不明白......我只是将ipv4更改为ipv6,它不应该一样吗?也感谢您告诉我有关位移的信息!没注意到! @PunalManalan 表示域名存在但不解析为 IPv6 地址。并非所有域都支持 IPv6。 是的,但谷歌有 ipv6 域对吗?它应该可以正常工作吗? @PunalManalan 是的,Google 有一个 IPv6 地址。这就是您在DomainName 参数中传递的内容吗?如果您在问题中提供了minimal reproducible example,那将会有所帮助。请编辑您的问题。 @RemyLebeau 我认为这是我的 ISP 部分的问题 [test-ipv6.com/](IPv6 测试)这就是它所说的“您的 DNS 服务器(可能由您的 ISP 运行)似乎无法访问 IPv6 Internet,或未配置为使用它。这可能会在将来限制您访问纯 IPv6 站点的能力"

以上是关于IPv6 的 getaddrinfo 始终失败,错误代码为 11268096的主要内容,如果未能解决你的问题,请参考以下文章

getaddrinfo with fist NULL参数给出第一个IPv4而不是IPv6

getaddrinfo()详解

getaddrinfo()函数详解-(转自 cxz2009)

Postman发送请求失败报错“Error: getaddrinfo ENOTFOUND xxx.xxx.xxx.xxx“

getaddrinfo() 连续失败并出现 EAI_AGAIN

fopen 失败,getaddrinfo 失败