【问题标题】:getaddrinfo on Android returning error EAI_BADFLAGSAndroid上的getaddrinfo返回错误EAI_BADFLAGS
【发布时间】:2017-02-02 02:29:18
【问题描述】:

我们正在尝试在 Android API 14 及更高版本上使用 getaddrinfo(在使用 NDK r12 的 C++ 代码中)从 IPV4 地址获取合成的 IPV6 地址。这适用于具有 NAT64 的仅 IPV6 网络。但是,如果设置了 aiflags (AI_V4MAPPED | AI_ADDRCONFIG),getaddrinfo 将返回 EAI_BADFLAGS。

        struct addrinfo *ai, hints;
        memset(&hints, 0, sizeof(hints));
        hints.ai_socktype = SOCK_DGRAM;

        hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
         hints.ai_family = AF_UNSPEC;
        int error = getaddrinfo( "46.23.43.12", "80", &hints, &ai);
        if( error == 0)

与 Linux 有什么主要区别吗?

【问题讨论】:

    标签: android linux sockets networking android-ndk


    【解决方案1】:

    是的,预计会与 linux 有所不同。尽管 Android 在 Linux 内核上运行,但 libc、bionic 几乎是基于 BSD 的(它的某些部分也来自相当老的版本,尽管最近已经更新)。

    我不确定是否有任何关于此的明确文档,但您可以检查实现以了解它的行为方式。

    请参见此处的第 617-718 行: https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c

        if (hints->ai_flags & ~AI_MASK)
            ERR(EAI_BADFLAGS);
    

    还有第 153-170 行: https://android.googlesource.com/platform/bionic/+/085543106/libc/include/netdb.h

    /*
     * Flag values for getaddrinfo()
     */
    #define AI_PASSIVE  0x00000001 /* get address to use bind() */
    #define AI_CANONNAME    0x00000002 /* fill ai_canonname */
    #define AI_NUMERICHOST  0x00000004 /* prevent host name resolution */
    #define AI_NUMERICSERV  0x00000008 /* prevent service name resolution */
    /* valid flags for addrinfo (not a standard def, apps should not use it) */
    #define AI_MASK \
        (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \
        AI_ADDRCONFIG)
    #define AI_ALL      0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
    #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
    #define AI_ADDRCONFIG   0x00000400 /* only if any address is assigned */
    #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */
    /* special recommended flags for getipnodebyname */
    #define AI_DEFAULT  (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
    

    因此,如果您设置了AI_MASK 中列出的标志之外的任何标志,getaddrinfo 将返回EAI_BADFLAGS。此外,实际上在仿生中的任何地方都没有使用AI_V4MAPPED,并且在 cmets 之外只提到了AI_ADDRCONFIG(而且由于getaddrinfo 禁止设置它,您似乎永远无法真正接触到它)。

    【讨论】:

    • 谢谢,答案差不多了。这是否意味着Android上实现的getaddrinfo无法生成IPV6合成地址
    • 是的,看起来是这样。
    • 只是想知道如果 getaddrinfo 不能这样做,是否有任何 Java API 可以从 IPV4 文字生成合成的 IPV6 地址
    【解决方案2】:

    rfc7050,我们可以找到如何从 IPv4 地址合成 IPv6 地址的解决方案。您也可以参考nativePrintIPv6Prefix

    有了 IPv6 前缀,您可以轻松合成 IPv6 地址。

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-01
      • 2011-04-06
      相关资源
      最近更新 更多