Hi/2. Bruno Haible wrote: > KO Myung-Hun wrote: >> These are the patches to support AI_NUMERICSERV and AI_NUMERICHOST flag >> to getaddrinfo(). >> >> Review, please... >> >> [PATCH 1/2] getaddrinfo: Add AI_NUMERICSERV to the supported flags >> [PATCH 2/2] getaddrinfo: Add AI_NUMERICHOST flag support > > Your patches don't contain actual portable support for these flags > (on platforms where the native function does not implement it). > > POSIX [1] specifies the meaning of these two flags. So, if you encountered > a program which uses them, that is OK and I have no objection to Gnulib > supporting them. > > But the way to do so is in several steps, for each of the flags: > 1) Prepare a patch to tests/test-getaddrinfo.c that verifies the behaviour > of the flag. > 2) Send us this patch, so that we can run the modified test on many > platforms (including native Windows). > Also, run the modified test yourself, on OS/2. > 3) Then it will be clear which parts of lib/getaddrinfo.c need to be > extended. > > Bruno > > [1] > https://pubs.opengroup.org/onlinepubs/9799919799/functions/getaddrinfo.html >
Done. -- KO Myung-Hun Korean OS/2 User Community : https://www.os2.kr/
From e9de288c29df326e552f70de269192494bc2d57a Mon Sep 17 00:00:00 2001 From: KO Myung-Hun <komh78@gmail.com> Date: Mon, 10 Feb 2025 20:39:05 +0900 Subject: [PATCH v2] getaddrinfo: Supports AI_NUMERICHOST and AI_NUMERICSERV flags * lib/getaddrinfo.c (getaddrinfo): Add AI_NUMERICHOST and AI_NUMERICSERV as supported flags. * lib/netdb.in.h: Define AI_NUMERICHOST if not defined yet. * modules/getaddrinfo (Depends-on): Add inet_pton module. * tests/test-getaddrinfo.c: Add tests for AI_NUMERICHOST and AI_NUMERICSERV flags. --- lib/getaddrinfo.c | 26 +++++++++++++++++++++++++- lib/netdb.in.h | 2 +- modules/getaddrinfo | 1 + tests/test-getaddrinfo.c | 34 ++++++++++++++++++++++++++-------- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c index cd045c5121..03a93f311d 100644 --- a/lib/getaddrinfo.c +++ b/lib/getaddrinfo.c @@ -200,12 +200,14 @@ getaddrinfo (const char *restrict nodename, struct addrinfo addrinfo; struct sockaddr_in6 sockaddr_in6; }; + struct in6_addr addr6; # endif # if HAVE_IPV4 struct v4_pair { struct addrinfo addrinfo; struct sockaddr_in sockaddr_in; }; + struct in_addr addr4; # endif # ifdef WINDOWS_NATIVE @@ -213,7 +215,8 @@ getaddrinfo (const char *restrict nodename, return getaddrinfo_ptr (nodename, servname, hints, res); # endif - if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) + if (hints && (hints->ai_flags & + ~(AI_CANONNAME|AI_PASSIVE|AI_NUMERICHOST|AI_NUMERICSERV))) /* FIXME: Support more flags. */ return EAI_BADFLAGS; @@ -237,6 +240,26 @@ getaddrinfo (const char *restrict nodename, # endif } + if (hints && (hints->ai_flags & AI_NUMERICHOST)) + { + int valid = 0; + +# ifdef HAVE_IPV6 + valid |= !valid && + (hints->ai_family == AF_INET6 || + hints->ai_family == AF_UNSPEC) && + inet_pton (AF_INET6, nodename, &addr6) == 1; +# endif +# ifdef HAVE_IPV4 + valid |= !valid && + (hints->ai_family == AF_INET || + hints->ai_family == AF_UNSPEC) && + inet_pton (AF_INET, nodename, &addr4) == 1; +# endif + if (!valid) + return EAI_NONAME; + } + if (servname) { struct servent *se = NULL; @@ -261,6 +284,7 @@ getaddrinfo (const char *restrict nodename, port = se->s_port; } + /* FIXME: Assume gethostbyname can accept a numeric address string. */ /* FIXME: Use gethostbyname_r if available. */ he = gethostbyname (nodename); if (!he || he->h_addr_list[0] == NULL) diff --git a/lib/netdb.in.h b/lib/netdb.in.h index e8ba8f0978..9cad2d937a 100644 --- a/lib/netdb.in.h +++ b/lib/netdb.in.h @@ -103,7 +103,7 @@ struct addrinfo # define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */ # endif -# if 0 +# ifndef AI_NUMERICHOST # define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ # endif diff --git a/modules/getaddrinfo b/modules/getaddrinfo index b31d395635..265886e6c0 100644 --- a/modules/getaddrinfo +++ b/modules/getaddrinfo @@ -13,6 +13,7 @@ extensions gettext-h [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1 || test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1] gnulib-i18n [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1 || test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1] inet_ntop [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1] +inet_pton [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1] snprintf [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1] bool [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1] strdup [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1] diff --git a/tests/test-getaddrinfo.c b/tests/test-getaddrinfo.c index 968e0052dc..b11a2c6140 100644 --- a/tests/test-getaddrinfo.c +++ b/tests/test-getaddrinfo.c @@ -60,7 +60,7 @@ SIGNATURE_CHECK (getaddrinfo, int, (char const *, char const *, #endif static int -simple (char const *host, char const *service) +simple (char const *host, char const *service, int flags) { char buf[BUFSIZ]; static int skip = 0; @@ -78,11 +78,11 @@ simple (char const *host, char const *service) /* This initializes "hints" but does not use it. Is there a reason for this? If so, please fix this comment. */ memset (&hints, 0, sizeof (hints)); - hints.ai_flags = AI_CANONNAME; + hints.ai_flags = AI_CANONNAME | flags; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - res = getaddrinfo (host, service, NULL, &ai0); + res = getaddrinfo (host, service, &hints, &ai0); err = errno; dbgprintf ("res %d: %s\n", res, gai_strerror (res)); @@ -101,7 +101,7 @@ simple (char const *host, char const *service) /* IRIX reports EAI_NONAME for "https". Don't fail the test merely because of this. */ if (res == EAI_NONAME) - return 0; + return (flags & (AI_NUMERICHOST | AI_NUMERICSERV)) ? 2 : 0; /* Solaris reports EAI_SERVICE for "http" and "https". Don't fail the test merely because of this. */ if (res == EAI_SERVICE) @@ -166,13 +166,31 @@ simple (char const *host, char const *service) #define SERV3 "http" #define HOST4 "google.org" #define SERV4 "ldap" +#ifdef HAVE_IPV6 +#define NUMERICHOSTV6 "2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF" +#endif +#ifdef HAVE_IPV4 +#define NUMERICHOSTV4 "1.2.3.4" +#endif +#define NUMERICSERV "54321" int main (void) { (void) gl_sockets_startup (SOCKETS_1_1); - return simple (HOST1, SERV1) - + simple (HOST2, SERV2) - + simple (HOST3, SERV3) - + simple (HOST4, SERV4); + return simple (HOST1, SERV1, 0) + + simple (HOST2, SERV2, 0) + + simple (HOST3, SERV3, 0) + + simple (HOST4, SERV4, 0) +#ifdef HAVE_IPV6 + + simple (NUMERICHOSTV6, NUMERICSERV, AI_NUMERICHOST | AI_NUMERICSERV) + + !(simple (HOST1, NULL, AI_NUMERICHOST) == 2) + + !(simple (NULL, SERV1, AI_NUMERICSERV) == 2) +#endif +#ifdef HAVE_IPV4 + + simple (NUMERICHOSTV4, NUMERICSERV, AI_NUMERICHOST | AI_NUMERICSERV) + + !(simple (HOST1, NULL, AI_NUMERICHOST) == 2) + + !(simple (NULL, SERV1, AI_NUMERICSERV) == 2) +#endif + ; } -- 2.42.0