From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2206) id 4BFCB3858415; Tue, 1 Mar 2022 02:41:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4BFCB3858415 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Siddhesh Poyarekar To: glibc-cvs@sourceware.org Subject: [glibc/siddhesh/gai-cleanup2] gaih_inet: Simplify canon name resolution X-Act-Checkin: glibc X-Git-Author: Siddhesh Poyarekar X-Git-Refname: refs/heads/siddhesh/gai-cleanup2 X-Git-Oldrev: 878e14b58f8d70addb5a77c0d906a29c1195acd7 X-Git-Newrev: 84fc40f6b2dea9e0b455675ea9123d03699830ef Message-Id: <20220301024107.4BFCB3858415@sourceware.org> Date: Tue, 1 Mar 2022 02:41:07 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Mar 2022 02:41:07 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=84fc40f6b2dea9e0b455675ea9123d03699830ef commit 84fc40f6b2dea9e0b455675ea9123d03699830ef Author: Siddhesh Poyarekar Date: Mon Feb 28 19:00:23 2022 +0530 gaih_inet: Simplify canon name resolution Simplify logic for allocation of canon to remove the canonbuf variable; canon now always points to an allocated block. Also pull the canon name set into a separate function. Signed-off-by: Siddhesh Poyarekar Diff: --- sysdeps/posix/getaddrinfo.c | 109 +++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 43a8c7e266..ea3fa76748 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -336,7 +336,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, pat = &((*pat)->next); \ if (localcanon != NULL && canon == NULL) \ { \ - canonbuf = __strdup (localcanon); \ + char *canonbuf = __strdup (localcanon); \ if (canonbuf == NULL) \ { \ __resolv_context_put (res_ctx); \ @@ -768,6 +768,38 @@ simple_gethostbyname (const char *name, const struct addrinfo *req, return -EAI_NODATA; } +static int +process_canonname (const struct addrinfo *req, const char *orig_name, + char **canonp) +{ + char *canon = *canonp; + + if ((req->ai_flags & AI_CANONNAME) != 0) + { + bool do_idn = req->ai_flags & AI_CANONIDN; + if (do_idn) + { + char *out; + int rc = __idna_from_dns_encoding (canon ?: orig_name, &out); + if (rc == 0) + { + free (canon); + canon = out; + } + else if (rc == EAI_IDN_ENCODE) + /* Use the punycode name as a fallback. */ + do_idn = false; + else + return -rc; + } + if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL) + return -EAI_MEMORY; + } + + *canonp = canon; + return 0; +} + static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, @@ -778,7 +810,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_addrtuple *at = NULL; bool got_ipv6 = false; - const char *canon = NULL; + char *canon = NULL; const char *orig_name = name; /* Reserve stack memory for the scratch buffer in the getaddrinfo @@ -790,7 +822,6 @@ gaih_inet (const char *name, const struct gaih_service *service, return rc; bool malloc_name = false; - char *canonbuf = NULL; int result = 0; struct gaih_lookup_result res = {0}; struct scratch_buffer resbuf; @@ -815,7 +846,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else if (res.at != NULL) { at = res.at; - canon = canonbuf = at->name; + canon = at->name; goto process_list; } @@ -839,12 +870,14 @@ gaih_inet (const char *name, const struct gaih_service *service, else if (res.at != NULL) { at = res.at; - canon = canonbuf = at->name; + canon = at->name; got_ipv6 = res.got_ipv6; goto process_list; } #endif + /* For NSS lookups, use PAT to track the end of the tuple list so that + multiple lookups append to the end of the latest list. */ struct gaih_addrtuple **pat = &at; int no_data = 0; int no_inet6_data = 0; @@ -920,7 +953,16 @@ gaih_inet (const char *name, const struct gaih_service *service, no_data = 1; if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) - canon = (*pat)->name; + { + char *canonbuf = __strdup ((*pat)->name); + if (canonbuf == NULL) + { + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto free_and_return; + } + canon = canonbuf; + } while (*pat != NULL) { @@ -1004,7 +1046,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) { - canonbuf = getcanonname (nip, at, name); + char *canonbuf = getcanonname (nip, at, name); if (canonbuf == NULL) { __resolv_context_put (res_ctx); @@ -1052,8 +1094,8 @@ gaih_inet (const char *name, const struct gaih_service *service, { at = NULL; pat = &at; - free (canonbuf); - canon = canonbuf = NULL; + free (canon); + canon = NULL; } nip++; @@ -1121,6 +1163,10 @@ gaih_inet (const char *name, const struct gaih_service *service, } { + /* Set up the canonical name if we need it. */ + if ((result = process_canonname (req, orig_name, &canon)) != 0) + goto free_and_return; + struct gaih_addrtuple *at2 = at; size_t socklen; sa_family_t family; @@ -1130,48 +1176,6 @@ gaih_inet (const char *name, const struct gaih_service *service, */ while (at2 != NULL) { - /* Only the first entry gets the canonical name. */ - if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0) - { - if (canon == NULL) - /* If the canonical name cannot be determined, use - the passed in string. */ - canon = orig_name; - - bool do_idn = req->ai_flags & AI_CANONIDN; - if (do_idn) - { - char *out; - int rc = __idna_from_dns_encoding (canon, &out); - if (rc == 0) - canon = out; - else if (rc == EAI_IDN_ENCODE) - /* Use the punycode name as a fallback. */ - do_idn = false; - else - { - result = -rc; - goto free_and_return; - } - } - if (!do_idn) - { - if (canonbuf != NULL) - /* We already allocated the string using malloc, but - the buffer is now owned by canon. */ - canonbuf = NULL; - else - { - canon = __strdup (canon); - if (canon == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - } - } - } - family = at2->family; if (family == AF_INET6) { @@ -1194,7 +1198,6 @@ gaih_inet (const char *name, const struct gaih_service *service, ai = *pai = malloc (sizeof (struct addrinfo) + socklen); if (ai == NULL) { - free ((char *) canon); result = -EAI_MEMORY; goto free_and_return; } @@ -1253,7 +1256,7 @@ gaih_inet (const char *name, const struct gaih_service *service, free_and_return: if (malloc_name) free ((char *) name); - free (canonbuf); + free (canon); gaih_lookup_result_free (&res); scratch_buffer_free (&resbuf);