|
|
Message-ID: <89b25567-5887-80ee-bfac-58b25e7a9b45@bell-sw.com>
Date: Thu, 27 Feb 2020 13:17:20 +0300
From: Alexander Scherbatiy <alexander.scherbatiy@...l-sw.com>
To: musl@...ts.openwall.com
Subject: getaddrinfo(3) with AI_V4MAPPED and AI_ALL flags
Hello,
When I call getaddrinfo() with different families, SOCK_STREAM socktype,
IPPROTO_TCP protocol, and AI_PASSIVE flag the result is the same on the
Alpine Linux 3.11.3 and Ubuntu 19.10 (the code sample is below):
----------------
family: AF_UNSPEC, flags: AI_PASSIVE
AF_INET IPv4 addr '0.0.0.0'
AF_INET6 IPv6 addr '::'
family: AF_INET, flags: AI_PASSIVE
AF_INET IPv4 addr '0.0.0.0'
family: AF_INET6, flags: AI_PASSIVE
AF_INET6 IPv6 addr '::'
----------------
When I use getaddrinfo() with AF_INET6 family and additional AI_V4MAPPED
| AI_ALL (return both IPv6 and IPv4-mapped IPv6 addresses) flags the
result on Ubuntu contains only IPv6 '::' address:
----------------
family: AF_INET6, flags: AI_PASSIVE | AI_V4MAPPED | AI_ALL
AF_INET6 IPv6 addr '::'
----------------
whereas the result on Alpine Linux contains both IPv4-mapped IPv6
addresses '::ffff:0.0.0.0' and IPv6 '::'
----------------
family: AF_INET6, flags: AI_PASSIVE | AI_V4MAPPED | AI_ALL
AF_INET6 IPv6 addr '::ffff:0.0.0.0'
AF_INET6 IPv6 addr '::'
----------------
Is it expected behavior?
I use Alpine Linux 3.11.3 from docker with musl libc (x86_64).
Thanks,
Alexander.
Code sample:
------------- addr_info.c -----------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
void sockaddr_show(struct sockaddr *sa) {
int family = sa->sa_family;
if (family == AF_INET) {
char buff[INET_ADDRSTRLEN];
struct sockaddr_in server_addr = *((struct sockaddr_in*) sa);
inet_ntop(AF_INET, &server_addr.sin_addr, buff, INET_ADDRSTRLEN);
printf("AF_INET IPv4 addr '%s'\n", buff);
} else if (family == AF_INET6) {
char buff[INET_ADDRSTRLEN];
struct sockaddr_in6 server_addr = *((struct sockaddr_in6*) sa);
inet_ntop(AF_INET6, &server_addr.sin6_addr, buff,
INET6_ADDRSTRLEN);
printf("AF_INET6 IPv6 addr '%s'\n", buff);
} else {
printf("family: %d\n", family);
}
}
void show_addr_info(int family, int flags) {
char* hostname = NULL;
char* service = "33833";
struct addrinfo hints;
struct addrinfo *result, *rp;
memset (&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = flags;
int res = getaddrinfo(hostname, service, &hints, &result);
for (rp = result; rp != NULL; rp = rp->ai_next) {
sockaddr_show(rp->ai_addr);
}
printf("\n");
}
int main(void) {
printf("family: AF_UNSPEC, flags: AI_PASSIVE\n");
show_addr_info(AF_UNSPEC, AI_PASSIVE);
printf("family: AF_INET, flags: AI_PASSIVE\n");
show_addr_info(AF_INET, AI_PASSIVE);
printf("family: AF_INET6, flags: AI_PASSIVE\n");
show_addr_info(AF_INET6, AI_PASSIVE);
printf("family: AF_INET6, flags: AI_PASSIVE | AI_V4MAPPED |
AI_ALL\n");
show_addr_info(AF_INET6, AI_PASSIVE | AI_V4MAPPED | AI_ALL);
return EXIT_SUCCESS;
}
--------------------------------
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.