From patchwork Tue Aug 3 21:29:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 44565 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 025D8384F014 for ; Tue, 3 Aug 2021 21:33:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 025D8384F014 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1628026438; bh=t64dqFSZhayjTngTeHwHEPUM3MS+UB0vv0e3ISTzRkI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=FUOqUpIEeSTpwyrYvJXSMk0lzFzuFaBF7y0xEXEONSm63hqqRz8fcw+KYRiGS6fmJ sJFhmCSG6EnQryWZpPr5KOKSd7M7qriXye7BDui9VsDjlqIPaiu89IutsW17ZwlDHi ugSO+IC5in8EZov+qKmoldVA+qvkK9qo+5UZzZIA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from buffalo.birch.relay.mailchannels.net (buffalo.birch.relay.mailchannels.net [23.83.209.24]) by sourceware.org (Postfix) with ESMTPS id 0C8FE384F014 for ; Tue, 3 Aug 2021 21:29:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0C8FE384F014 X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id D521248150B for ; Tue, 3 Aug 2021 21:29:40 +0000 (UTC) Received: from pdx1-sub0-mail-a4.g.dreamhost.com (100-96-13-120.trex.outbound.svc.cluster.local [100.96.13.120]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 82296482501 for ; Tue, 3 Aug 2021 21:29:40 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a4.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.13.120 (trex/6.3.3); Tue, 03 Aug 2021 21:29:40 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Power-Exultant: 533138f8203a1f67_1628026180771_1465703800 X-MC-Loop-Signature: 1628026180771:2189012621 X-MC-Ingress-Time: 1628026180770 Received: from pdx1-sub0-mail-a4.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a4.g.dreamhost.com (Postfix) with ESMTP id 44DFE8AAA8 for ; Tue, 3 Aug 2021 14:29:40 -0700 (PDT) Received: from rhbox.redhat.com (unknown [1.186.101.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a4.g.dreamhost.com (Postfix) with ESMTPSA id 3D7DD8AAAA for ; Tue, 3 Aug 2021 14:29:38 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a4 To: libc-alpha@sourceware.org Subject: [PATCH 5/5] gaih_inet: Make process_list label into a function Date: Wed, 4 Aug 2021 02:59:19 +0530 Message-Id: <20210803212919.3059194-6-siddhesh@sourceware.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210803212919.3059194-1-siddhesh@sourceware.org> References: <20210803212919.3059194-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3494.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Siddhesh Poyarekar via Libc-alpha From: Siddhesh Poyarekar Reply-To: Siddhesh Poyarekar Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" process_list is the final operation in gaih_inet where the result is written out. Factor it out into a separate function and call it at the end if there have been no errors. Rename the free_and_return label to done and use it to jump to the end of gaih_inet, where process_list is called if return is non-zero. This change makes the code more linear and slightly clearer to follow. This needs still more rework to make the function simpler to understand. --- sysdeps/posix/getaddrinfo.c | 311 +++++++++++++++++------------------- 1 file changed, 149 insertions(+), 162 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 220cd41cde..3afac87fa2 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -256,7 +256,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_MEMORY; \ - goto free_and_return; \ + goto done; \ } \ } \ if (status == NSS_STATUS_NOTFOUND \ @@ -266,7 +266,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto done; \ } \ if (h_errno == TRY_AGAIN) \ no_data = EAI_AGAIN; \ @@ -279,7 +279,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto done; \ } \ *pat = addrmem; \ \ @@ -290,7 +290,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto done; \ } \ canon = canonbuf; \ } \ @@ -323,6 +323,123 @@ getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name) return __strdup (name); } +static int +process_list (const struct addrinfo *req, struct gaih_addrtuple *at, + struct gaih_servtuple *st, const char *canon, bool canon_alloc, + bool got_ipv6, struct addrinfo **pai, unsigned int *naddrs) +{ + struct gaih_servtuple *st2; + struct gaih_addrtuple *at2 = at; + size_t socklen; + sa_family_t family; + + /* + buffer is the size of an unformatted IPv6 address in printable format. + */ + for (at2 = at; at2 != NULL; at2 = at2->next) + { + /* Only the first entry gets the canonical name. */ + if (at2 == at && (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, &out); + if (rc == 0) + canon = out; + else if (rc == EAI_IDN_ENCODE) + /* Use the punycode name as a fallback. */ + do_idn = false; + else + return -rc; + } + if (!do_idn) + { + if (!canon_alloc) + { + canon = __strdup (canon); + if (canon == NULL) + return -EAI_MEMORY; + } + } + } + + family = at2->family; + if (family == AF_INET6) + { + socklen = sizeof (struct sockaddr_in6); + + /* If we looked up IPv4 mapped address discard them here if + the caller isn't interested in all address and we have + found at least one IPv6 address. */ + if (got_ipv6 + && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED + && IN6_IS_ADDR_V4MAPPED (at2->addr)) + continue; + } + else + socklen = sizeof (struct sockaddr_in); + + for (st2 = st; st2 != NULL; st2 = st2->next) + { + struct addrinfo *ai; + ai = *pai = malloc (sizeof (struct addrinfo) + socklen); + if (ai == NULL) + { + free ((char *) canon); + return -EAI_MEMORY; + } + + ai->ai_flags = req->ai_flags; + ai->ai_family = family; + ai->ai_socktype = st2->socktype; + ai->ai_protocol = st2->protocol; + ai->ai_addrlen = socklen; + ai->ai_addr = (void *) (ai + 1); + + /* We only add the canonical name once. */ + ai->ai_canonname = (char *) canon; + canon = NULL; + +#ifdef _HAVE_SA_LEN + ai->ai_addr->sa_len = socklen; +#endif /* _HAVE_SA_LEN */ + ai->ai_addr->sa_family = family; + + /* In case of an allocation error the list must be NULL + terminated. */ + ai->ai_next = NULL; + + if (family == AF_INET6) + { + struct sockaddr_in6 *sin6p = + (struct sockaddr_in6 *) ai->ai_addr; + + sin6p->sin6_port = st2->port; + sin6p->sin6_flowinfo = 0; + memcpy (&sin6p->sin6_addr, + at2->addr, sizeof (struct in6_addr)); + sin6p->sin6_scope_id = at2->scopeid; + } + else + { + struct sockaddr_in *sinp = + (struct sockaddr_in *) ai->ai_addr; + sinp->sin_port = st2->port; + memcpy (&sinp->sin_addr, + at2->addr, sizeof (struct in_addr)); + memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); + } + + pai = &(ai->ai_next); + } + + ++*naddrs; + } + return 0; +} + static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, @@ -479,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else { result = -EAI_ADDRFAMILY; - goto free_and_return; + goto done; } if (req->ai_flags & AI_CANONNAME) @@ -507,7 +624,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else { result = -EAI_ADDRFAMILY; - goto free_and_return; + goto done; } if (scope_delim != NULL @@ -516,7 +633,7 @@ gaih_inet (const char *name, const struct gaih_service *service, &at->scopeid) != 0) { result = -EAI_NONAME; - goto free_and_return; + goto done; } if (req->ai_flags & AI_CANONNAME) @@ -555,7 +672,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (!scratch_buffer_grow (tmpbuf)) { result = -EAI_MEMORY; - goto free_and_return; + goto done; } } @@ -568,7 +685,7 @@ gaih_inet (const char *name, const struct gaih_service *service, (req, AF_INET, h, &addrmem)) { result = -EAI_MEMORY; - goto free_and_return; + goto done; } *pat = addrmem; } @@ -578,7 +695,7 @@ gaih_inet (const char *name, const struct gaih_service *service, result = -EAI_NODATA; else result = -EAI_NONAME; - goto free_and_return; + goto done; } } else @@ -592,10 +709,13 @@ gaih_inet (const char *name, const struct gaih_service *service, The name is known, though. */ result = -EAI_NODATA; - goto free_and_return; + goto done; } - goto process_list; + if (at->family == AF_UNSPEC) + result = -EAI_NONAME; + + goto done; } #ifdef USE_NSCD @@ -619,7 +739,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (addrmem == NULL) { result = -EAI_MEMORY; - goto free_and_return; + goto done; } struct gaih_addrtuple *addrfree = addrmem; @@ -654,7 +774,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (canonbuf == NULL) { result = -EAI_MEMORY; - goto free_and_return; + goto done; } canon = (*pat)->name = canonbuf; } @@ -687,16 +807,13 @@ gaih_inet (const char *name, const struct gaih_service *service, free (air); if (at->family == AF_UNSPEC) - { - result = -EAI_NONAME; - goto free_and_return; - } + result = -EAI_NONAME; - goto process_list; + goto done; } else if (err == 0) /* The database contains a negative entry. */ - goto free_and_return; + goto done; else if (__nss_not_use_nscd_hosts == 0) { if (h_errno == NETDB_INTERNAL && errno == ENOMEM) @@ -706,7 +823,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else result = -EAI_SYSTEM; - goto free_and_return; + goto done; } } #endif @@ -755,7 +872,7 @@ gaih_inet (const char *name, const struct gaih_service *service, { __resolv_context_put (res_ctx); result = -EAI_MEMORY; - goto free_and_return; + goto done; } } @@ -854,7 +971,7 @@ gaih_inet (const char *name, const struct gaih_service *service, { __resolv_context_put (res_ctx); result = -EAI_MEMORY; - goto free_and_return; + goto done; } canon = canonbuf; } @@ -903,7 +1020,7 @@ gaih_inet (const char *name, const struct gaih_service *service, && h_errno == NETDB_INTERNAL) { result = -EAI_SYSTEM; - goto free_and_return; + goto done; } if (no_data != 0 && no_inet6_data != 0) @@ -916,16 +1033,12 @@ gaih_inet (const char *name, const struct gaih_service *service, is known, though. */ result = -EAI_NODATA; - goto free_and_return; + goto done; } } - process_list: if (at->family == AF_UNSPEC) - { - result = -EAI_NONAME; - goto free_and_return; - } + result = -EAI_NONAME; } else { @@ -955,142 +1068,16 @@ gaih_inet (const char *name, const struct gaih_service *service, } } - { - struct gaih_servtuple *st2; - struct gaih_addrtuple *at2 = at; - size_t socklen; - sa_family_t family; - - /* - buffer is the size of an unformatted IPv6 address in printable format. - */ - 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) - { - socklen = sizeof (struct sockaddr_in6); - - /* If we looked up IPv4 mapped address discard them here if - the caller isn't interested in all address and we have - found at least one IPv6 address. */ - if (got_ipv6 - && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED - && IN6_IS_ADDR_V4MAPPED (at2->addr)) - goto ignore; - } - else - socklen = sizeof (struct sockaddr_in); - - for (st2 = st; st2 != NULL; st2 = st2->next) - { - struct addrinfo *ai; - ai = *pai = malloc (sizeof (struct addrinfo) + socklen); - if (ai == NULL) - { - free ((char *) canon); - result = -EAI_MEMORY; - goto free_and_return; - } - - ai->ai_flags = req->ai_flags; - ai->ai_family = family; - ai->ai_socktype = st2->socktype; - ai->ai_protocol = st2->protocol; - ai->ai_addrlen = socklen; - ai->ai_addr = (void *) (ai + 1); - - /* We only add the canonical name once. */ - ai->ai_canonname = (char *) canon; - canon = NULL; - -#ifdef _HAVE_SA_LEN - ai->ai_addr->sa_len = socklen; -#endif /* _HAVE_SA_LEN */ - ai->ai_addr->sa_family = family; - - /* In case of an allocation error the list must be NULL - terminated. */ - ai->ai_next = NULL; - - if (family == AF_INET6) - { - struct sockaddr_in6 *sin6p = - (struct sockaddr_in6 *) ai->ai_addr; - - sin6p->sin6_port = st2->port; - sin6p->sin6_flowinfo = 0; - memcpy (&sin6p->sin6_addr, - at2->addr, sizeof (struct in6_addr)); - sin6p->sin6_scope_id = at2->scopeid; - } - else - { - struct sockaddr_in *sinp = - (struct sockaddr_in *) ai->ai_addr; - sinp->sin_port = st2->port; - memcpy (&sinp->sin_addr, - at2->addr, sizeof (struct in_addr)); - memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); - } - - pai = &(ai->ai_next); - } - - ++*naddrs; - - ignore: - at2 = at2->next; - } - } +done: + if (result == 0) + result = process_list (req, at, st, canon ?: orig_name, canonbuf != NULL, + got_ipv6, pai, naddrs); - free_and_return: if (malloc_name) free ((char *) name); free (addrmem); - free (canonbuf); + if (result != 0) + free (canonbuf); return result; }