Was ist der Zweck der AI_V4MAPPED Flagge in Getaddrinfo?
-
05-07-2019 - |
Frage
Der Getaddrinfo Anruf hat viele interessante Fahnen. Ich frage mich, was der Zweck der AI_V4MAPPED Flagge ist. In keinem System scheine ich in der Lage zu sein zu bekommen getaddrinfo :: ffff zu produzieren: n.n.n.n Form Adressen wie ich erwarten würde, wenn ich diesen Flag gesetzt. Erwarte ich die falsche Sache? Bin ich sehe Bugs?
In particlar, wenn ich für AF_INET6 Familie Adressen stellen und angeben AI_V4MAPPED würde ich erwarten :: ffff zu sehen: n.n.n.n Adressen für Hosts, die nur DNS-A (IPv4-Adresse) Datensätze. Und ich würde, dass im Allgemeinen erwarten, auch wenn ich AI_ALL angegeben, dass ich bekommen beide einen DNS-AAAA des Hosts (IPv6-Adresse) Aufzeichnungen und DNS-A-Einträge in :: ffff:. N.n.n.n Form
Auch hier bin ich hier all die falschen Dinge erwarten?
Ich habe das auf Fedora getestet. 11 - glibc 2.10.1 und OS X 10.4
Lösung
ich genau das, was Sie erwarten zu bekommen, auf Debian Lenny (2.7 glibc) - mit einer Ausnahme - wenn ich AI_V4MAPPED
ohne AI_ALL
angeben, und der Hostname ich nachschlagen hat bei A Aufzeichnungen CNAMEs zeigt, kann ich nicht erhalten diejenigen zurückgegeben. Es funktioniert gut, wenn AI_ALL
auch angegeben ist, oder wenn der Hostname direkt mit A-Einträgen verknüpft ist.
Ich weiß nicht, warum - vielleicht ist das ein glibc Fehler
Hier ist mein Testprogramm:
#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;
}
Andere Tipps
Nach meiner Erfahrung AI_V4MAPPED
funktioniert nicht auf Mac OS X 10.6. Wenn Sie hints.ai_family = AF_INET6
bieten und hints.ai_flags = AI_V4MAPPED
es wird immer EAI_NONAME
zurück und gai_strerror()
prints „nodename noch servname zur Verfügung gestellt, oder nicht bekannt“.
Es funktioniert auf OS X 10.7.
dieses Posting hier, falls es jemand hilft, auch wenn Sie auf Fedora sind.