|
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.