当前位置:  开发笔记 > 运维 > 正文

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

如何解决《getaddrinfo中AI_V4MAPPED标志的用途是什么?》经验,为你挑选了1个好方法。

getaddrinfo调用有许多有趣的标志.我想知道AI_V4MAPPED标志的用途是什么.在没有系统的情况下,我似乎能够获得getaddrinfo来生成:: ffff:nnnn表单地址,正如我在设置此标志时所期望的那样.我期待错误的事吗?我看到了虫子吗?

特别是,如果我要求AF_INET6系列地址并指定AI_V4MAPPED,我希望看到只有DNS A(IPv4地址)记录的主机的:: ffff:nnnn地址.我通常也会期望,如果我指定AI_ALL,我将获得主机的DNS AAAA(IPv6地址)记录和:: ffff:nnnn形式的DNS A记录.

我再次期待这里所有错误的事情吗?

我在Fedora 11上测试了这个 - glibc 2.10.1和OS X 10.4.



1> caf..:

我得到了你期望得到的东西,在Debian Lenny(glibc 2.7) - 有一个例外 - 如果我指定AI_V4MAPPED没有AI_ALL,并且我查找的主机名有CNAME指向A记录,我不会得到那些返回.如果AI_ALL还指定了它,或者主机名与A记录直接关联,则它可以正常工作.

我不知道为什么 - 也许这是一个glibc错误?

这是我的测试程序:

#include 
#include 
#include 
#include 
#include 

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;
}

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有