문제

getAddrinfo 호출에는 많은 흥미로운 깃발이 있습니다. AI_V4MAPPED 플래그의 목적이 무엇인지 궁금합니다. 시스템이 없음 시스템에서는이 플래그를 설정할 때 예상대로 :: ffff : nnnn 양식 주소를 생산할 수있는 getAddrinfo를 얻을 수있는 것 같습니다. 내가 잘못된 것을 기대하고 있습니까? 나는 버그를보고 있습니까?

Particlar에서 AF_INET6 제품군 주소를 요청하고 AI_V4MAPPE를 지정하면 DNS A (IPv4 주소) 레코드 만있는 호스트의 경우 :: FFFF : NNNN 주소를 확인할 것으로 예상됩니다. 또한 AI_ALL을 지정하면 호스트의 DNS AAAA (IPv6 주소) 레코드와 DNS A Records :: FFFF : NNNN Form을 모두 얻을 것으로 기대합니다.

다시, 나는 여기서 모든 잘못된 것을 기대하고 있습니까?

Fedora 11 -GLIBC 2.10.1 및 OS X 10.4에서 이것을 테스트했습니다.

도움이 되었습니까?

해결책

나는 당신이 기대하는 것을 정확하게 얻습니다. 데비안 레니 (Glibc 2.7) - 한 가지 예외로 - 내가 지정하면 AI_V4MAPPED 없이 AI_ALL, 그리고 내가 찾는 호스트 이름에는 레코드를 가리키는 cname이 있습니다. 만약 잘 작동합니다 AI_ALL 또한 지정되거나 호스트 이름이 레코드와 직접 연관되어 있는지 여부.

왜 그런지 모르겠습니다 - 아마도 그게 glibc 버그일까요?

내 테스트 프로그램은 다음과 같습니다.

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

다른 팁

내 경험상 AI_V4MAPPED Mac OS X 10.6에서는 작동하지 않습니다. 당신이 제공하는 경우 hints.ai_family = AF_INET6 그리고 hints.ai_flags = AI_V4MAPPED 항상 돌아올 것입니다 EAI_NONAME, 그리고 gai_strerror() "Nodename 또는 Servname 제공 또는 알려지지 않은"인쇄.

OS X 10.7에서 제대로 작동합니다.

페도라에도 불구하고 누군가를 돕는 경우에 여기에 이것을 게시합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top