Я знакомлюсь с IPv6 и читал, что адреса IPv4 можно сопоставить с IPv6 с помощью префикса ::ffff:
. Это заставило меня задуматься о том, относится ли адрес ::ffff:127.0.0.1
к localhost
, поэтому я написал простую программу на C, которая использует getaddrinfo()
и IN6_IS_ADDR_LOOPBACK
a> макрос для проверки, является ли возвращаемый адрес петлевым.
Я протестировал программу с ::1
и другими вариациями петлевого адреса, и, как и ожидалось, программа говорит, что это петлевой адрес. Но, к моему удивлению, когда я пробую ::ffff:127.0.0.1
, программа говорит, что это не так! Как это возможно? Я что-то упустил?
Вот упрощенная версия исходного кода моей программы:
struct addrinfo hints, *servinfo;
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
/* hostname_or_ip is entered from the command line */
if ( (rv = getaddrinfo(hostname_or_ip, NULL, &hints, &servinfo)) != 0) {
exit(1);
}
struct addrinfo *p = servinfo;
struct sockaddr_in6 *h = (struct sockaddr_in6 *) p->ai_addr;
int is_loopback = IN6_IS_ADDR_LOOPBACK(&h->sin6_addr) ? 1 : 0;
printf("%s\n", is_loopback ? "YES!" : "NO!");