代码之家  ›  专栏  ›  技术社区  ›  Omnifarious

getaddrinfo中AI_V4MAPPED标志的用途是什么?

  •  6
  • Omnifarious  · 技术社区  · 16 年前

    getaddrinfo调用有许多有趣的标志。我想知道AI_标志的用途是什么。在任何系统上,我似乎都无法让getaddrinfo生成::ffff:n.n.n.n表单地址,正如我设置此标志时所期望的那样。我是不是预期错了?我看到虫子了吗?

    特别是,如果我询问AF_INET6系列地址并指定AI_V4MAPPED,我希望看到:ffff:n.n.n地址用于仅具有DNS A(IPv4地址)记录的主机。我通常还希望,如果我指定了AI_,那么我将以::ffff:n.n.n.n形式获得主机的DNS AAAA(IPv6地址)记录和DNS a记录。

    2 回复  |  直到 16 年前
        1
  •  7
  •   caf    16 年前

    在Debian Lenny(glibc 2.7)上,我得到了您希望得到的东西——只有一个例外——如果我指定的话 AI_V4MAPPED AI_ALL ,我查找的主机名的CNAMEs指向A记录,我没有返回这些记录。如果 艾尔 也指定了,或者如果主机名与记录直接关联。

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    
    int main(int argc, char *argv[])
    {
        struct addrinfo hints = { 0 };
        struct addrinfo *res, *res_c;
        int err;
        char name[INET6_ADDRSTRLEN];
    
        if (argc < 2)
        {
            return 1;
        }
    
        hints.ai_family = AF_INET6;
        hints.ai_flags = AI_V4MAPPED | AI_ALL;
    
        err = getaddrinfo(argv[1], NULL, &hints, &res);
    
        if (err)
        {
            printf("getaddrinfo: %s\n", gai_strerror(err));
            return 1;
        }
    
        for (res_c = res; res_c; res_c = res_c->ai_next)
        {
            const void *addr;
            int port;
            struct protoent *proto;
    
            switch (res_c->ai_family)
            {
                case AF_INET6:
                    addr = &((struct sockaddr_in6 *)(res_c->ai_addr))->sin6_addr;
                    port = ((struct sockaddr_in6 *)(res_c->ai_addr))->sin6_port;
                    printf("AF_INET6\t");
                    break;
                case AF_INET:
                    addr = &((struct sockaddr_in *)(res_c->ai_addr))->sin_addr;
                    port = ((struct sockaddr_in *)(res_c->ai_addr))->sin_port;
                    printf("AF_INET\t");
                    break;
                default:
                    addr = NULL;
                    printf("(%d)\t", res_c->ai_family);
            }
    
            proto = getprotobynumber(res_c->ai_protocol);
            if (proto)
            {
                printf("%s\t", proto->p_name);
            }
            else
            {
                printf("(%d)\t", res_c->ai_protocol);
            }
    
            switch (res_c->ai_socktype)
            {
                case SOCK_STREAM:
                    printf("SOCK_STREAM\t");
                    break;
    
                case SOCK_DGRAM:
                    printf("SOCK_DGRAM\t");
                    break;
    
                default:
                    printf("(?socktype?)\t");
                    break;
            }
    
            if (addr && inet_ntop(res_c->ai_family, addr, name, sizeof name))
                printf("addr = %s", name);
    
            if (addr)
                printf(",%d", port);
    
            printf("\n");
        }
    
        return 0;
    }
    
        2
  •  4
  •   T Percival Daniel Gehriger    14 年前

    根据我的经验, AI_V4MAPPED hints.ai_family = AF_INET6 hints.ai_flags = AI_V4MAPPED 它总会回来的 EAI_NONAME gai_strerror()

    它在OSX10.7上正常工作。