From 60e0b01e893137efebc278e6da33f6199fc7a863 Mon Sep 17 00:00:00 2001 From: Robin Hack Date: Mon, 7 Sep 2015 08:06:52 +0200 Subject: [PATCH] nwrap: Add AI_NUMERICHOST flag support for getaddrinfo function. Solves bug 11477. Signed-off-by: Robin Hack --- src/nss_wrapper.c | 6 +++++ tests/test_getaddrinfo.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/nss_wrapper.c b/src/nss_wrapper.c index 28c23d8..d3395d7 100644 --- a/src/nss_wrapper.c +++ b/src/nss_wrapper.c @@ -3895,6 +3895,12 @@ static int nwrap_getaddrinfo(const char *node, return ret; } + if ((hints != NULL) && (ret == EAI_NONAME) + && (hints->ai_flags & AI_NUMERICHOST)) + { + return ret; + } + if (hints == NULL) { hints = &default_hints; } diff --git a/tests/test_getaddrinfo.c b/tests/test_getaddrinfo.c index 492913b..e464a2b 100644 --- a/tests/test_getaddrinfo.c +++ b/tests/test_getaddrinfo.c @@ -371,6 +371,74 @@ static void test_nwrap_getaddrinfo_ipv6(void **state) freeaddrinfo(res); } +/* This test can be tricky. It can pass against raw glibc. + * Then test if nss_wrapper is enabled is present. + */ +static void test_nwrap_getaddrinfo_flags_ai_numerichost(void **state) +{ + struct addrinfo hints; + struct addrinfo *res; + struct sockaddr_in *sinp; + struct sockaddr_in6 *sin6p; + char ip6[INET6_ADDRSTRLEN]; + char *ip; + int rc; + + (void) state; /* unused */ + + /* IPv4 */ + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + + rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); + assert_int_equal(rc, 0); + + rc = getaddrinfo(NULL, "echo", &hints, &res); + assert_int_equal(rc, 0); + + /* Must fail because string instead of ip addr given */ + rc = getaddrinfo("magrathea.galaxy.site", NULL, &hints, &res); + assert_int_equal(rc, EAI_NONAME); + + rc = getaddrinfo("", NULL, &hints, &res); + assert_int_equal(rc, EAI_NONAME); + + rc = getaddrinfo("fail.me", "echo", &hints, &res); + assert_int_equal(rc, EAI_NONAME); + + hints.ai_family = AF_INET6; + rc = getaddrinfo("::1", NULL, &hints, &res); + assert_int_equal(rc, 0); + + rc = getaddrinfo("hello.world.example.dot.net", NULL, &hints, &res); + assert_int_equal(rc, EAI_NONAME); + + + /* Actually this just check if nss_wrapper is enabled. */ + hints.ai_family = AF_INET; + rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); + assert_int_equal(rc, 0); + assert_non_null(res->ai_canonname); + assert_string_equal(res->ai_canonname, "magrathea.galaxy.site"); + + /* Should be directly handled by glibc */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; /* For wildcard IP address */ + hints.ai_family = AF_INET6; + rc = getaddrinfo(NULL, "echo", &hints, &res); + assert_int_equal(rc, 0); + + /* DANGEROUS! BEWARE! FIRE! hints changed here! */ + hints.ai_flags = 0; + rc = getaddrinfo(NULL, "echo", &hints, &res); + assert_int_equal(rc, 0); + + freeaddrinfo(res); +} + int main(void) { int rc; @@ -383,6 +451,7 @@ int main(void) { unit_test(test_nwrap_getaddrinfo_null), unit_test(test_nwrap_getaddrinfo_dot), unit_test(test_nwrap_getaddrinfo_ipv6), + unit_test(test_nwrap_getaddrinfo_flags_ai_numerichost), }; rc = run_tests(tests); -- 1.9.3