2009-09-10 12 views
6

La llamada getaddrinfo tiene muchas banderas interesantes. Me pregunto cuál es el propósito de la bandera AI_V4MAPPED. En ningún sistema, parece que soy capaz de obtener getaddrinfo para producir :: ffff: n.n.n.n las direcciones de formulario que esperaría cuando configuro este indicador. ¿Estoy esperando lo equivocado? ¿Estoy viendo errores?¿Cuál es el propósito de la bandera AI_V4MAPPED en getaddrinfo?

En particular, si solicito direcciones de familia AF_INET6 y especifico AI_V4MAPPED esperaría ver direcciones :: ffff: n.n.n.n para hosts que solo tienen registros de DNS A (dirección IPv4). Y generalmente también esperaría que si especificara AI_ALL obtendría los registros DNS AAAA (dirección IPv6) de un host y los registros DNS A en formato :: ffff: n.n.n.n.

De nuevo, ¿estoy esperando todas las cosas malas aquí?

He probado esto en Fedora 11 - glibc 2.10.1 y OS X 10.4.

Respuesta

6

puedo obtener exactamente lo que usted está esperando para obtener, en Debian Lenny (glibc 2.7) - con una excepción - si especifico AI_V4MAPPED sin AI_ALL, y el nombre de host Miro hacia arriba ha CNAME apuntando a registros A, I don' t obtener los devueltos. Funciona bien si también se especifica AI_ALL, o si el nombre de host está directamente asociado con los registros A.

No sé por qué, quizás sea un error glibc.

Aquí es mi programa de pruebas:

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

He estado investigando mucho más sobre esto. getaddrinfo parece estar plagado de cualquier cantidad de errores, en parte porque tiene muchos casos extraños para evitar el manejo incorrecto de las solicitudes AAAA. – Omnifarious

+0

Su respuesta es la más cercana a una respuesta real, por lo que obtiene el crédito de respuesta. – Omnifarious

+0

AI_V4MAPPED sin AI_ALL es un error glibc ver http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=503912 – unixman83

4

En mi experiencia, AI_V4MAPPED no funciona en Mac OS X 10.6. Si proporciona hints.ai_family = AF_INET6 y hints.ai_flags = AI_V4MAPPED, siempre devolverá EAI_NONAME, y gai_strerror() imprime "nombre de nodo o servidor proporcionado, o no conocido".

Funciona correctamente en OS X 10.7.

Publicando esto aquí en caso de que ayude a alguien, incluso si está en Fedora.

Cuestiones relacionadas