Android上的getaddrinfo返回错误EAI_BADFLAGS

时间:2016-09-24 08:18:54

标签: android linux sockets networking android-ndk

我们正在尝试在Android API 14及更高版本上使用getaddrinfo(使用NDK r12的C ++代码)从IPV4地址获取合成的IPV6地址。这适用于仅具有NAT64的IPV6网络。但是,如果设置了aiflags,则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有什么重大差异吗?

2 个答案:

答案 0 :(得分:7)

是的,预计会有一些与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)

因此,如果您在EAI_BADFLAGS中列出的标志之外设置任何标志,则getaddrinfo将返回AI_MASK。此外,实际上在仿生学的任何地方都没有使用AI_V4MAPPED,并且在评论之外只有一个AI_ADDRCONFIG提及(而且似乎自getaddrinfo禁止以来你实际上无法覆盖它设置它。)

答案 1 :(得分:0)

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

使用IPv6前缀,您可以轻松地合成IPv6地址。