From patchwork Tue Mar 8 10:07:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602844 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=egh0vkEK; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWHT2Q4lz9sGS for ; Tue, 8 Mar 2022 21:08:21 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2C1AA385780C for ; Tue, 8 Mar 2022 10:08:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C1AA385780C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734098; bh=J1XjTNs4pG+dtCXBuLduQEXBBou5Ky//lq0zrw6bCls=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=egh0vkEKvSqqjdaDuLfFR9pICpaMbio53yK50OuPLafhK14H476zLna+nsRwQP3of Q7AM10wxANN93BjBH5xaTLc/CeGeuCizus24vuWqxFiAR64yzwioIXk+Udn3ksaJMY Cxe2M/I6bOrKOtGkCE/eADCVLkqjyfo7mgXGDvaM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from blue.oak.relay.mailchannels.net (blue.oak.relay.mailchannels.net [23.83.215.20]) by sourceware.org (Postfix) with ESMTPS id 53D8F3858C83 for ; Tue, 8 Mar 2022 10:08:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 53D8F3858C83 Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id A942A6C2065; Tue, 8 Mar 2022 10:08:00 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 211A86C1D48; Tue, 8 Mar 2022 10:07:41 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734065; a=rsa-sha256; cv=none; b=u7tvttOkLvbEFHB6p2A/cS2JtEKb4TmnFtJ1k69gCwDrF6J0hvyeabesSJoyIVgp7DazaK SEeI1mF9kNIxw5ds9GaBcsfB9q7Xb1PKSM87RjwqSukqqQwSfwOYuWoOSkeCnFIgqWIVQ3 iJ8W/ZXXsBCiPc3q8+/RCnzEXNqRVOu3nKvvrf1DQo6jycH0pqsWODOd0MwWBN3EQeoi/o AisI1vRPY6AbaUvTifzY2cnR68I+7/+izpXWVJLVZQZQ9BkkM0nIln352tmR4ChD0Mpy91 lexFD1kjteUMtC9p/FOB5l6bNwqCmX0yATz2khHr/X0rcmlGb8qAN2322ze1Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734065; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J1XjTNs4pG+dtCXBuLduQEXBBou5Ky//lq0zrw6bCls=; b=yimjmt5bl+3ToP9E5c12xbjEGVBK8h1xD00N4BDIhPfiiHS7TP2H4wjMbqZxIWtl+bRDZc 7e83fcmA/22r1TcajbPNqk8Ezi4f1N9ss6hKRZiQP43SJU3Qh7DBHbCQH/DqoPdrq69XLo mkvuS5JA3IoCgTS2mHLDZkDzzKfm1R6lEGvGFutKS27079CRnXufwiBjLcZGpGRv3JGFDG cS8A7RomWhahHNbJ4BO82zAfYBqROOQneXoJ1tOZ4xP8nyS6KBcEXrkW1O+EX4AFXJB0HQ 7LXP4au8ksaYskUhqshiaPe03UToPcVgLjrh/UDtKQwv0lTgHA17bA3h0d8izQ== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-zzqcw; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.118.223.199 (trex/6.5.3); Tue, 08 Mar 2022 10:08:00 +0000 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGg4B7dz1Nj; Tue, 8 Mar 2022 02:07:39 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 01/12] Simplify allocations and fix merge and continue actions [BZ #28931] Date: Tue, 8 Mar 2022 15:37:06 +0530 Message-Id: <20220308100717.1006126-2-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Allocations for address tuples is currently a bit confusing because of the pointer chasing through PAT, making it hard to observe the sequence in which allocations have been made. Narrow scope of the pointer chasing through PAT so that it is only used where necessary. This also tightens actions behaviour with the hosts database in getaddrinfo to comply with the manual text. The "continue" action discards previous results and the "merge" action results in an immedate lookup failure. Consequently, chaining of allocations across modules is no longer necessary, thus opening up cleanup opportunities. A test has been added that checks some combinations to ensure that they work correctly. The "dns [SUCCESS=continue] dns" for example results in a segfault without this fix. Resolves: BZ #28931 Signed-off-by: Siddhesh Poyarekar --- nss/Makefile | 1 + nss/tst-nss-gai-actions.c | 242 ++++++++++++++++++++++++++++++++++++ sysdeps/posix/getaddrinfo.c | 142 +++++++++++++-------- 3 files changed, 333 insertions(+), 52 deletions(-) create mode 100644 nss/tst-nss-gai-actions.c diff --git a/nss/Makefile b/nss/Makefile index 552e5d03e1..43a0b9defe 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -78,6 +78,7 @@ tests += tst-nss-files-hosts-multi tests += tst-nss-files-hosts-getent tests += tst-nss-files-alias-leak tests += tst-nss-files-alias-truncated +tests += tst-nss-gai-actions endif # If we have a thread library then we can test cancellation against diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c new file mode 100644 index 0000000000..b5ba5f0138 --- /dev/null +++ b/nss/tst-nss-gai-actions.c @@ -0,0 +1,242 @@ +/* Test continue and merge NSS actions for getaddrinfo. + Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +enum +{ + ACTION_MERGE = 0, + ACTION_CONTINUE, +}; + +enum +{ + DB_FILES = 0, + DB_DNS, +}; + +struct test_params +{ + int db; + int action; + int family; + bool canon; +}; + +struct support_chroot *chroot_env; + +static void +prepare (int argc, char **argv) +{ + chroot_env = support_chroot_create + ((struct support_chroot_configuration) + { + .resolv_conf = "", + .hosts = "", + .host_conf = "multi on\n", + }); +} + +/* Create the /etc/hosts file from outside the chroot. */ +static void +write_hosts (void) +{ + const int count = 512; + + FILE *fp = xfopen (chroot_env->path_hosts, "w"); + fputs ("127.0.0.1 localhost localhost.localdomain\n" + "::1 localhost localhost.localdomain\n", + fp); + for (int i = 1; i < count; ++i) + fprintf (fp, "192.0.%d.%d gnu.org\n", (i / 256) & 0xff, i & 0xff); + xfclose (fp); +} + +static const char * +family_str (int family) +{ + switch (family) + { + case AF_UNSPEC: + return "AF_UNSPEC"; + case AF_INET: + return "AF_INET"; + default: + __builtin_unreachable (); + } +} + +static const char * +db_str (int db) +{ + switch (db) + { + case DB_DNS: + return "dns"; + case DB_FILES: + return "files"; + default: + __builtin_unreachable (); + } +} + +static const char * +action_str (int action) +{ + switch (action) + { + case ACTION_MERGE: + return "merge"; + case ACTION_CONTINUE: + return "continue"; + default: + __builtin_unreachable (); + } +} + +/* getaddrinfo test. To be run from a subprocess. */ +static void +test_gai (void *closure) +{ + struct test_params *params = closure; + + struct addrinfo hints = + { + .ai_family = params->family, + }; + + struct addrinfo *ai; + + if (params->canon) + hints.ai_flags = AI_CANONNAME; + + /* Use /etc/hosts in the chroot. */ + if (params->db == DB_FILES) + xchroot (chroot_env->path_chroot); + + printf ("***** Testing \"%s [SUCCESS=%s] %s\" for family %s, %s\n", + db_str (params->db), action_str (params->action), + db_str (params->db), family_str (params->family), + params->canon ? "AI_CANONNAME" : ""); + + int ret = getaddrinfo ("gnu.org", "80", &hints, &ai); + + switch (params->action) + { + case ACTION_MERGE: + if (ret == 0) + { + char *formatted = support_format_addrinfo (ai, ret); + + printf ("merge unexpectedly succeeded:\n %s\n", formatted); + support_record_failure (); + free (formatted); + } + else + return; + case ACTION_CONTINUE: + { + char *formatted = support_format_addrinfo (ai, ret); + + if (params->db == DB_FILES) + { + /* Verify that the result appears exactly once. */ + const char *expected = "address: STREAM/TCP 192.0.0.1 80\n" + "address: DGRAM/UDP 192.0.0.1 80\n" + "address: RAW/IP 192.0.0.1 80\n"; + + const char *contains = strstr (formatted, expected); + const char *contains2 = NULL; + + if (contains != NULL) + contains2 = strstr (contains + strlen (expected), expected); + + if (contains == NULL || contains2 != NULL) + { + printf ("continue failed:\n%s\n", formatted); + support_record_failure (); + } + } + else if (ret != 0) + { + printf ("continue unexpectedly failed:\n%s\n", formatted); + support_record_failure (); + } + + free (formatted); + break; + } + default: + __builtin_unreachable (); + } +} + +static void +test_in_subprocess (int db, int action) +{ + char buf[32]; + + snprintf (buf, sizeof (buf), "%s [SUCCESS=%s] %s", + db_str (db), action_str (action), db_str (db)); + __nss_configure_lookup ("hosts", buf); + + struct test_params params = + { + .db = db, + .action = action, + .family = AF_UNSPEC, + .canon = false, + }; + support_isolate_in_subprocess (test_gai, ¶ms); + params.family = AF_INET; + support_isolate_in_subprocess (test_gai, ¶ms); + params.canon = true; + support_isolate_in_subprocess (test_gai, ¶ms); +} + +static int +do_test (void) +{ + support_become_root (); + if (!support_can_chroot ()) + FAIL_UNSUPPORTED ("Cannot chroot\n"); + + write_hosts (); + test_in_subprocess (DB_FILES, ACTION_CONTINUE); + test_in_subprocess (DB_FILES, ACTION_MERGE); + test_in_subprocess (DB_DNS, ACTION_CONTINUE); + test_in_subprocess (DB_DNS, ACTION_MERGE); + + support_chroot_free (chroot_env); + return 0; +} + +#define PREPARE prepare +#include diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 18dccd5924..454a27eb2f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -458,11 +458,6 @@ gaih_inet (const char *name, const struct gaih_service *service, if (name != NULL) { - at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); - at->family = AF_UNSPEC; - at->scopeid = 0; - at->next = NULL; - if (req->ai_flags & AI_IDN) { char *out; @@ -473,13 +468,21 @@ gaih_inet (const char *name, const struct gaih_service *service, malloc_name = true; } - if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) + uint32_t addr[4]; + if (__inet_aton_exact (name, (struct in_addr *) addr) != 0) { + at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); + at->scopeid = 0; + at->next = NULL; + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) - at->family = AF_INET; + { + memcpy (at->addr, addr, sizeof (at->addr)); + at->family = AF_INET; + } else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED)) { - at->addr[3] = at->addr[0]; + at->addr[3] = addr[0]; at->addr[2] = htonl (0xffff); at->addr[1] = 0; at->addr[0] = 0; @@ -493,49 +496,62 @@ gaih_inet (const char *name, const struct gaih_service *service, if (req->ai_flags & AI_CANONNAME) canon = name; + + goto process_list; } - else if (at->family == AF_UNSPEC) + + char *scope_delim = strchr (name, SCOPE_DELIMITER); + int e; + + if (scope_delim == NULL) + e = inet_pton (AF_INET6, name, addr); + else + e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr); + + if (e > 0) { - char *scope_delim = strchr (name, SCOPE_DELIMITER); - int e; - if (scope_delim == NULL) - e = inet_pton (AF_INET6, name, at->addr); + at = alloca_account (sizeof (struct gaih_addrtuple), + alloca_used); + at->scopeid = 0; + at->next = NULL; + + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + { + memcpy (at->addr, addr, sizeof (at->addr)); + at->family = AF_INET6; + } + else if (req->ai_family == AF_INET + && IN6_IS_ADDR_V4MAPPED (addr)) + { + at->addr[0] = addr[3]; + at->addr[1] = addr[1]; + at->addr[2] = addr[2]; + at->addr[3] = addr[3]; + at->family = AF_INET; + } else - e = __inet_pton_length (AF_INET6, name, scope_delim - name, - at->addr); - if (e > 0) { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - at->family = AF_INET6; - else if (req->ai_family == AF_INET - && IN6_IS_ADDR_V4MAPPED (at->addr)) - { - at->addr[0] = at->addr[3]; - at->family = AF_INET; - } - else - { - result = -EAI_ADDRFAMILY; - goto free_and_return; - } - - if (scope_delim != NULL - && __inet6_scopeid_pton ((struct in6_addr *) at->addr, - scope_delim + 1, - &at->scopeid) != 0) - { - result = -EAI_NONAME; - goto free_and_return; - } + result = -EAI_ADDRFAMILY; + goto free_and_return; + } - if (req->ai_flags & AI_CANONNAME) - canon = name; + if (scope_delim != NULL + && __inet6_scopeid_pton ((struct in6_addr *) at->addr, + scope_delim + 1, + &at->scopeid) != 0) + { + result = -EAI_NONAME; + goto free_and_return; } + + if (req->ai_flags & AI_CANONNAME) + canon = name; + + goto process_list; } - if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) + if ((req->ai_flags & AI_NUMERICHOST) == 0) { - struct gaih_addrtuple **pat = &at; int no_data = 0; int no_inet6_data = 0; nss_action_list nip; @@ -543,6 +559,7 @@ gaih_inet (const char *name, const struct gaih_service *service, enum nss_status status = NSS_STATUS_UNAVAIL; int no_more; struct resolv_context *res_ctx = NULL; + bool do_merge = false; /* If we do not have to look for IPv6 addresses or the canonical name, use the simple, old functions, which do not support @@ -579,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service, result = -EAI_MEMORY; goto free_and_return; } - *pat = addrmem; + at = addrmem; } else { @@ -632,6 +649,8 @@ gaih_inet (const char *name, const struct gaih_service *service, } struct gaih_addrtuple *addrfree = addrmem; + struct gaih_addrtuple **pat = &at; + for (int i = 0; i < air->naddrs; ++i) { socklen_t size = (air->family[i] == AF_INET @@ -695,12 +714,6 @@ gaih_inet (const char *name, const struct gaih_service *service, free (air); - if (at->family == AF_UNSPEC) - { - result = -EAI_NONAME; - goto free_and_return; - } - goto process_list; } else if (err == 0) @@ -732,6 +745,21 @@ gaih_inet (const char *name, const struct gaih_service *service, while (!no_more) { + /* Always start afresh; continue should discard previous results + and the hosts database does not support merge. */ + at = NULL; + free (canonbuf); + free (addrmem); + canon = canonbuf = NULL; + addrmem = NULL; + + if (do_merge) + { + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + break; + } + no_data = 0; nss_gethostbyname4_r *fct4 = NULL; @@ -744,12 +772,14 @@ gaih_inet (const char *name, const struct gaih_service *service, { while (1) { - status = DL_CALL_FCT (fct4, (name, pat, + status = DL_CALL_FCT (fct4, (name, &at, tmpbuf->data, tmpbuf->length, &errno, &h_errno, NULL)); if (status == NSS_STATUS_SUCCESS) break; + /* gethostbyname4_r may write into AT, so reset it. */ + at = NULL; if (status != NSS_STATUS_TRYAGAIN || errno != ERANGE || h_errno != NETDB_INTERNAL) { @@ -774,7 +804,9 @@ 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; + canon = at->name; + + struct gaih_addrtuple **pat = &at; while (*pat != NULL) { @@ -826,6 +858,8 @@ gaih_inet (const char *name, const struct gaih_service *service, if (fct != NULL) { + struct gaih_addrtuple **pat = &at; + if (req->ai_family == AF_INET6 || req->ai_family == AF_UNSPEC) { @@ -899,6 +933,10 @@ gaih_inet (const char *name, const struct gaih_service *service, if (nss_next_action (nip, status) == NSS_ACTION_RETURN) break; + /* The hosts database does not support MERGE. */ + if (nss_next_action (nip, status) == NSS_ACTION_MERGE) + do_merge = true; + nip++; if (nip->module == NULL) no_more = -1; @@ -930,7 +968,7 @@ gaih_inet (const char *name, const struct gaih_service *service, } process_list: - if (at->family == AF_UNSPEC) + if (at == NULL) { result = -EAI_NONAME; goto free_and_return; From patchwork Tue Mar 8 10:07:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602866 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=cpc4MqBb; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWQf1vjyz9sGL for ; Tue, 8 Mar 2022 21:14:34 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F2D1E385AC2B for ; Tue, 8 Mar 2022 10:14:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F2D1E385AC2B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734472; bh=VYm81me2qsvZNIo9Y6GE+T0uv6kme6lwmNJ4KR5XplQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=cpc4MqBbkTE0rtPG9qnoccSEoiGpwvUw4JJGU4/dq5J3WJXKKR0o0/+4IUBCkqgb5 RxT5z5bfVeQi1kuePKM6GKwBkgSdYPVFc6loLKU8q9qrdDRh8+agRGTa9u3ikoPMgv eKEbNJtb1QDuX7U8PgWiMYczBLDFHMWIibKiuyhc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from black.elm.relay.mailchannels.net (black.elm.relay.mailchannels.net [23.83.212.19]) by sourceware.org (Postfix) with ESMTPS id D8316385AC2C for ; Tue, 8 Mar 2022 10:08:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D8316385AC2C 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 11F7F8218C7; Tue, 8 Mar 2022 10:08:30 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 4E31F8211CD; Tue, 8 Mar 2022 10:07:59 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734105; a=rsa-sha256; cv=none; b=T3XOIOFpi1Dame1i8QejhUoCcUIh+7FEKa4ZqYwF99Fvmqo3TldiSiYbsWhiGjH08CSXoi +wTf1lUPkzbw3repA/ZOOdtR+6Nzj31XKpIE2426g98rwL4GtnrD37juyoBqWR4nml4teZ 3+AoYLcUZecmczmVffb2Z5MMwNSQEqOXiBFIXrFI2AfNGFS3jOlLq+WCyUeY0ioiNjUG7w 5oTJbs8tChRp1RsvJUDWwx6c9FGJK34IiKaEP40oSMzEBrOl6irDXy/5ZO6XtAKxCYGWTd OYfiWqHx6rhuFt0TE6KWvUrRNDT5sVNk+PamgB2QgR/9uPbquQCTPCApGaR46g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734105; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VYm81me2qsvZNIo9Y6GE+T0uv6kme6lwmNJ4KR5XplQ=; b=EzU4neTRnurQYT6lKtG3aiYl5SpPm8gk54uRba8iJe18trrrFaRyzmQ1lAatKJRwwSGJXG qF/Ld4XFDqDNkqAhn5JYAu7k+fa+WyU36faTv9P5+G8j2oUguGX9Gn3cND/m4vWTpFUxMU 1WQlyQAjZNqPbCy6QYzbfRGeDztFJpxUz9KHSEhDCp7BTY1cwMm9ZG5/aBLaivBcyiHNDO bXlmBmaJvIxhmoVJ59TDUgy/x8Ceq2vcuE8/WElAFGjmht7FbCUDTrqYZiG00GMy3jTYZH R0MnldU5TayXcDlq8MlbOyFKydXyvDzXUQnqypzuAez88k4N6lTbWfTQvNEmUw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-c72dn; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.118.223.199 (trex/6.5.3); Tue, 08 Mar 2022 10:08:30 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Thoughtful-Interest: 38ae01c0409c610f_1646734109903_807457131 X-MC-Loop-Signature: 1646734109903:3873766039 X-MC-Ingress-Time: 1646734109903 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGk1mfCz1PV; Tue, 8 Mar 2022 02:07:41 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 02/12] gaih_inet: Simplify canon name resolution Date: Tue, 8 Mar 2022 15:37:07 +0530 Message-Id: <20220308100717.1006126-3-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.3 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_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" 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 --- sysdeps/posix/getaddrinfo.c | 130 +++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 55 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 454a27eb2f..df164a3e96 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -285,7 +285,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, \ if (localcanon != NULL && canon == NULL) \ { \ - canonbuf = __strdup (localcanon); \ + char *canonbuf = __strdup (localcanon); \ if (canonbuf == NULL) \ { \ __resolv_context_put (res_ctx); \ @@ -323,6 +323,41 @@ getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name) return __strdup (name); } +/* Process looked up canonical name and if necessary, decode to IDNA. Result + is a new string written to CANONP and the earlier string is freed. */ + +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, @@ -332,7 +367,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; 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 @@ -453,7 +488,6 @@ gaih_inet (const char *name, const struct gaih_service *service, bool malloc_name = false; struct gaih_addrtuple *addrmem = NULL; - char *canonbuf = NULL; int result = 0; if (name != NULL) @@ -495,7 +529,15 @@ gaih_inet (const char *name, const struct gaih_service *service, } if (req->ai_flags & AI_CANONNAME) - canon = name; + { + char *canonbuf = __strdup (name); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + canon = canonbuf; + } goto process_list; } @@ -545,7 +587,15 @@ gaih_inet (const char *name, const struct gaih_service *service, } if (req->ai_flags & AI_CANONNAME) - canon = name; + { + char *canonbuf = __strdup (name); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + canon = canonbuf; + } goto process_list; } @@ -676,9 +726,9 @@ gaih_inet (const char *name, const struct gaih_service *service, (*pat)->next = NULL; if (added_canon || air->canon == NULL) (*pat)->name = NULL; - else if (canonbuf == NULL) + else if (canon == NULL) { - canonbuf = __strdup (air->canon); + char *canonbuf = __strdup (air->canon); if (canonbuf == NULL) { result = -EAI_MEMORY; @@ -748,9 +798,9 @@ gaih_inet (const char *name, const struct gaih_service *service, /* Always start afresh; continue should discard previous results and the hosts database does not support merge. */ at = NULL; - free (canonbuf); + free (canon); free (addrmem); - canon = canonbuf = NULL; + canon = NULL; addrmem = NULL; if (do_merge) @@ -804,7 +854,16 @@ gaih_inet (const char *name, const struct gaih_service *service, no_data = 1; if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) - canon = at->name; + { + char *canonbuf = __strdup (at->name); + if (canonbuf == NULL) + { + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto free_and_return; + } + canon = canonbuf; + } struct gaih_addrtuple **pat = &at; @@ -892,7 +951,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); @@ -1003,6 +1062,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_servtuple *st2; struct gaih_addrtuple *at2 = at; size_t socklen; @@ -1013,48 +1076,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) { @@ -1077,7 +1098,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; } @@ -1137,7 +1157,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (malloc_name) free ((char *) name); free (addrmem); - free (canonbuf); + free (canon); return result; } From patchwork Tue Mar 8 10:07:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602845 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=kYhhPdUw; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWJM0GQNz9sGL for ; Tue, 8 Mar 2022 21:09:07 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1B74F385800A for ; Tue, 8 Mar 2022 10:09:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1B74F385800A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734145; bh=EVSZ51jl62MSTU4V4ZSfnYHnlCeYhaOaOPo5p5O5asI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=kYhhPdUwxy35upi5rkX1ukzQdCvpg49LgALReMtopmqhbrFUmGmLfVjGntoK++xcW sRdsE2KjWm01pgSBhoJrFLmK13LbqBLIzq0xaWEsbXiJnQ5/UrdOt+iVHvCZf0FGF0 5AFaeCA7s9LoF8sd6pIn36zvoAqVcEv4Mwp3nk24= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cyan.elm.relay.mailchannels.net (cyan.elm.relay.mailchannels.net [23.83.212.47]) by sourceware.org (Postfix) with ESMTPS id 50A393858C83 for ; Tue, 8 Mar 2022 10:08:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 50A393858C83 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 A198C6222E7; Tue, 8 Mar 2022 10:08:03 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 18E71621C33; Tue, 8 Mar 2022 10:07:47 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734082; a=rsa-sha256; cv=none; b=E2lFV5T5O37JwBxLJ6KfvMnTLhmsO6M6KEGPwpK4e3Scolqj8kCQWzO3E6aKowHlJz+cr2 UmfsdwNMXlQ4q3/IkVtKJ8IdIsq8OA82CbxYn0s+coAdqPXmjhupgcoMKMge/0eo4LT9X2 SHwXwCHUqJj0/EZzQYeDFgQ3qm++hMpZrVeWG66jhKeBqI1Wmd6DXxWKZrTqEDSws+dyGG PuztwnA3DfSCuPzgIvnMCkPH0S5qfvJ/VAc1yWpye+//tEbENgLnnsytR82oODDH8xKOz/ oXXPgKZNJf1ErZypry/gMdtn7viZMV/hYdNZThKihHZTQ9Rh7ND+F1NbpWqAEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734082; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EVSZ51jl62MSTU4V4ZSfnYHnlCeYhaOaOPo5p5O5asI=; b=J1vsc8GMQ26ZEGEaUkzKX08njMSkBbDBlEWv8cvqLnBxweg5qLCVUjE5tm04F//BfBiwg6 AYwe0X79+JtJsIdALh41CwW2ce92ZhwmlkoQt8gdZ3z2YuzZ2HEnpaSerEZ3MaSDyDfIkc Yy/9BPixKmMrMp8B0sEMHS6hVEj7A1Jhd8k6IwyJuR5AOYLQpAI6eatG1hx1qsK61QCvU4 QIGki4IRCkEbXzTfIKH3afXoTkreE/oXWiMD/NJyoCVT6lzYi8mRFcmZdK7XXixMYXbQYs mkgm1BIjZRpFxPByqvkpwYdeYNtBhL5oM0ehy2moy3QrzZPhOi/Qnl+eNkS2IQ== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-47l9f; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.124.31.75 (trex/6.5.3); Tue, 08 Mar 2022 10:08:03 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Attack-Trail: 28607d5b1aaa15ef_1646734083340_2948203479 X-MC-Loop-Signature: 1646734083340:2722243943 X-MC-Ingress-Time: 1646734083340 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGn0lP7z1PZ; Tue, 8 Mar 2022 02:07:44 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852] Date: Tue, 8 Mar 2022 15:37:08 +0530 Message-Id: <20220308100717.1006126-4-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Use realloc in convert_hostent_to_gaih_addrtuple and fix up pointers in the result list so that a single block is maintained for hostbyname3_r/hostbyname2_r and freed in gaih_inet. This result is never merged with any other results, since the hosts database does not permit merging. Resolves BZ #28852. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index df164a3e96..0ec85dc4bd 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -199,9 +199,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, struct hostent *h, struct gaih_addrtuple **result) { - while (*result) - result = &(*result)->next; - /* Count the number of addresses in h->h_addr_list. */ size_t count = 0; for (char **p = h->h_addr_list; *p != NULL; ++p) @@ -212,10 +209,30 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr)) return true; - struct gaih_addrtuple *array = calloc (count, sizeof (*array)); + struct gaih_addrtuple *array = *result; + size_t old = 0; + + while (array) + { + old++; + array = array->next; + } + + array = realloc (*result, (old + count) * sizeof (*array)); + if (array == NULL) return false; + *result = array; + + /* Update the next pointers on reallocation. */ + for (size_t i = 0; i < old; i++) + array[i].next = array + i + 1; + + array += old; + + memset (array, 0, count * sizeof (*array)); + for (size_t i = 0; i < count; ++i) { if (family == AF_INET && req->ai_family == AF_INET6) @@ -235,7 +252,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, array[0].name = h->h_name; array[count - 1].next = NULL; - *result = array; return true; } From patchwork Tue Mar 8 10:07:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602871 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=u0iarhvU; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWWm4YFrz9sGL for ; Tue, 8 Mar 2022 21:19:00 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9D785385AC24 for ; Tue, 8 Mar 2022 10:18:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9D785385AC24 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734737; bh=1jioEukRsP8ewWwsjmmjkZt39kc2YRYT2qez3uziwak=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=u0iarhvUVWuWwA/cRh8W/gund2yxHqDpZmwYVLvRC7icv7fmoMaepiHc61rYThUm0 JzFc/P7wxRd8bryGchpxfGf11VyM719BZUSrjNDEu7Vwj5K9aUDfBi4Eb7Ls8kWQ8c Z214v1ONRcHxWDCGvprr8bnBZqYmHprdYDSZJ0sk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from crocodile.elm.relay.mailchannels.net (crocodile.elm.relay.mailchannels.net [23.83.212.45]) by sourceware.org (Postfix) with ESMTPS id 0D3CA385741B for ; Tue, 8 Mar 2022 10:18:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0D3CA385741B 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 7F4BC8220A2; Tue, 8 Mar 2022 10:08:25 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id D1C8E821428; Tue, 8 Mar 2022 10:08:00 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734094; a=rsa-sha256; cv=none; b=w5FzT41PX5uoNmbhBTw/PMZR0YjL+1DHOjRA6hTbbH26GqyGRfcQPEYBlzQ2dHEspuw12Z 3XTp4ZfGr6WPFchj9pCeXEQyVtWDEvlXBiswKilKdtDUCWNwNSBs7+wk53OznqGoVHSqU0 EUdyfqq3VEmbxcelaeHRAFcLUYSdZgbJIKOmA+XMSE+ociTZePmkpHKa+22I9Mhmf3VamQ whod6bP+YUaRs+o887bCueqiyCvIZodHlsQ8Lq/UKhYNxzfx8O2F52kowTwYpHy+nilGjg OZiztUBoDCBgn/vRfzUXhzZVCFlexaENN679peoXgn1Rwk4SbdZSlClh0Szy0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734094; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1jioEukRsP8ewWwsjmmjkZt39kc2YRYT2qez3uziwak=; b=0b2g14hE6abb60SEzd9v86HFK9TA8WcehYOxuqFgLpZ6huhbPXJEAAyKkbVu6/2e4tqFSG KD3ZfXPyZiqIrts1FSwOcjycQ9alJ7n4PVr4D7/3CIIUSDG2/ECPbus/Z9ypMRJFUyFQor b937QmSvGXAXxWNAWHaSia7PHcW81pRznpP/pZsNPvKAbmB6CtjvTMp7UuOO1E/T6dLOmN /FjbamuZ18ifccPWxZxBGZZWsdp+GZKCMBRocS3EQoQYgW4DsiSVunWjm6xLl0I0goxSD/ MmIdiZQ4gqK8fOgceUQx+bA1zKJ1t2mEd8CGi4GzHVIZExNf7SHC7MvERG7VAg== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-87vvq; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.126.0.48 (trex/6.5.3); Tue, 08 Mar 2022 10:08:25 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Coil-Suffer: 6c985510356322ea_1646734095265_250822703 X-MC-Loop-Signature: 1646734095265:4001814990 X-MC-Ingress-Time: 1646734095264 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGq5RKyz1PY; Tue, 8 Mar 2022 02:07:47 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 04/12] gaih_inet: Simplify service resolution Date: Tue, 8 Mar 2022 15:37:09 +0530 Message-Id: <20220308100717.1006126-5-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.3 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, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Refactor the code to split out the service resolution code into a separate function. Allocate the service tuples array just once to the size of the typeproto array, thus avoiding the unnecessary pointer chasing and stack allocations. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 178 ++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 100 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 0ec85dc4bd..6bc1d6b8d2 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -100,14 +100,12 @@ struct gaih_service struct gaih_servtuple { - struct gaih_servtuple *next; int socktype; int protocol; int port; + bool set; }; -static const struct gaih_servtuple nullserv; - struct gaih_typeproto { @@ -180,11 +178,11 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, } while (r); - st->next = NULL; st->socktype = tp->socktype; st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) ? req->ai_protocol : tp->protocol); st->port = s->s_port; + st->set = true; return 0; } @@ -375,20 +373,11 @@ process_canonname (const struct addrinfo *req, const char *orig_name, } static int -gaih_inet (const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai, - unsigned int *naddrs, struct scratch_buffer *tmpbuf) +get_servtuples (const struct gaih_service *service, const struct addrinfo *req, + struct gaih_servtuple *st, struct scratch_buffer *tmpbuf) { + int i; const struct gaih_typeproto *tp = gaih_inet_typeproto; - struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; - struct gaih_addrtuple *at = NULL; - bool got_ipv6 = false; - char *canon = NULL; - const char *orig_name = name; - - /* Reserve stack memory for the scratch buffer in the getaddrinfo - function. */ - size_t alloca_used = sizeof (struct scratch_buffer); if (req->ai_protocol || req->ai_socktype) { @@ -410,98 +399,88 @@ gaih_inet (const char *name, const struct gaih_service *service, } } - int port = 0; - if (service != NULL) + if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + return -EAI_SERVICE; + + if (service == NULL || service->num >= 0) { - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - return -EAI_SERVICE; + int port = service != NULL ? htons (service->num) : 0; - if (service->num < 0) + if (req->ai_socktype || req->ai_protocol) { - if (tp->name[0]) - { - st = (struct gaih_servtuple *) - alloca_account (sizeof (struct gaih_servtuple), alloca_used); - - int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf); - if (__glibc_unlikely (rc != 0)) - return rc; - } - else - { - struct gaih_servtuple **pst = &st; - for (tp++; tp->name[0]; tp++) - { - struct gaih_servtuple *newp; + st[0].socktype = tp->socktype; + st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) + ? req->ai_protocol : tp->protocol); + st[0].port = port; + st[0].set = true; - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - continue; + return 0; + } - if (req->ai_socktype != 0 - && req->ai_socktype != tp->socktype) - continue; - if (req->ai_protocol != 0 - && !(tp->protoflag & GAI_PROTO_PROTOANY) - && req->ai_protocol != tp->protocol) - continue; + /* Neither socket type nor protocol is set. Return all socket types + we know about. */ + for (i = 0, ++tp; tp->name[0]; ++tp) + if (tp->defaultflag) + { + st[i].socktype = tp->socktype; + st[i].protocol = tp->protocol; + st[i].port = port; + st[i++].set = true; + } - newp = (struct gaih_servtuple *) - alloca_account (sizeof (struct gaih_servtuple), - alloca_used); + return 0; + } - if (gaih_inet_serv (service->name, - tp, req, newp, tmpbuf) != 0) - continue; + if (tp->name[0]) + return gaih_inet_serv (service->name, tp, req, st, tmpbuf); - *pst = newp; - pst = &(newp->next); - } - if (st == (struct gaih_servtuple *) &nullserv) - return -EAI_SERVICE; - } - } - else - { - port = htons (service->num); - goto got_port; - } - } - else + for (i = 0, tp++; tp->name[0]; tp++) { - got_port: + if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + continue; - if (req->ai_socktype || req->ai_protocol) - { - st = alloca_account (sizeof (struct gaih_servtuple), alloca_used); - st->next = NULL; - st->socktype = tp->socktype; - st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) - ? req->ai_protocol : tp->protocol); - st->port = port; - } - else - { - /* Neither socket type nor protocol is set. Return all socket types - we know about. */ - struct gaih_servtuple **lastp = &st; - for (++tp; tp->name[0]; ++tp) - if (tp->defaultflag) - { - struct gaih_servtuple *newp; + if (req->ai_socktype != 0 + && req->ai_socktype != tp->socktype) + continue; + if (req->ai_protocol != 0 + && !(tp->protoflag & GAI_PROTO_PROTOANY) + && req->ai_protocol != tp->protocol) + continue; - newp = alloca_account (sizeof (struct gaih_servtuple), - alloca_used); - newp->next = NULL; - newp->socktype = tp->socktype; - newp->protocol = tp->protocol; - newp->port = port; + if (gaih_inet_serv (service->name, + tp, req, &st[i], tmpbuf) != 0) + continue; - *lastp = newp; - lastp = &newp->next; - } - } + i++; } + if (!st[0].set) + return -EAI_SERVICE; + + return 0; +} + +static int +gaih_inet (const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, + unsigned int *naddrs, struct scratch_buffer *tmpbuf) +{ + struct gaih_servtuple st[sizeof (gaih_inet_typeproto) + / sizeof (struct gaih_typeproto)] = {0}; + + struct gaih_addrtuple *at = NULL; + bool got_ipv6 = false; + char *canon = NULL; + const char *orig_name = name; + + /* Reserve stack memory for the scratch buffer in the getaddrinfo + function. */ + size_t alloca_used = sizeof (struct scratch_buffer); + + int rc; + if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0) + return rc; + bool malloc_name = false; struct gaih_addrtuple *addrmem = NULL; int result = 0; @@ -1082,7 +1061,6 @@ gaih_inet (const char *name, const struct gaih_service *service, if ((result = process_canonname (req, orig_name, &canon)) != 0) goto free_and_return; - struct gaih_servtuple *st2; struct gaih_addrtuple *at2 = at; size_t socklen; sa_family_t family; @@ -1108,7 +1086,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else socklen = sizeof (struct sockaddr_in); - for (st2 = st; st2 != NULL; st2 = st2->next) + for (int i = 0; st[i].set; i++) { struct addrinfo *ai; ai = *pai = malloc (sizeof (struct addrinfo) + socklen); @@ -1120,8 +1098,8 @@ gaih_inet (const char *name, const struct gaih_service *service, ai->ai_flags = req->ai_flags; ai->ai_family = family; - ai->ai_socktype = st2->socktype; - ai->ai_protocol = st2->protocol; + ai->ai_socktype = st[i].socktype; + ai->ai_protocol = st[i].protocol; ai->ai_addrlen = socklen; ai->ai_addr = (void *) (ai + 1); @@ -1143,7 +1121,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr; - sin6p->sin6_port = st2->port; + sin6p->sin6_port = st[i].port; sin6p->sin6_flowinfo = 0; memcpy (&sin6p->sin6_addr, at2->addr, sizeof (struct in6_addr)); @@ -1153,7 +1131,7 @@ gaih_inet (const char *name, const struct gaih_service *service, { struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr; - sinp->sin_port = st2->port; + sinp->sin_port = st[i].port; memcpy (&sinp->sin_addr, at2->addr, sizeof (struct in_addr)); memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); From patchwork Tue Mar 8 10:07:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602846 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=rM9IDhDS; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWKB1NY6z9sGL for ; Tue, 8 Mar 2022 21:09:50 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 837353857439 for ; Tue, 8 Mar 2022 10:09:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 837353857439 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734187; bh=klGofE8/SJLmw+2bqVxeRcBfbBlflTLsmD1eQOMcUPM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=rM9IDhDSpRvlOeLqb3QD8PwJaVGtt7KRToVmar5/knW50ZTsz5FtZLqrazp0mmzRd Iak4wfLwS4FeW9MGa/6UA2LXXSbKA7GyFB6iz4mTGMhaw12Ry3tcoli6sfE0TDucz+ CZxS+sv7ntLl3ZBTrX6g735xYYnTu5FFsQAd/yQs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from eastern.birch.relay.mailchannels.net (eastern.birch.relay.mailchannels.net [23.83.209.55]) by sourceware.org (Postfix) with ESMTPS id 111ED3858400 for ; Tue, 8 Mar 2022 10:08:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 111ED3858400 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 55F36862589; Tue, 8 Mar 2022 10:08:04 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 6DFA2862660; Tue, 8 Mar 2022 10:08:03 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734083; a=rsa-sha256; cv=none; b=i/PMigBfNX0OcQXVIlkq+RQrqvhPURdPMs+OMb0BTX0ImZtnRRSYOaKrX2tMVDP6QrP66a xknJvjAxQGN5hc3RoBlK/8/m7a5n2jNosM24FPLzD5mcfgo6HNYO9ZYhDN0PAw+iUEbMNZ mr3qdNTxIjg6chpQKg9wU1zDJa7//7qTaciiQEFY8TybXUeRruc4/ileA6GdqAUHq/CsPT Qpcqkh2h2NDmnP7XaPbKbOPD2z+MoeTYeepnv3YViJyan20scO/MdjMT+IfSCiJjrd8qAE 9Nfi9e+giqZD1xhdXes6LcUbRXdWssJEOzjrj7Qlil/DzP7gb0My2DG8QJ/5qQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734083; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=klGofE8/SJLmw+2bqVxeRcBfbBlflTLsmD1eQOMcUPM=; b=qAdBYdRe7lVIEPFfj9W3LiagwWF0NsCHthUrIm2/bnP2JqHy0ydUzUGRsnSkR7Cmk1paIP OoF2NcKhYOfQXgIEVYN0YHC1kb15F7N3cYlRIqo8PCSXqDWaUQAtS25NdjBPF0IBMu7FPt LVKd6iYd7L+qej2fZAXktcfc3JGpSMOZ4mOR2EivBOPYI3X3o4y8dFHmWyy+03cMbEO9AI GOG7ORp13pD9PsTNZNCSl+GzWLpzvMXjdZgd/iQWsoa8PuY3QkfW/hejTLMC6QK7Y+i5Pz 3O6Pr8xUkOGCe3/6TlBILJ0X79CizKSrhwnhqNi1LtLiJgDajtx2tQPGU6PRJw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-kq7js; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.118.223.199 (trex/6.5.3); Tue, 08 Mar 2022 10:08:04 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Attack-Bitter: 707c215b3b9b94ec_1646734083973_145020286 X-MC-Loop-Signature: 1646734083972:4200208763 X-MC-Ingress-Time: 1646734083972 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGt37MPz1Pr; Tue, 8 Mar 2022 02:07:50 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 05/12] gaih_inet: make numeric lookup a separate routine Date: Tue, 8 Mar 2022 15:37:10 +0530 Message-Id: <20220308100717.1006126-6-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Introduce the gaih_result structure and general paradigm for cleanups that follow to process the lookup request and return a result. A lookup function (like text_to_binary_address), should return an integer error code and set members of gaih_result based on what it finds. If the function does not have a result and no errors have occurred during the lookup, it should return 0 and res.at should be set to NULL, allowing a subsequent function to do the lookup until we run out of options. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 889 ++++++++++++++++++------------------ 1 file changed, 451 insertions(+), 438 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 6bc1d6b8d2..868c7d222f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -116,6 +116,12 @@ struct gaih_typeproto char name[8]; }; +struct gaih_result +{ + struct gaih_addrtuple *at; + char *canon; +}; + /* Values for `protoflag'. */ #define GAI_PROTO_NOSERVICE 1 #define GAI_PROTO_PROTOANY 2 @@ -297,7 +303,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, } \ *pat = addrmem; \ \ - if (localcanon != NULL && canon == NULL) \ + if (localcanon != NULL && res.canon == NULL) \ { \ char *canonbuf = __strdup (localcanon); \ if (canonbuf == NULL) \ @@ -306,7 +312,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, result = -EAI_SYSTEM; \ goto free_and_return; \ } \ - canon = canonbuf; \ + res.canon = canonbuf; \ } \ if (_family == AF_INET6 && *pat != NULL) \ got_ipv6 = true; \ @@ -342,9 +348,9 @@ getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name) static int process_canonname (const struct addrinfo *req, const char *orig_name, - char **canonp) + struct gaih_result *res) { - char *canon = *canonp; + char *canon = res->canon; if ((req->ai_flags & AI_CANONNAME) != 0) { @@ -368,7 +374,7 @@ process_canonname (const struct addrinfo *req, const char *orig_name, return -EAI_MEMORY; } - *canonp = canon; + res->canon = canon; return 0; } @@ -460,6 +466,105 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req, return 0; } +/* Convert numeric addresses to binary into RES. On failure, RES->AT is set to + NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and + the function cannot determine a result, RES->AT is set to NULL and 0 + returned. */ + +static int +text_to_binary_address (const char *name, const struct addrinfo *req, + struct gaih_result *res) +{ + struct gaih_addrtuple *at = res->at; + int result = 0; + + assert (at != NULL); + + memset (at->addr, 0, sizeof (at->addr)); + if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) + { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) + at->family = AF_INET; + else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED)) + { + at->addr[3] = at->addr[0]; + at->addr[2] = htonl (0xffff); + at->addr[1] = 0; + at->addr[0] = 0; + at->family = AF_INET6; + } + else + { + result = -EAI_ADDRFAMILY; + goto out; + } + + if (req->ai_flags & AI_CANONNAME) + { + char *canonbuf = __strdup (name); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + return 0; + } + + char *scope_delim = strchr (name, SCOPE_DELIMITER); + int e; + + if (scope_delim == NULL) + e = inet_pton (AF_INET6, name, at->addr); + else + e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr); + + if (e > 0) + { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + at->family = AF_INET6; + else if (req->ai_family == AF_INET + && IN6_IS_ADDR_V4MAPPED (at->addr)) + { + at->addr[0] = at->addr[3]; + at->family = AF_INET; + } + else + { + result = -EAI_ADDRFAMILY; + goto out; + } + + if (scope_delim != NULL + && __inet6_scopeid_pton ((struct in6_addr *) at->addr, + scope_delim + 1, &at->scopeid) != 0) + { + result = -EAI_NONAME; + goto out; + } + + if (req->ai_flags & AI_CANONNAME) + { + char *canonbuf = __strdup (name); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + return 0; + } + + if ((req->ai_flags & AI_NUMERICHOST)) + result = -EAI_NONAME; + +out: + res->at = NULL; + return result; +} + static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, @@ -468,9 +573,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_servtuple st[sizeof (gaih_inet_typeproto) / sizeof (struct gaih_typeproto)] = {0}; - struct gaih_addrtuple *at = NULL; bool got_ipv6 = false; - char *canon = NULL; const char *orig_name = name; /* Reserve stack memory for the scratch buffer in the getaddrinfo @@ -485,6 +588,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_addrtuple *addrmem = NULL; int result = 0; + struct gaih_result res = {0}; if (name != NULL) { if (req->ai_flags & AI_IDN) @@ -497,532 +601,440 @@ gaih_inet (const char *name, const struct gaih_service *service, malloc_name = true; } - uint32_t addr[4]; - if (__inet_aton_exact (name, (struct in_addr *) addr) != 0) + res.at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); + res.at->scopeid = 0; + res.at->next = NULL; + + if ((result = text_to_binary_address (name, req, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; + + int no_data = 0; + int no_inet6_data = 0; + nss_action_list nip; + enum nss_status inet6_status = NSS_STATUS_UNAVAIL; + enum nss_status status = NSS_STATUS_UNAVAIL; + int no_more; + struct resolv_context *res_ctx = NULL; + bool do_merge = false; + + /* If we do not have to look for IPv6 addresses or the canonical + name, use the simple, old functions, which do not support + IPv6 scope ids, nor retrieving the canonical name. */ + if (req->ai_family == AF_INET + && (req->ai_flags & AI_CANONNAME) == 0) { - at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); - at->scopeid = 0; - at->next = NULL; - - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) - { - memcpy (at->addr, addr, sizeof (at->addr)); - at->family = AF_INET; - } - else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED)) - { - at->addr[3] = addr[0]; - at->addr[2] = htonl (0xffff); - at->addr[1] = 0; - at->addr[0] = 0; - at->family = AF_INET6; - } - else - { - result = -EAI_ADDRFAMILY; - goto free_and_return; - } + int rc; + struct hostent th; + struct hostent *h; - if (req->ai_flags & AI_CANONNAME) + while (1) { - char *canonbuf = __strdup (name); - if (canonbuf == NULL) + rc = __gethostbyname2_r (name, AF_INET, &th, + tmpbuf->data, tmpbuf->length, + &h, &h_errno); + if (rc != ERANGE || h_errno != NETDB_INTERNAL) + break; + if (!scratch_buffer_grow (tmpbuf)) { result = -EAI_MEMORY; goto free_and_return; } - canon = canonbuf; } - goto process_list; - } - - char *scope_delim = strchr (name, SCOPE_DELIMITER); - int e; - - if (scope_delim == NULL) - e = inet_pton (AF_INET6, name, addr); - else - e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr); - - if (e > 0) - { - at = alloca_account (sizeof (struct gaih_addrtuple), - alloca_used); - at->scopeid = 0; - at->next = NULL; - - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - { - memcpy (at->addr, addr, sizeof (at->addr)); - at->family = AF_INET6; - } - else if (req->ai_family == AF_INET - && IN6_IS_ADDR_V4MAPPED (addr)) + if (rc == 0) { - at->addr[0] = addr[3]; - at->addr[1] = addr[1]; - at->addr[2] = addr[2]; - at->addr[3] = addr[3]; - at->family = AF_INET; + if (h != NULL) + { + /* We found data, convert it. */ + if (!convert_hostent_to_gaih_addrtuple + (req, AF_INET, h, &addrmem)) + { + result = -EAI_MEMORY; + goto free_and_return; + } + res.at = addrmem; + } + else + { + if (h_errno == NO_DATA) + result = -EAI_NODATA; + else + result = -EAI_NONAME; + goto free_and_return; + } } else { - result = -EAI_ADDRFAMILY; - goto free_and_return; - } + if (h_errno == NETDB_INTERNAL) + result = -EAI_SYSTEM; + else if (h_errno == TRY_AGAIN) + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. + The name is known, though. */ + result = -EAI_NODATA; - if (scope_delim != NULL - && __inet6_scopeid_pton ((struct in6_addr *) at->addr, - scope_delim + 1, - &at->scopeid) != 0) - { - result = -EAI_NONAME; goto free_and_return; } - if (req->ai_flags & AI_CANONNAME) + goto process_list; + } + +#ifdef USE_NSCD + if (__nss_not_use_nscd_hosts > 0 + && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) + __nss_not_use_nscd_hosts = 0; + + if (!__nss_not_use_nscd_hosts + && !__nss_database_custom[NSS_DBSIDX_hosts]) + { + /* Try to use nscd. */ + struct nscd_ai_result *air = NULL; + int err = __nscd_getai (name, &air, &h_errno); + if (air != NULL) { - char *canonbuf = __strdup (name); - if (canonbuf == NULL) + /* Transform into gaih_addrtuple list. */ + bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; + char *addrs = air->addrs; + + addrmem = calloc (air->naddrs, sizeof (*addrmem)); + if (addrmem == NULL) { result = -EAI_MEMORY; goto free_and_return; } - canon = canonbuf; - } - goto process_list; - } - - if ((req->ai_flags & AI_NUMERICHOST) == 0) - { - int no_data = 0; - int no_inet6_data = 0; - nss_action_list nip; - enum nss_status inet6_status = NSS_STATUS_UNAVAIL; - enum nss_status status = NSS_STATUS_UNAVAIL; - int no_more; - struct resolv_context *res_ctx = NULL; - bool do_merge = false; - - /* If we do not have to look for IPv6 addresses or the canonical - name, use the simple, old functions, which do not support - IPv6 scope ids, nor retrieving the canonical name. */ - if (req->ai_family == AF_INET - && (req->ai_flags & AI_CANONNAME) == 0) - { - int rc; - struct hostent th; - struct hostent *h; + struct gaih_addrtuple *addrfree = addrmem; + struct gaih_addrtuple **pat = &res.at; - while (1) + for (int i = 0; i < air->naddrs; ++i) { - rc = __gethostbyname2_r (name, AF_INET, &th, - tmpbuf->data, tmpbuf->length, - &h, &h_errno); - if (rc != ERANGE || h_errno != NETDB_INTERNAL) - break; - if (!scratch_buffer_grow (tmpbuf)) + socklen_t size = (air->family[i] == AF_INET + ? INADDRSZ : IN6ADDRSZ); + + if (!((air->family[i] == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) != 0) + || req->ai_family == AF_UNSPEC + || air->family[i] == req->ai_family)) { - result = -EAI_MEMORY; - goto free_and_return; + /* Skip over non-matching result. */ + addrs += size; + continue; } - } - if (rc == 0) - { - if (h != NULL) + if (*pat == NULL) + { + *pat = addrfree++; + (*pat)->scopeid = 0; + } + uint32_t *pataddr = (*pat)->addr; + (*pat)->next = NULL; + if (added_canon || air->canon == NULL) + (*pat)->name = NULL; + else if (res.canon == NULL) { - /* We found data, convert it. */ - if (!convert_hostent_to_gaih_addrtuple - (req, AF_INET, h, &addrmem)) + char *canonbuf = __strdup (air->canon); + if (canonbuf == NULL) { result = -EAI_MEMORY; goto free_and_return; } - at = addrmem; + res.canon = (*pat)->name = canonbuf; } - else + + if (air->family[i] == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED)) { - if (h_errno == NO_DATA) - result = -EAI_NODATA; - else - result = -EAI_NONAME; - goto free_and_return; + (*pat)->family = AF_INET6; + pataddr[3] = *(uint32_t *) addrs; + pataddr[2] = htonl (0xffff); + pataddr[1] = 0; + pataddr[0] = 0; + pat = &((*pat)->next); + added_canon = true; + } + else if (req->ai_family == AF_UNSPEC + || air->family[i] == req->ai_family) + { + (*pat)->family = air->family[i]; + memcpy (pataddr, addrs, size); + pat = &((*pat)->next); + added_canon = true; + if (air->family[i] == AF_INET6) + got_ipv6 = true; } + addrs += size; } - else - { - if (h_errno == NETDB_INTERNAL) - result = -EAI_SYSTEM; - else if (h_errno == TRY_AGAIN) - result = -EAI_AGAIN; - else - /* We made requests but they turned out no data. - The name is known, though. */ - result = -EAI_NODATA; - goto free_and_return; - } + free (air); goto process_list; } + else if (err == 0) + /* The database contains a negative entry. */ + goto free_and_return; + else if (__nss_not_use_nscd_hosts == 0) + { + if (h_errno == NETDB_INTERNAL && errno == ENOMEM) + result = -EAI_MEMORY; + else if (h_errno == TRY_AGAIN) + result = -EAI_AGAIN; + else + result = -EAI_SYSTEM; -#ifdef USE_NSCD - if (__nss_not_use_nscd_hosts > 0 - && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) - __nss_not_use_nscd_hosts = 0; + goto free_and_return; + } + } +#endif + + no_more = !__nss_database_get (nss_database_hosts, &nip); - if (!__nss_not_use_nscd_hosts - && !__nss_database_custom[NSS_DBSIDX_hosts]) + /* If we are looking for both IPv4 and IPv6 address we don't + want the lookup functions to automatically promote IPv4 + addresses to IPv6 addresses, so we use the no_inet6 + function variant. */ + res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + no_more = 1; + + while (!no_more) + { + /* Always start afresh; continue should discard previous results + and the hosts database does not support merge. */ + res.at = NULL; + free (res.canon); + free (addrmem); + res.canon = NULL; + addrmem = NULL; + + if (do_merge) { - /* Try to use nscd. */ - struct nscd_ai_result *air = NULL; - int err = __nscd_getai (name, &air, &h_errno); - if (air != NULL) + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + break; + } + + no_data = 0; + nss_gethostbyname4_r *fct4 = NULL; + + /* gethostbyname4_r sends out parallel A and AAAA queries and + is thus only suitable for PF_UNSPEC. */ + if (req->ai_family == PF_UNSPEC) + fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); + + if (fct4 != NULL) + { + while (1) { - /* Transform into gaih_addrtuple list. */ - bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; - char *addrs = air->addrs; + status = DL_CALL_FCT (fct4, (name, &res.at, + tmpbuf->data, tmpbuf->length, + &errno, &h_errno, + NULL)); + if (status == NSS_STATUS_SUCCESS) + break; + /* gethostbyname4_r may write into AT, so reset it. */ + res.at = NULL; + if (status != NSS_STATUS_TRYAGAIN + || errno != ERANGE || h_errno != NETDB_INTERNAL) + { + if (h_errno == TRY_AGAIN) + no_data = EAI_AGAIN; + else + no_data = h_errno == NO_DATA; + break; + } - addrmem = calloc (air->naddrs, sizeof (*addrmem)); - if (addrmem == NULL) + if (!scratch_buffer_grow (tmpbuf)) { + __resolv_context_put (res_ctx); result = -EAI_MEMORY; goto free_and_return; } + } - struct gaih_addrtuple *addrfree = addrmem; - struct gaih_addrtuple **pat = &at; + if (status == NSS_STATUS_SUCCESS) + { + assert (!no_data); + no_data = 1; - for (int i = 0; i < air->naddrs; ++i) + if ((req->ai_flags & AI_CANONNAME) != 0 && res.canon == NULL) { - socklen_t size = (air->family[i] == AF_INET - ? INADDRSZ : IN6ADDRSZ); - - if (!((air->family[i] == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) != 0) - || req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family)) + char *canonbuf = __strdup (res.at->name); + if (canonbuf == NULL) { - /* Skip over non-matching result. */ - addrs += size; - continue; + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto free_and_return; } + res.canon = canonbuf; + } - if (*pat == NULL) - { - *pat = addrfree++; - (*pat)->scopeid = 0; - } - uint32_t *pataddr = (*pat)->addr; - (*pat)->next = NULL; - if (added_canon || air->canon == NULL) - (*pat)->name = NULL; - else if (canon == NULL) - { - char *canonbuf = __strdup (air->canon); - if (canonbuf == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - canon = (*pat)->name = canonbuf; - } + struct gaih_addrtuple **pat = &res.at; - if (air->family[i] == AF_INET + while (*pat != NULL) + { + if ((*pat)->family == AF_INET && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED)) + && (req->ai_flags & AI_V4MAPPED) != 0) { + uint32_t *pataddr = (*pat)->addr; (*pat)->family = AF_INET6; - pataddr[3] = *(uint32_t *) addrs; + pataddr[3] = pataddr[0]; pataddr[2] = htonl (0xffff); pataddr[1] = 0; pataddr[0] = 0; pat = &((*pat)->next); - added_canon = true; + no_data = 0; } else if (req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family) + || (*pat)->family == req->ai_family) { - (*pat)->family = air->family[i]; - memcpy (pataddr, addrs, size); pat = &((*pat)->next); - added_canon = true; - if (air->family[i] == AF_INET6) + + no_data = 0; + if (req->ai_family == AF_INET6) got_ipv6 = true; } - addrs += size; + else + *pat = ((*pat)->next); } - - free (air); - - goto process_list; } - else if (err == 0) - /* The database contains a negative entry. */ - goto free_and_return; - else if (__nss_not_use_nscd_hosts == 0) - { - if (h_errno == NETDB_INTERNAL && errno == ENOMEM) - result = -EAI_MEMORY; - else if (h_errno == TRY_AGAIN) - result = -EAI_AGAIN; - else - result = -EAI_SYSTEM; - goto free_and_return; - } + no_inet6_data = no_data; } -#endif - - no_more = !__nss_database_get (nss_database_hosts, &nip); - - /* If we are looking for both IPv4 and IPv6 address we don't - want the lookup functions to automatically promote IPv4 - addresses to IPv6 addresses, so we use the no_inet6 - function variant. */ - res_ctx = __resolv_context_get (); - if (res_ctx == NULL) - no_more = 1; - - while (!no_more) + else { - /* Always start afresh; continue should discard previous results - and the hosts database does not support merge. */ - at = NULL; - free (canon); - free (addrmem); - canon = NULL; - addrmem = NULL; - - if (do_merge) + nss_gethostbyname3_r *fct = NULL; + if (req->ai_flags & AI_CANONNAME) + /* No need to use this function if we do not look for + the canonical name. The function does not exist in + all NSS modules and therefore the lookup would + often fail. */ + fct = __nss_lookup_function (nip, "gethostbyname3_r"); + if (fct == NULL) + /* We are cheating here. The gethostbyname2_r + function does not have the same interface as + gethostbyname3_r but the extra arguments the + latter takes are added at the end. So the + gethostbyname2_r code will just ignore them. */ + fct = __nss_lookup_function (nip, "gethostbyname2_r"); + + if (fct != NULL) { - __set_h_errno (NETDB_INTERNAL); - __set_errno (EBUSY); - break; - } - - no_data = 0; - nss_gethostbyname4_r *fct4 = NULL; - - /* gethostbyname4_r sends out parallel A and AAAA queries and - is thus only suitable for PF_UNSPEC. */ - if (req->ai_family == PF_UNSPEC) - fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); + struct gaih_addrtuple **pat = &res.at; - if (fct4 != NULL) - { - while (1) + if (req->ai_family == AF_INET6 + || req->ai_family == AF_UNSPEC) { - status = DL_CALL_FCT (fct4, (name, &at, - tmpbuf->data, tmpbuf->length, - &errno, &h_errno, - NULL)); - if (status == NSS_STATUS_SUCCESS) - break; - /* gethostbyname4_r may write into AT, so reset it. */ - at = NULL; - if (status != NSS_STATUS_TRYAGAIN - || errno != ERANGE || h_errno != NETDB_INTERNAL) - { - if (h_errno == TRY_AGAIN) - no_data = EAI_AGAIN; - else - no_data = h_errno == NO_DATA; - break; - } + gethosts (AF_INET6); + no_inet6_data = no_data; + inet6_status = status; + } + if (req->ai_family == AF_INET + || req->ai_family == AF_UNSPEC + || (req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) + /* Avoid generating the mapped addresses if we + know we are not going to need them. */ + && ((req->ai_flags & AI_ALL) || !got_ipv6))) + { + gethosts (AF_INET); - if (!scratch_buffer_grow (tmpbuf)) + if (req->ai_family == AF_INET) { - __resolv_context_put (res_ctx); - result = -EAI_MEMORY; - goto free_and_return; + no_inet6_data = no_data; + inet6_status = status; } } - if (status == NSS_STATUS_SUCCESS) + /* If we found one address for AF_INET or AF_INET6, + don't continue the search. */ + if (inet6_status == NSS_STATUS_SUCCESS + || status == NSS_STATUS_SUCCESS) { - assert (!no_data); - no_data = 1; - - if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) + if ((req->ai_flags & AI_CANONNAME) != 0 + && res.canon == NULL) { - char *canonbuf = __strdup (at->name); + char *canonbuf = getcanonname (nip, res.at, name); if (canonbuf == NULL) { __resolv_context_put (res_ctx); result = -EAI_MEMORY; goto free_and_return; } - canon = canonbuf; - } - - struct gaih_addrtuple **pat = &at; - - while (*pat != NULL) - { - if ((*pat)->family == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) != 0) - { - uint32_t *pataddr = (*pat)->addr; - (*pat)->family = AF_INET6; - pataddr[3] = pataddr[0]; - pataddr[2] = htonl (0xffff); - pataddr[1] = 0; - pataddr[0] = 0; - pat = &((*pat)->next); - no_data = 0; - } - else if (req->ai_family == AF_UNSPEC - || (*pat)->family == req->ai_family) - { - pat = &((*pat)->next); - - no_data = 0; - if (req->ai_family == AF_INET6) - got_ipv6 = true; - } - else - *pat = ((*pat)->next); - } - } - - no_inet6_data = no_data; - } - else - { - nss_gethostbyname3_r *fct = NULL; - if (req->ai_flags & AI_CANONNAME) - /* No need to use this function if we do not look for - the canonical name. The function does not exist in - all NSS modules and therefore the lookup would - often fail. */ - fct = __nss_lookup_function (nip, "gethostbyname3_r"); - if (fct == NULL) - /* We are cheating here. The gethostbyname2_r - function does not have the same interface as - gethostbyname3_r but the extra arguments the - latter takes are added at the end. So the - gethostbyname2_r code will just ignore them. */ - fct = __nss_lookup_function (nip, "gethostbyname2_r"); - - if (fct != NULL) - { - struct gaih_addrtuple **pat = &at; - - if (req->ai_family == AF_INET6 - || req->ai_family == AF_UNSPEC) - { - gethosts (AF_INET6); - no_inet6_data = no_data; - inet6_status = status; - } - if (req->ai_family == AF_INET - || req->ai_family == AF_UNSPEC - || (req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) - /* Avoid generating the mapped addresses if we - know we are not going to need them. */ - && ((req->ai_flags & AI_ALL) || !got_ipv6))) - { - gethosts (AF_INET); - - if (req->ai_family == AF_INET) - { - no_inet6_data = no_data; - inet6_status = status; - } - } - - /* If we found one address for AF_INET or AF_INET6, - don't continue the search. */ - if (inet6_status == NSS_STATUS_SUCCESS - || status == NSS_STATUS_SUCCESS) - { - if ((req->ai_flags & AI_CANONNAME) != 0 - && canon == NULL) - { - char *canonbuf = getcanonname (nip, at, name); - if (canonbuf == NULL) - { - __resolv_context_put (res_ctx); - result = -EAI_MEMORY; - goto free_and_return; - } - canon = canonbuf; - } - status = NSS_STATUS_SUCCESS; - } - else - { - /* We can have different states for AF_INET and - AF_INET6. Try to find a useful one for both. */ - if (inet6_status == NSS_STATUS_TRYAGAIN) - status = NSS_STATUS_TRYAGAIN; - else if (status == NSS_STATUS_UNAVAIL - && inet6_status != NSS_STATUS_UNAVAIL) - status = inet6_status; + res.canon = canonbuf; } + status = NSS_STATUS_SUCCESS; } else { - /* Could not locate any of the lookup functions. - The NSS lookup code does not consistently set - errno, so we need to supply our own error - code here. The root cause could either be a - resource allocation failure, or a missing - service function in the DSO (so it should not - be listed in /etc/nsswitch.conf). Assume the - former, and return EBUSY. */ - status = NSS_STATUS_UNAVAIL; - __set_h_errno (NETDB_INTERNAL); - __set_errno (EBUSY); + /* We can have different states for AF_INET and + AF_INET6. Try to find a useful one for both. */ + if (inet6_status == NSS_STATUS_TRYAGAIN) + status = NSS_STATUS_TRYAGAIN; + else if (status == NSS_STATUS_UNAVAIL + && inet6_status != NSS_STATUS_UNAVAIL) + status = inet6_status; } } + else + { + /* Could not locate any of the lookup functions. + The NSS lookup code does not consistently set + errno, so we need to supply our own error + code here. The root cause could either be a + resource allocation failure, or a missing + service function in the DSO (so it should not + be listed in /etc/nsswitch.conf). Assume the + former, and return EBUSY. */ + status = NSS_STATUS_UNAVAIL; + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + } + } - if (nss_next_action (nip, status) == NSS_ACTION_RETURN) - break; + if (nss_next_action (nip, status) == NSS_ACTION_RETURN) + break; - /* The hosts database does not support MERGE. */ - if (nss_next_action (nip, status) == NSS_ACTION_MERGE) - do_merge = true; + /* The hosts database does not support MERGE. */ + if (nss_next_action (nip, status) == NSS_ACTION_MERGE) + do_merge = true; - nip++; - if (nip->module == NULL) - no_more = -1; - } + nip++; + if (nip->module == NULL) + no_more = -1; + } - __resolv_context_put (res_ctx); + __resolv_context_put (res_ctx); - /* If we have a failure which sets errno, report it using - EAI_SYSTEM. */ - if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) - && h_errno == NETDB_INTERNAL) - { - result = -EAI_SYSTEM; - goto free_and_return; - } + /* If we have a failure which sets errno, report it using + EAI_SYSTEM. */ + if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) + && h_errno == NETDB_INTERNAL) + { + result = -EAI_SYSTEM; + goto free_and_return; + } - if (no_data != 0 && no_inet6_data != 0) - { - /* If both requests timed out report this. */ - if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) - result = -EAI_AGAIN; - else - /* We made requests but they turned out no data. The name - is known, though. */ - result = -EAI_NODATA; + if (no_data != 0 && no_inet6_data != 0) + { + /* If both requests timed out report this. */ + if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. The name + is known, though. */ + result = -EAI_NODATA; - goto free_and_return; - } + goto free_and_return; } process_list: - if (at == NULL) + if (res.at == NULL) { result = -EAI_NONAME; goto free_and_return; @@ -1031,21 +1043,22 @@ gaih_inet (const char *name, const struct gaih_service *service, else { struct gaih_addrtuple *atr; - atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); - memset (at, '\0', sizeof (struct gaih_addrtuple)); + atr = res.at = alloca_account (sizeof (struct gaih_addrtuple), + alloca_used); + memset (res.at, '\0', sizeof (struct gaih_addrtuple)); if (req->ai_family == AF_UNSPEC) { - at->next = __alloca (sizeof (struct gaih_addrtuple)); - memset (at->next, '\0', sizeof (struct gaih_addrtuple)); + res.at->next = __alloca (sizeof (struct gaih_addrtuple)); + memset (res.at->next, '\0', sizeof (struct gaih_addrtuple)); } if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) { - at->family = AF_INET6; + res.at->family = AF_INET6; if ((req->ai_flags & AI_PASSIVE) == 0) - memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr)); - atr = at->next; + memcpy (res.at->addr, &in6addr_loopback, sizeof (struct in6_addr)); + atr = res.at->next; } if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) @@ -1058,10 +1071,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) + if ((result = process_canonname (req, orig_name, &res)) != 0) goto free_and_return; - struct gaih_addrtuple *at2 = at; + struct gaih_addrtuple *at2 = res.at; size_t socklen; sa_family_t family; @@ -1104,8 +1117,8 @@ gaih_inet (const char *name, const struct gaih_service *service, ai->ai_addr = (void *) (ai + 1); /* We only add the canonical name once. */ - ai->ai_canonname = (char *) canon; - canon = NULL; + ai->ai_canonname = res.canon; + res.canon = NULL; #ifdef _HAVE_SA_LEN ai->ai_addr->sa_len = socklen; @@ -1151,7 +1164,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (malloc_name) free ((char *) name); free (addrmem); - free (canon); + free (res.canon); return result; } From patchwork Tue Mar 8 10:07:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602861 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=dEBvOABD; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWMK1tH9z9sGL for ; Tue, 8 Mar 2022 21:11:41 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 41E59385AC24 for ; Tue, 8 Mar 2022 10:11:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 41E59385AC24 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734299; bh=XoY01rsMxAM1MpJeAj/b66wXgDyV2dsMPktaudfY4pE=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=dEBvOABDl4PIhXz7lv/xmsVqJlBU4NDkaHM+VyeSMHqSSoB0XE3ayWkX9qM3jqRz4 1AyTR3HzAuFkbjajNW8JkKsI4OwvDOeRaRuxi29AmJSybRx25qVZEA8EFwtE4K7UHx P9MtgxZ/lIPSwLHkoMgOzKqITTc/3WJut3l1b2VM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from dormouse.elm.relay.mailchannels.net (dormouse.elm.relay.mailchannels.net [23.83.212.50]) by sourceware.org (Postfix) with ESMTPS id A644F3857820 for ; Tue, 8 Mar 2022 10:08:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A644F3857820 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 40B426C219B; Tue, 8 Mar 2022 10:08:23 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 059306C1F41; Tue, 8 Mar 2022 10:08:03 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734091; a=rsa-sha256; cv=none; b=iWzPCRQlnabRX/Hu5RvlaBBwNkuyHL+7Nj0LxVePTNLu0JUlLSEDY9aR/oUagA463jSrEa 6P0pkuMMhzxZBRnPQVXswM2q5N8n3oqMIlk89xi3WhVhg22nGMH8uGp22CGq9D6NYlCaQT C0z8OxYCqRi13n+6D2NWLqhosgIZnmrBZXlYaH3A1TeizsdV/K5H7GeKD1ddR2cWcoM5Z+ bhpS+tW59dJoNLJhvxQjkWDFEX0d50VY1ubDUYElO03aBTuk96inid4sr7xJvNCF5NWpUE XvPBaVuqt0gqmfXmOwbqaXBVi9pnWsf8xLj6UnWNxbphPn1Ww/vGmNo59MCf/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734091; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XoY01rsMxAM1MpJeAj/b66wXgDyV2dsMPktaudfY4pE=; b=SVOQXUzbHMwXsrB9bgAMPIK5Gl6dzvxL6zZyuXRZAwcHTC9woUZdYMd8OqsYJ5ru48Uji4 uXwZ5J3x2Ry5jL9nYoeE41TKPzhiOTcuW31S7wKcEUI6vB/9cif/1J6xNDgDi2a2tv8AH8 xlgtdSPJQZBe+n/XkRafJOci4YIWGLqPbu9d3sgVx3LJBX+WU/50m4UZmOpK4pbhYkjbTB r+DIf1Bo584lreUJ51Oqj7PVcUtNy7BIQTjj+VtwSmWK9cqaEIike4e8Psi4LAL5rRx4ex kQrpISFUAyBDrwiH+Tlzo2oTZIojPCz/mtcau1L6MYuctpYLq0dptMJTcjewxw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-c72dn; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.114.196.240 (trex/6.5.3); Tue, 08 Mar 2022 10:08:23 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Eight-Troubled: 272d76c716f488f6_1646734093022_1316427513 X-MC-Loop-Signature: 1646734093021:246370833 X-MC-Ingress-Time: 1646734093021 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGx25y2z1Qc; Tue, 8 Mar 2022 02:07:52 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 06/12] gaih_inet: Split simple gethostbyname into its own function Date: Tue, 8 Mar 2022 15:37:11 +0530 Message-Id: <20220308100717.1006126-7-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Add a free_at flag in gaih_result to indicate if res.at needs to be freed by the caller. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 125 ++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 868c7d222f..2024464f52 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -120,6 +120,7 @@ struct gaih_result { struct gaih_addrtuple *at; char *canon; + bool free_at; }; /* Values for `protoflag'. */ @@ -565,6 +566,60 @@ out: return result; } +/* If possible, call the simple, old functions, which do not support IPv6 scope + ids, nor retrieving the canonical name. */ + +static int +try_simple_gethostbyname (const char *name, const struct addrinfo *req, + struct scratch_buffer *tmpbuf, + struct gaih_result *res) +{ + res->at = NULL; + + if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0) + return 0; + + int rc; + struct hostent th; + struct hostent *h; + + while (1) + { + rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data, + tmpbuf->length, &h, &h_errno); + if (rc != ERANGE || h_errno != NETDB_INTERNAL) + break; + if (!scratch_buffer_grow (tmpbuf)) + return -EAI_MEMORY; + } + + if (rc == 0) + { + if (h != NULL) + { + /* We found data, convert it. */ + if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, &res->at)) + return -EAI_MEMORY; + + res->free_at = true; + return 0; + } + if (h_errno == NO_DATA) + return -EAI_NODATA; + + return -EAI_NONAME; + } + + if (h_errno == NETDB_INTERNAL) + return -EAI_SYSTEM; + if (h_errno == TRY_AGAIN) + return -EAI_AGAIN; + + /* We made requests but they turned out no data. + The name is known, though. */ + return -EAI_NODATA; +} + static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, @@ -610,6 +665,11 @@ gaih_inet (const char *name, const struct gaih_service *service, else if (res.at != NULL) goto process_list; + if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; + int no_data = 0; int no_inet6_data = 0; nss_action_list nip; @@ -619,69 +679,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct resolv_context *res_ctx = NULL; bool do_merge = false; - /* If we do not have to look for IPv6 addresses or the canonical - name, use the simple, old functions, which do not support - IPv6 scope ids, nor retrieving the canonical name. */ - if (req->ai_family == AF_INET - && (req->ai_flags & AI_CANONNAME) == 0) - { - int rc; - struct hostent th; - struct hostent *h; - - while (1) - { - rc = __gethostbyname2_r (name, AF_INET, &th, - tmpbuf->data, tmpbuf->length, - &h, &h_errno); - if (rc != ERANGE || h_errno != NETDB_INTERNAL) - break; - if (!scratch_buffer_grow (tmpbuf)) - { - result = -EAI_MEMORY; - goto free_and_return; - } - } - - if (rc == 0) - { - if (h != NULL) - { - /* We found data, convert it. */ - if (!convert_hostent_to_gaih_addrtuple - (req, AF_INET, h, &addrmem)) - { - result = -EAI_MEMORY; - goto free_and_return; - } - res.at = addrmem; - } - else - { - if (h_errno == NO_DATA) - result = -EAI_NODATA; - else - result = -EAI_NONAME; - goto free_and_return; - } - } - else - { - if (h_errno == NETDB_INTERNAL) - result = -EAI_SYSTEM; - else if (h_errno == TRY_AGAIN) - result = -EAI_AGAIN; - else - /* We made requests but they turned out no data. - The name is known, though. */ - result = -EAI_NODATA; - - goto free_and_return; - } - - goto process_list; - } - #ifdef USE_NSCD if (__nss_not_use_nscd_hosts > 0 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) @@ -1164,6 +1161,8 @@ gaih_inet (const char *name, const struct gaih_service *service, if (malloc_name) free ((char *) name); free (addrmem); + if (res.free_at) + free (res.at); free (res.canon); return result; From patchwork Tue Mar 8 10:07:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602867 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=EuYcdWUL; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWRS5F6jz9sGL for ; Tue, 8 Mar 2022 21:15:16 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0BD16385AC2F for ; Tue, 8 Mar 2022 10:15:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0BD16385AC2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734514; bh=Rc9P7xrmB7nT8ZBhXRPoDzjEKLyEI0Tpzu80J6xinZ0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=EuYcdWUL8zqVbmbmlV18Kth0s1pUufAJkkqNhsnTzHf8x6jJXmLrZMrgjaCGix70q 1SNUML1a47gxCLpCWdBlO96GOM08F0/Dy3N9iajumPBlwzhSj6DXHcsXUEmf4U9JC6 8h0MLYWt+P5rVXSlpwIH/3rUGGaFxa6Ef2ktEmPc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cyan.elm.relay.mailchannels.net (cyan.elm.relay.mailchannels.net [23.83.212.47]) by sourceware.org (Postfix) with ESMTPS id B06FC3858032 for ; Tue, 8 Mar 2022 10:08:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B06FC3858032 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 94FC96222F7; Tue, 8 Mar 2022 10:08:30 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id BC2466222A7; Tue, 8 Mar 2022 10:08:03 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734107; a=rsa-sha256; cv=none; b=ASRftipNxMsYpPAmePw+rQIGGVWzBClTJP5HoN4TONATMFAvIF8xP10wFcx4i6HYhCdd3L or+u2kxwVrE42LdRZISk0lasoVigTmYjPGeP1OEKGtc58NTP7SRxWB2C/K9gEz4IVi1DeJ f5Aclu0d/KJgJK/YyUZBoI53sDAbcl+DVNqgjpFKSAa4z+bmXp3CaoEswGTkhnR9hT1jCg /FjG++I8twow00ucqSaHdarLduQZmzPkrGhYfK/lKmD1VxMMStNuQjLlx/6LgCAbAz1R8E c7pnBv2aepAMnBOdoocxFXWaqJDzH07X5/Tbv157diOwYB/wK1ow6e+syQXbOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734107; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Rc9P7xrmB7nT8ZBhXRPoDzjEKLyEI0Tpzu80J6xinZ0=; b=rpAesBKOkcXnHXqfeATLlE70JGw8kLTQBjMy5Rbx138RBNf8Q1JPYC2DooO9wqYjBnaMg0 qzd5t389/aWgDwIad3tPgN6IucikQ3/HLLpE3AZ3EIMfFRNJ1gz32s1mhoI4uVsBDHPhRj dPbE1wsVgY0BOXGVruM/XNPsuXPrny6U85i6K2wx3dMflmlM30vkZiPrcTsPSG1MFJQjJg /tJ3jcfmkY/PEacW5bwsChgkO8yOV++/5/Tm+kFTRIgZUt/koYiPxXIKFXXbqKDmYmfZoD VXQcuwHnKfq5nNgGW6Sc0fHUjwD6TbSNqREjsequq8/j89kev0CiU/B4Pic92w== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-ddjvc; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.106.113.23 (trex/6.5.3); Tue, 08 Mar 2022 10:08:30 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Exultant-Decisive: 33c0e1654d2905d9_1646734110204_1018798307 X-MC-Loop-Signature: 1646734110204:103352657 X-MC-Ingress-Time: 1646734110203 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWGz6vlHz1R3; Tue, 8 Mar 2022 02:07:55 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 07/12] gaih_inet: Split nscd lookup code into its own function. Date: Tue, 8 Mar 2022 15:37:12 +0530 Message-Id: <20220308100717.1006126-8-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.3 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_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Add a new member got_ipv6 to indicate if the results have an IPv6 result and use it instead of the local got_ipv6. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 248 +++++++++++++++++++----------------- 1 file changed, 134 insertions(+), 114 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 2024464f52..2ec5a7d76f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -121,6 +121,7 @@ struct gaih_result struct gaih_addrtuple *at; char *canon; bool free_at; + bool got_ipv6; }; /* Values for `protoflag'. */ @@ -316,7 +317,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, res.canon = canonbuf; \ } \ if (_family == AF_INET6 && *pat != NULL) \ - got_ipv6 = true; \ + res.got_ipv6 = true; \ } \ } @@ -467,6 +468,128 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req, return 0; } +#ifdef USE_NSCD +/* Query addresses from nscd cache, returning a non-zero value on error. + RES members have the lookup result; RES->AT is NULL if there were no errors + but also no results. */ + +static int +get_nscd_addresses (const char *name, const struct addrinfo *req, + struct gaih_result *res) +{ + if (__nss_not_use_nscd_hosts > 0 + && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) + __nss_not_use_nscd_hosts = 0; + + res->at = NULL; + + if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts]) + return 0; + + /* Try to use nscd. */ + struct nscd_ai_result *air = NULL; + int err = __nscd_getai (name, &air, &h_errno); + + if (__glibc_unlikely (air == NULL)) + { + /* The database contains a negative entry. */ + if (err == 0) + return -EAI_NONAME; + if (__nss_not_use_nscd_hosts == 0) + { + if (h_errno == NETDB_INTERNAL && errno == ENOMEM) + return -EAI_MEMORY; + if (h_errno == TRY_AGAIN) + return -EAI_AGAIN; + return -EAI_SYSTEM; + } + return 0; + } + + /* Transform into gaih_addrtuple list. */ + int result = 0; + char *addrs = air->addrs; + + struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree)); + struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at)); + if (at == NULL) + { + result = -EAI_MEMORY; + goto out; + } + + res->free_at = true; + + int count = 0; + for (int i = 0; i < air->naddrs; ++i) + { + socklen_t size = (air->family[i] == AF_INET + ? INADDRSZ : IN6ADDRSZ); + + if (!((air->family[i] == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) != 0) + || req->ai_family == AF_UNSPEC + || air->family[i] == req->ai_family)) + { + /* Skip over non-matching result. */ + addrs += size; + continue; + } + + if (air->family[i] == AF_INET && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED)) + { + at[count].family = AF_INET6; + at[count].addr[3] = *(uint32_t *) addrs; + at[count].addr[2] = htonl (0xffff); + } + else if (req->ai_family == AF_UNSPEC + || air->family[count] == req->ai_family) + { + at[count].family = air->family[count]; + memcpy (at[count].addr, addrs, size); + if (air->family[count] == AF_INET6) + res->got_ipv6 = true; + } + at[count].next = at + count + 1; + count++; + addrs += size; + } + + if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL) + { + char *canonbuf = __strdup (air->canon); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + + if (count == 0) + { + result = -EAI_NONAME; + goto out; + } + + at[count - 1].next = NULL; + + res->at = at; + +out: + free (air); + if (result != 0) + { + free (at); + res->free_at = false; + } + + return result; +} +#endif + /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and the function cannot determine a result, RES->AT is set to NULL and 0 @@ -628,7 +751,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_servtuple st[sizeof (gaih_inet_typeproto) / sizeof (struct gaih_typeproto)] = {0}; - bool got_ipv6 = false; const char *orig_name = name; /* Reserve stack memory for the scratch buffer in the getaddrinfo @@ -670,6 +792,13 @@ gaih_inet (const char *name, const struct gaih_service *service, else if (res.at != NULL) goto process_list; +#ifdef USE_NSCD + if ((result = get_nscd_addresses (name, req, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; +#endif + int no_data = 0; int no_inet6_data = 0; nss_action_list nip; @@ -679,115 +808,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct resolv_context *res_ctx = NULL; bool do_merge = false; -#ifdef USE_NSCD - if (__nss_not_use_nscd_hosts > 0 - && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) - __nss_not_use_nscd_hosts = 0; - - if (!__nss_not_use_nscd_hosts - && !__nss_database_custom[NSS_DBSIDX_hosts]) - { - /* Try to use nscd. */ - struct nscd_ai_result *air = NULL; - int err = __nscd_getai (name, &air, &h_errno); - if (air != NULL) - { - /* Transform into gaih_addrtuple list. */ - bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; - char *addrs = air->addrs; - - addrmem = calloc (air->naddrs, sizeof (*addrmem)); - if (addrmem == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - - struct gaih_addrtuple *addrfree = addrmem; - struct gaih_addrtuple **pat = &res.at; - - for (int i = 0; i < air->naddrs; ++i) - { - socklen_t size = (air->family[i] == AF_INET - ? INADDRSZ : IN6ADDRSZ); - - if (!((air->family[i] == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) != 0) - || req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family)) - { - /* Skip over non-matching result. */ - addrs += size; - continue; - } - - if (*pat == NULL) - { - *pat = addrfree++; - (*pat)->scopeid = 0; - } - uint32_t *pataddr = (*pat)->addr; - (*pat)->next = NULL; - if (added_canon || air->canon == NULL) - (*pat)->name = NULL; - else if (res.canon == NULL) - { - char *canonbuf = __strdup (air->canon); - if (canonbuf == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - res.canon = (*pat)->name = canonbuf; - } - - if (air->family[i] == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED)) - { - (*pat)->family = AF_INET6; - pataddr[3] = *(uint32_t *) addrs; - pataddr[2] = htonl (0xffff); - pataddr[1] = 0; - pataddr[0] = 0; - pat = &((*pat)->next); - added_canon = true; - } - else if (req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family) - { - (*pat)->family = air->family[i]; - memcpy (pataddr, addrs, size); - pat = &((*pat)->next); - added_canon = true; - if (air->family[i] == AF_INET6) - got_ipv6 = true; - } - addrs += size; - } - - free (air); - - goto process_list; - } - else if (err == 0) - /* The database contains a negative entry. */ - goto free_and_return; - else if (__nss_not_use_nscd_hosts == 0) - { - if (h_errno == NETDB_INTERNAL && errno == ENOMEM) - result = -EAI_MEMORY; - else if (h_errno == TRY_AGAIN) - result = -EAI_AGAIN; - else - result = -EAI_SYSTEM; - - goto free_and_return; - } - } -#endif - no_more = !__nss_database_get (nss_database_hosts, &nip); /* If we are looking for both IPv4 and IPv6 address we don't @@ -894,7 +914,7 @@ gaih_inet (const char *name, const struct gaih_service *service, no_data = 0; if (req->ai_family == AF_INET6) - got_ipv6 = true; + res.got_ipv6 = true; } else *pat = ((*pat)->next); @@ -937,7 +957,7 @@ gaih_inet (const char *name, const struct gaih_service *service, && (req->ai_flags & AI_V4MAPPED) /* Avoid generating the mapped addresses if we know we are not going to need them. */ - && ((req->ai_flags & AI_ALL) || !got_ipv6))) + && ((req->ai_flags & AI_ALL) || !res.got_ipv6))) { gethosts (AF_INET); @@ -1088,7 +1108,7 @@ gaih_inet (const char *name, const struct gaih_service *service, /* 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 + if (res.got_ipv6 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED && IN6_IS_ADDR_V4MAPPED (at2->addr)) goto ignore; From patchwork Tue Mar 8 10:07:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602868 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=Wtxun9Um; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWSM1dHzz9sGL for ; Tue, 8 Mar 2022 21:16:03 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D4A94385780C for ; Tue, 8 Mar 2022 10:16:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D4A94385780C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734560; bh=eyFHilxuvEdVKLz4gACaFsHSQpmOcm1mVcsoINcuwtM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Wtxun9UmvZ/y2rirq9N1cQUF9EyGqnqNlrUHKljVm3AR1bI/U/wv7aqJTt6YkleX2 40t8QJXSvnjHMFLsY2gkTAbXKi5vM+9V8XISn63JKtAAQ3toNX3DQxzXSov2cBzJGd Zke1lDHpoFKhqFk9oCkAm7Wb2sLCJB8uycsJlzJc= 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 639943857C72 for ; Tue, 8 Mar 2022 10:08:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 639943857C72 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 6FAD3281582; Tue, 8 Mar 2022 10:08:32 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id B1C0A2815DE; Tue, 8 Mar 2022 10:08:28 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734109; a=rsa-sha256; cv=none; b=VtXOdgbJA2Q5s49GPv2M/XrTTfe4lh/Wljffp96yfYpJnE+JoRMlOX9c/fMSHRltcYdZdC 8fUhcZ6pOY6hts4b824wO9lMtROQKxd4ZxfNI8PKNj9ilOGN22yrFg+zxQa42Gws8o47eP p3d3FOFRix7nXRDeYsZi5x+60Hh+9WtjHnV4X4dvfEtEHWBEuBzHTPnf/L91sVoct+9s0w sw+OQquWPGUUC+1HauDPLs/fk4C2fx2AEHv6sPNvLyMU/uoRU68voioH0mkfjrvF87Vo0n 2h7LZ+a12KT8RTSiWjlwOwpSYMDtFqueiFSVQWkgTUJ82dmBxmvro5MqZ2bfDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734109; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eyFHilxuvEdVKLz4gACaFsHSQpmOcm1mVcsoINcuwtM=; b=crv1pbJdZIc6a5X1BnZcNFBlSSHNizYCjDS7kGbtmu5oZqYXsaFDRBMdtttXmicINFkjHU r9TIHFvh6437W4UU3VkMSB42F8O8vff8yH1/PLxPGb+J4hGRkEggjLOiNltIhTW7hWrRIO baRqLbybjk3nxm2oIrP02rF/bbpBeyDy9BTcOUhM9KpaEQZ4PDtVzVErga/C1QuvDcw3C8 unEAwEPUpZSEBN8MsAExfha8KI5aWdBjhmqGMjGQjnGkCD4rWFR9R7A19FyD779D+VyT91 od5gLFRdXjXGAbhAE3sPYj/6hZ7IlfqIL3RBo5oBV1lGxyGUEQaIwSDi2JbM8A== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-67hct; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.126.0.48 (trex/6.5.3); Tue, 08 Mar 2022 10:08:32 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Plucky-Eight: 4ac70a5b4c66db1a_1646734112283_2763103591 X-MC-Loop-Signature: 1646734112283:2349782363 X-MC-Ingress-Time: 1646734112283 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWH24RmKz1Rh; Tue, 8 Mar 2022 02:07:58 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 08/12] gaih_inet: separate nss lookup loop into its own function Date: Tue, 8 Mar 2022 15:37:13 +0530 Message-Id: <20220308100717.1006126-9-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.3 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_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 566 ++++++++++++++++++------------------ 1 file changed, 288 insertions(+), 278 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 2ec5a7d76f..b30af6bb7b 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -159,6 +159,14 @@ static const struct addrinfo default_hints = .ai_next = NULL }; +static void +gaih_result_reset (struct gaih_result *res) +{ + if (res->free_at) + free (res->at); + free (res->canon); + memset (res, 0, sizeof (*res)); +} static int gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, @@ -195,15 +203,13 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, return 0; } -/* Convert struct hostent to a list of struct gaih_addrtuple objects. - h_name is not copied, and the struct hostent object must not be - deallocated prematurely. *RESULT must be NULL or a pointer to a - linked-list. The new addresses are appended at the end. */ +/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name + is not copied, and the struct hostent object must not be deallocated + prematurely. *RESULT must be NULL or a pointer to a linked-list. The new + addresses are appended at the end. */ static bool -convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, - int family, - struct hostent *h, - struct gaih_addrtuple **result) +convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, + struct hostent *h, struct gaih_result *res) { /* Count the number of addresses in h->h_addr_list. */ size_t count = 0; @@ -215,7 +221,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr)) return true; - struct gaih_addrtuple *array = *result; + struct gaih_addrtuple *array = res->at; size_t old = 0; while (array) @@ -224,12 +230,13 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, array = array->next; } - array = realloc (*result, (old + count) * sizeof (*array)); + array = res->at = realloc (res->at, (old + count) * sizeof (*array)); if (array == NULL) return false; - *result = array; + res->got_ipv6 = family == AF_INET6; + res->free_at = true; /* Update the next pointers on reallocation. */ for (size_t i = 0; i < old; i++) @@ -278,7 +285,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_MEMORY; \ - goto free_and_return; \ + goto out; \ } \ } \ if (status == NSS_STATUS_NOTFOUND \ @@ -288,7 +295,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto out; \ } \ if (h_errno == TRY_AGAIN) \ no_data = EAI_AGAIN; \ @@ -297,27 +304,24 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, } \ else if (status == NSS_STATUS_SUCCESS) \ { \ - if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \ + if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, res)) \ { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto out; \ } \ - *pat = addrmem; \ \ - if (localcanon != NULL && res.canon == NULL) \ + if (localcanon != NULL && res->canon == NULL) \ { \ char *canonbuf = __strdup (localcanon); \ if (canonbuf == NULL) \ { \ __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ - goto free_and_return; \ + goto out; \ } \ - res.canon = canonbuf; \ + res->canon = canonbuf; \ } \ - if (_family == AF_INET6 && *pat != NULL) \ - res.got_ipv6 = true; \ } \ } @@ -590,6 +594,260 @@ out: } #endif +static int +get_nss_addresses (const char *name, const struct addrinfo *req, + struct scratch_buffer *tmpbuf, struct gaih_result *res) +{ + int no_data = 0; + int no_inet6_data = 0; + nss_action_list nip; + enum nss_status inet6_status = NSS_STATUS_UNAVAIL; + enum nss_status status = NSS_STATUS_UNAVAIL; + int no_more; + struct resolv_context *res_ctx = NULL; + bool do_merge = false; + int result = 0; + + no_more = !__nss_database_get (nss_database_hosts, &nip); + + /* If we are looking for both IPv4 and IPv6 address we don't + want the lookup functions to automatically promote IPv4 + addresses to IPv6 addresses, so we use the no_inet6 + function variant. */ + res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + no_more = 1; + + while (!no_more) + { + /* Always start afresh; continue should discard previous results + and the hosts database does not support merge. */ + gaih_result_reset (res); + + if (do_merge) + { + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + break; + } + + no_data = 0; + nss_gethostbyname4_r *fct4 = NULL; + + /* gethostbyname4_r sends out parallel A and AAAA queries and + is thus only suitable for PF_UNSPEC. */ + if (req->ai_family == PF_UNSPEC) + fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); + + if (fct4 != NULL) + { + while (1) + { + status = DL_CALL_FCT (fct4, (name, &res->at, + tmpbuf->data, tmpbuf->length, + &errno, &h_errno, + NULL)); + if (status == NSS_STATUS_SUCCESS) + break; + /* gethostbyname4_r may write into AT, so reset it. */ + res->at = NULL; + if (status != NSS_STATUS_TRYAGAIN + || errno != ERANGE || h_errno != NETDB_INTERNAL) + { + if (h_errno == TRY_AGAIN) + no_data = EAI_AGAIN; + else + no_data = h_errno == NO_DATA; + break; + } + + if (!scratch_buffer_grow (tmpbuf)) + { + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto out; + } + } + + if (status == NSS_STATUS_SUCCESS) + { + assert (!no_data); + no_data = 1; + + if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL) + { + char *canonbuf = __strdup (res->at->name); + if (canonbuf == NULL) + { + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + + struct gaih_addrtuple **pat = &res->at; + + while (*pat != NULL) + { + if ((*pat)->family == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) != 0) + { + uint32_t *pataddr = (*pat)->addr; + (*pat)->family = AF_INET6; + pataddr[3] = pataddr[0]; + pataddr[2] = htonl (0xffff); + pataddr[1] = 0; + pataddr[0] = 0; + pat = &((*pat)->next); + no_data = 0; + } + else if (req->ai_family == AF_UNSPEC + || (*pat)->family == req->ai_family) + { + pat = &((*pat)->next); + + no_data = 0; + if (req->ai_family == AF_INET6) + res->got_ipv6 = true; + } + else + *pat = ((*pat)->next); + } + } + + no_inet6_data = no_data; + } + else + { + nss_gethostbyname3_r *fct = NULL; + if (req->ai_flags & AI_CANONNAME) + /* No need to use this function if we do not look for + the canonical name. The function does not exist in + all NSS modules and therefore the lookup would + often fail. */ + fct = __nss_lookup_function (nip, "gethostbyname3_r"); + if (fct == NULL) + /* We are cheating here. The gethostbyname2_r + function does not have the same interface as + gethostbyname3_r but the extra arguments the + latter takes are added at the end. So the + gethostbyname2_r code will just ignore them. */ + fct = __nss_lookup_function (nip, "gethostbyname2_r"); + + if (fct != NULL) + { + if (req->ai_family == AF_INET6 + || req->ai_family == AF_UNSPEC) + { + gethosts (AF_INET6); + no_inet6_data = no_data; + inet6_status = status; + } + if (req->ai_family == AF_INET + || req->ai_family == AF_UNSPEC + || (req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) + /* Avoid generating the mapped addresses if we + know we are not going to need them. */ + && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) + { + gethosts (AF_INET); + + if (req->ai_family == AF_INET) + { + no_inet6_data = no_data; + inet6_status = status; + } + } + + /* If we found one address for AF_INET or AF_INET6, + don't continue the search. */ + if (inet6_status == NSS_STATUS_SUCCESS + || status == NSS_STATUS_SUCCESS) + { + if ((req->ai_flags & AI_CANONNAME) != 0 + && res->canon == NULL) + { + char *canonbuf = getcanonname (nip, res->at, name); + if (canonbuf == NULL) + { + __resolv_context_put (res_ctx); + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + status = NSS_STATUS_SUCCESS; + } + else + { + /* We can have different states for AF_INET and + AF_INET6. Try to find a useful one for both. */ + if (inet6_status == NSS_STATUS_TRYAGAIN) + status = NSS_STATUS_TRYAGAIN; + else if (status == NSS_STATUS_UNAVAIL + && inet6_status != NSS_STATUS_UNAVAIL) + status = inet6_status; + } + } + else + { + /* Could not locate any of the lookup functions. + The NSS lookup code does not consistently set + errno, so we need to supply our own error + code here. The root cause could either be a + resource allocation failure, or a missing + service function in the DSO (so it should not + be listed in /etc/nsswitch.conf). Assume the + former, and return EBUSY. */ + status = NSS_STATUS_UNAVAIL; + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + } + } + + if (nss_next_action (nip, status) == NSS_ACTION_RETURN) + break; + + /* The hosts database does not support MERGE. */ + if (nss_next_action (nip, status) == NSS_ACTION_MERGE) + do_merge = true; + + nip++; + if (nip->module == NULL) + no_more = -1; + } + + __resolv_context_put (res_ctx); + + /* If we have a failure which sets errno, report it using + EAI_SYSTEM. */ + if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) + && h_errno == NETDB_INTERNAL) + { + result = -EAI_SYSTEM; + goto out; + } + + if (no_data != 0 && no_inet6_data != 0) + { + /* If both requests timed out report this. */ + if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. The name + is known, though. */ + result = -EAI_NODATA; + } + +out: + if (result != 0) + gaih_result_reset (res); + return result; +} + /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and the function cannot determine a result, RES->AT is set to NULL and 0 @@ -721,7 +979,7 @@ try_simple_gethostbyname (const char *name, const struct addrinfo *req, if (h != NULL) { /* We found data, convert it. */ - if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, &res->at)) + if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res)) return -EAI_MEMORY; res->free_at = true; @@ -799,263 +1057,14 @@ gaih_inet (const char *name, const struct gaih_service *service, goto process_list; #endif - int no_data = 0; - int no_inet6_data = 0; - nss_action_list nip; - enum nss_status inet6_status = NSS_STATUS_UNAVAIL; - enum nss_status status = NSS_STATUS_UNAVAIL; - int no_more; - struct resolv_context *res_ctx = NULL; - bool do_merge = false; - - no_more = !__nss_database_get (nss_database_hosts, &nip); - - /* If we are looking for both IPv4 and IPv6 address we don't - want the lookup functions to automatically promote IPv4 - addresses to IPv6 addresses, so we use the no_inet6 - function variant. */ - res_ctx = __resolv_context_get (); - if (res_ctx == NULL) - no_more = 1; - - while (!no_more) - { - /* Always start afresh; continue should discard previous results - and the hosts database does not support merge. */ - res.at = NULL; - free (res.canon); - free (addrmem); - res.canon = NULL; - addrmem = NULL; - - if (do_merge) - { - __set_h_errno (NETDB_INTERNAL); - __set_errno (EBUSY); - break; - } - - no_data = 0; - nss_gethostbyname4_r *fct4 = NULL; - - /* gethostbyname4_r sends out parallel A and AAAA queries and - is thus only suitable for PF_UNSPEC. */ - if (req->ai_family == PF_UNSPEC) - fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); - - if (fct4 != NULL) - { - while (1) - { - status = DL_CALL_FCT (fct4, (name, &res.at, - tmpbuf->data, tmpbuf->length, - &errno, &h_errno, - NULL)); - if (status == NSS_STATUS_SUCCESS) - break; - /* gethostbyname4_r may write into AT, so reset it. */ - res.at = NULL; - if (status != NSS_STATUS_TRYAGAIN - || errno != ERANGE || h_errno != NETDB_INTERNAL) - { - if (h_errno == TRY_AGAIN) - no_data = EAI_AGAIN; - else - no_data = h_errno == NO_DATA; - break; - } - - if (!scratch_buffer_grow (tmpbuf)) - { - __resolv_context_put (res_ctx); - result = -EAI_MEMORY; - goto free_and_return; - } - } - - if (status == NSS_STATUS_SUCCESS) - { - assert (!no_data); - no_data = 1; - - if ((req->ai_flags & AI_CANONNAME) != 0 && res.canon == NULL) - { - char *canonbuf = __strdup (res.at->name); - if (canonbuf == NULL) - { - __resolv_context_put (res_ctx); - result = -EAI_MEMORY; - goto free_and_return; - } - res.canon = canonbuf; - } - - struct gaih_addrtuple **pat = &res.at; - - while (*pat != NULL) - { - if ((*pat)->family == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) != 0) - { - uint32_t *pataddr = (*pat)->addr; - (*pat)->family = AF_INET6; - pataddr[3] = pataddr[0]; - pataddr[2] = htonl (0xffff); - pataddr[1] = 0; - pataddr[0] = 0; - pat = &((*pat)->next); - no_data = 0; - } - else if (req->ai_family == AF_UNSPEC - || (*pat)->family == req->ai_family) - { - pat = &((*pat)->next); - - no_data = 0; - if (req->ai_family == AF_INET6) - res.got_ipv6 = true; - } - else - *pat = ((*pat)->next); - } - } - - no_inet6_data = no_data; - } - else - { - nss_gethostbyname3_r *fct = NULL; - if (req->ai_flags & AI_CANONNAME) - /* No need to use this function if we do not look for - the canonical name. The function does not exist in - all NSS modules and therefore the lookup would - often fail. */ - fct = __nss_lookup_function (nip, "gethostbyname3_r"); - if (fct == NULL) - /* We are cheating here. The gethostbyname2_r - function does not have the same interface as - gethostbyname3_r but the extra arguments the - latter takes are added at the end. So the - gethostbyname2_r code will just ignore them. */ - fct = __nss_lookup_function (nip, "gethostbyname2_r"); - - if (fct != NULL) - { - struct gaih_addrtuple **pat = &res.at; - - if (req->ai_family == AF_INET6 - || req->ai_family == AF_UNSPEC) - { - gethosts (AF_INET6); - no_inet6_data = no_data; - inet6_status = status; - } - if (req->ai_family == AF_INET - || req->ai_family == AF_UNSPEC - || (req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) - /* Avoid generating the mapped addresses if we - know we are not going to need them. */ - && ((req->ai_flags & AI_ALL) || !res.got_ipv6))) - { - gethosts (AF_INET); - - if (req->ai_family == AF_INET) - { - no_inet6_data = no_data; - inet6_status = status; - } - } - - /* If we found one address for AF_INET or AF_INET6, - don't continue the search. */ - if (inet6_status == NSS_STATUS_SUCCESS - || status == NSS_STATUS_SUCCESS) - { - if ((req->ai_flags & AI_CANONNAME) != 0 - && res.canon == NULL) - { - char *canonbuf = getcanonname (nip, res.at, name); - if (canonbuf == NULL) - { - __resolv_context_put (res_ctx); - result = -EAI_MEMORY; - goto free_and_return; - } - res.canon = canonbuf; - } - status = NSS_STATUS_SUCCESS; - } - else - { - /* We can have different states for AF_INET and - AF_INET6. Try to find a useful one for both. */ - if (inet6_status == NSS_STATUS_TRYAGAIN) - status = NSS_STATUS_TRYAGAIN; - else if (status == NSS_STATUS_UNAVAIL - && inet6_status != NSS_STATUS_UNAVAIL) - status = inet6_status; - } - } - else - { - /* Could not locate any of the lookup functions. - The NSS lookup code does not consistently set - errno, so we need to supply our own error - code here. The root cause could either be a - resource allocation failure, or a missing - service function in the DSO (so it should not - be listed in /etc/nsswitch.conf). Assume the - former, and return EBUSY. */ - status = NSS_STATUS_UNAVAIL; - __set_h_errno (NETDB_INTERNAL); - __set_errno (EBUSY); - } - } - - if (nss_next_action (nip, status) == NSS_ACTION_RETURN) - break; - - /* The hosts database does not support MERGE. */ - if (nss_next_action (nip, status) == NSS_ACTION_MERGE) - do_merge = true; - - nip++; - if (nip->module == NULL) - no_more = -1; - } - - __resolv_context_put (res_ctx); - - /* If we have a failure which sets errno, report it using - EAI_SYSTEM. */ - if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) - && h_errno == NETDB_INTERNAL) - { - result = -EAI_SYSTEM; - goto free_and_return; - } - - if (no_data != 0 && no_inet6_data != 0) - { - /* If both requests timed out report this. */ - if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) - result = -EAI_AGAIN; - else - /* We made requests but they turned out no data. The name - is known, though. */ - result = -EAI_NODATA; - - goto free_and_return; - } + if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; - process_list: - if (res.at == NULL) - { - result = -EAI_NONAME; - goto free_and_return; - } + /* None of the lookups worked, so name not found. */ + result = -EAI_NONAME; + goto free_and_return; } else { @@ -1086,6 +1095,7 @@ gaih_inet (const char *name, const struct gaih_service *service, } } +process_list: { /* Set up the canonical name if we need it. */ if ((result = process_canonname (req, orig_name, &res)) != 0) From patchwork Tue Mar 8 10:07:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602863 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=DsJJz6aO; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWNx30PKz9sGL for ; Tue, 8 Mar 2022 21:13:05 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6E985385780C for ; Tue, 8 Mar 2022 10:13:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6E985385780C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734383; bh=WRYrl8OSjLLE/kqYDzQntKueFh2kHSPW+bYxvTEOqOo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=DsJJz6aOcro1EnvRcGSob9GqbWpKxSgAgi7sHZa/zpW0U1xgi7Sp4CvSTM4JpMXK3 H81W+KQLA6RZztbNKqPxOkLhQn6o7PjtuNoexEinrVHDUXNEJs0mqgN5hplTCOtp2n Vp0DP4mONbJNOaUs86Zi8DxrcgTVTQrWzYMHy/wY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from purple.birch.relay.mailchannels.net (purple.birch.relay.mailchannels.net [23.83.209.150]) by sourceware.org (Postfix) with ESMTPS id 5143B385AC27 for ; Tue, 8 Mar 2022 10:08:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5143B385AC27 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 3D864281731; Tue, 8 Mar 2022 10:08:28 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 943A6281619; Tue, 8 Mar 2022 10:08:04 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.126.0.48 (trex/6.5.3); Tue, 08 Mar 2022 10:08:28 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Wide-Eyed-Bubble: 2a3a05c362fd825e_1646734107306_687420660 X-MC-Loop-Signature: 1646734107306:4016046609 X-MC-Ingress-Time: 1646734107306 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWH522ckz1QK; Tue, 8 Mar 2022 02:08:00 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 09/12] gaih_inet: make gethosts into a function Date: Tue, 8 Mar 2022 15:37:14 +0530 Message-Id: <20220308100717.1006126-10-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" The macro is quite a pain to debug, so make gethosts into a function to make it easier to maintain. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 117 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index b30af6bb7b..81710632cb 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -268,63 +268,54 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, return true; } -#define gethosts(_family) \ - { \ - struct hostent th; \ - char *localcanon = NULL; \ - no_data = 0; \ - while (1) \ - { \ - status = DL_CALL_FCT (fct, (name, _family, &th, \ - tmpbuf->data, tmpbuf->length, \ - &errno, &h_errno, NULL, &localcanon)); \ - if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \ - || errno != ERANGE) \ - break; \ - if (!scratch_buffer_grow (tmpbuf)) \ - { \ - __resolv_context_put (res_ctx); \ - result = -EAI_MEMORY; \ - goto out; \ - } \ - } \ - if (status == NSS_STATUS_NOTFOUND \ - || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \ - { \ - if (h_errno == NETDB_INTERNAL) \ - { \ - __resolv_context_put (res_ctx); \ - result = -EAI_SYSTEM; \ - goto out; \ - } \ - if (h_errno == TRY_AGAIN) \ - no_data = EAI_AGAIN; \ - else \ - no_data = h_errno == NO_DATA; \ - } \ - else if (status == NSS_STATUS_SUCCESS) \ - { \ - if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, res)) \ - { \ - __resolv_context_put (res_ctx); \ - result = -EAI_SYSTEM; \ - goto out; \ - } \ - \ - if (localcanon != NULL && res->canon == NULL) \ - { \ - char *canonbuf = __strdup (localcanon); \ - if (canonbuf == NULL) \ - { \ - __resolv_context_put (res_ctx); \ - result = -EAI_SYSTEM; \ - goto out; \ - } \ - res->canon = canonbuf; \ - } \ - } \ - } +static int +gethosts (nss_gethostbyname3_r fct, int family, const char *name, + const struct addrinfo *req, struct scratch_buffer *tmpbuf, + struct gaih_result *res, enum nss_status *statusp, int *no_datap) +{ + struct hostent th; + char *localcanon = NULL; + enum nss_status status; + + *no_datap = 0; + while (1) + { + *statusp = status = DL_CALL_FCT (fct, (name, family, &th, + tmpbuf->data, tmpbuf->length, + &errno, &h_errno, NULL, + &localcanon)); + if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL + || errno != ERANGE) + break; + if (!scratch_buffer_grow (tmpbuf)) + return -EAI_MEMORY; + } + if (status == NSS_STATUS_NOTFOUND + || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) + { + if (h_errno == NETDB_INTERNAL) + return -EAI_SYSTEM; + if (h_errno == TRY_AGAIN) + *no_datap = EAI_AGAIN; + else + *no_datap = h_errno == NO_DATA; + } + else if (status == NSS_STATUS_SUCCESS) + { + if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res)) + return -EAI_SYSTEM; + + if (localcanon != NULL && res->canon == NULL) + { + char *canonbuf = __strdup (localcanon); + if (canonbuf == NULL) + return -EAI_SYSTEM; + res->canon = canonbuf; + } + } + return 0; +} /* This function is called if a canonical name is requested, but if the service function did not provide it. It tries to obtain the @@ -741,7 +732,12 @@ get_nss_addresses (const char *name, const struct addrinfo *req, if (req->ai_family == AF_INET6 || req->ai_family == AF_UNSPEC) { - gethosts (AF_INET6); + if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf, + res, &status, &no_data)) != 0) + { + __resolv_context_put (res_ctx); + goto out; + } no_inet6_data = no_data; inet6_status = status; } @@ -753,7 +749,12 @@ get_nss_addresses (const char *name, const struct addrinfo *req, know we are not going to need them. */ && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) { - gethosts (AF_INET); + if ((result = gethosts (fct, AF_INET, name, req, tmpbuf, + res, &status, &no_data)) != 0) + { + __resolv_context_put (res_ctx); + goto out; + } if (req->ai_family == AF_INET) { From patchwork Tue Mar 8 10:07:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602870 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=EqwPvSnP; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWVr5DC5z9sGT for ; Tue, 8 Mar 2022 21:18:12 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D195D385B829 for ; Tue, 8 Mar 2022 10:18:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D195D385B829 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734690; bh=uND44+mud2dgTpaqyPysZfEtjD87ad4UatThbz3HHfI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=EqwPvSnPZXq3xuKLHvNomJkuXQefNVcf9WdltYMA92GqiNHpYLsgYBMdkGF+cE108 c2J0e79dOX8z4OL1BwUQTrG3wyBpy9F2LQOKxsY31AkGKD5sBqlUsQNtjiI83RbgJk nrUcKaeOEATjfX9Dk/62FE0ToqPazkg2fSFqvVhQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from quail.birch.relay.mailchannels.net (quail.birch.relay.mailchannels.net [23.83.209.151]) by sourceware.org (Postfix) with ESMTPS id 2DDAE385AC34 for ; Tue, 8 Mar 2022 10:14:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2DDAE385AC34 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 F27F8622339; Tue, 8 Mar 2022 10:08:24 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id C1850622278; Tue, 8 Mar 2022 10:08:11 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734091; a=rsa-sha256; cv=none; b=Lx+qqsO5QPE7aeMUy9nXlBWGCFilCS2G3OENykNFR+kAcSDFX4Hi5VPSMoLwaicc1cx7hw rY2yTuC4lk2Hqiv5IIg4uXuAzO0N7e60+AI9LItVQVfuP7citH5dR2ycKSmCrl0iTW5Yad Jc9uYW0/LguAswys8/shcYs4zSa+tx4gTqWpmXyzrWQUZz6zar7z3SGrm4ibWExWFqE2zw cyqsRcKwU8UmzTshxA1yOxgNslb97gbu8BM08gvmZcE7o+UqPsUYRGrHkJAkBSQLo/MQot E5tcB4A8ZXfDMLJrLO1BCSqrEuRlsf8idOrLoz+/sTSlY117wQJ8i9n1kUjKYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734091; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uND44+mud2dgTpaqyPysZfEtjD87ad4UatThbz3HHfI=; b=p1hSHqvnWLZpgHzTiUx5WJEiDazRRZ3dc9v1C8BwIYCR172HmPmWN77vlei0UaDTNWnJ+A TLI3ahwHLYUCG6GM9NaMp3aSWDqyq4muMw4CU8Wf60sQEwQsQ+UYlW+xG6kYOIfpO7PQcR Fu6aC7rB2e0aHjdTSsXulbsY6oZwUOVor7CT+jdxydjBgpkJ8bvl/yg/zpGg6Rx02eAHY7 JPt/jyRc27PTNjR6NUg8yE6ZawPVCeBUlGLZGCdn5OhgEZKTMdDOb1FLJqRfyg4FmHOgdb cwcxOFLv9HWDsXntuxAGQiosC39RqTxS3z8BLcRKGBculRK7N1YIezDCyXNp8Q== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-pqcdc; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.103.158.113 (trex/6.5.3); Tue, 08 Mar 2022 10:08:24 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Cellar-Arch: 03640590417b7c24_1646734094870_565974649 X-MC-Loop-Signature: 1646734094870:3349729816 X-MC-Ingress-Time: 1646734094870 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWH816fWz1PZ; Tue, 8 Mar 2022 02:08:03 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 10/12] gaih_inet: split loopback lookup into its own function Date: Tue, 8 Mar 2022 15:37:15 +0530 Message-Id: <20220308100717.1006126-11-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Flatten the condition nesting and replace the alloca for RET.AT/ATR with a single array LOCAL_AT[2]. This gets rid of alloca and alloca accounting. `git diff -b` is probably the best way to view this change since much of the diff is whitespace changes. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 127 ++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 81710632cb..7258fa6f7e 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1002,6 +1002,32 @@ try_simple_gethostbyname (const char *name, const struct addrinfo *req, return -EAI_NODATA; } +/* Add local address information into RES. RES->AT is assumed to have enough + space for two tuples and is zeroed out. */ + +static void +get_local_addresses (const struct addrinfo *req, struct gaih_result *res) +{ + struct gaih_addrtuple *atr = res->at; + if (req->ai_family == AF_UNSPEC) + res->at->next = res->at + 1; + + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + { + res->at->family = AF_INET6; + if ((req->ai_flags & AI_PASSIVE) == 0) + memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr)); + atr = res->at->next; + } + + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) + { + atr->family = AF_INET; + if ((req->ai_flags & AI_PASSIVE) == 0) + atr->addr[0] = htonl (INADDR_LOOPBACK); + } +} + static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, @@ -1012,10 +1038,6 @@ gaih_inet (const char *name, const struct gaih_service *service, const char *orig_name = name; - /* Reserve stack memory for the scratch buffer in the getaddrinfo - function. */ - size_t alloca_used = sizeof (struct scratch_buffer); - int rc; if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0) return rc; @@ -1025,76 +1047,51 @@ gaih_inet (const char *name, const struct gaih_service *service, int result = 0; struct gaih_result res = {0}; - if (name != NULL) + struct gaih_addrtuple local_at[2] = {0}; + + res.at = local_at; + + if (__glibc_unlikely (name == NULL)) { - if (req->ai_flags & AI_IDN) - { - char *out; - result = __idna_to_dns_encoding (name, &out); - if (result != 0) - return -result; - name = out; - malloc_name = true; - } + get_local_addresses (req, &res); + goto process_list; + } - res.at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); - res.at->scopeid = 0; - res.at->next = NULL; + if (req->ai_flags & AI_IDN) + { + char *out; + result = __idna_to_dns_encoding (name, &out); + if (result != 0) + return -result; + name = out; + malloc_name = true; + } - if ((result = text_to_binary_address (name, req, &res)) != 0) - goto free_and_return; - else if (res.at != NULL) - goto process_list; + if ((result = text_to_binary_address (name, req, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; - if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0) - goto free_and_return; - else if (res.at != NULL) - goto process_list; + if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; #ifdef USE_NSCD - if ((result = get_nscd_addresses (name, req, &res)) != 0) - goto free_and_return; - else if (res.at != NULL) - goto process_list; + if ((result = get_nscd_addresses (name, req, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; #endif - if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0) - goto free_and_return; - else if (res.at != NULL) - goto process_list; - - /* None of the lookups worked, so name not found. */ - result = -EAI_NONAME; - goto free_and_return; - } - else - { - struct gaih_addrtuple *atr; - atr = res.at = alloca_account (sizeof (struct gaih_addrtuple), - alloca_used); - memset (res.at, '\0', sizeof (struct gaih_addrtuple)); - - if (req->ai_family == AF_UNSPEC) - { - res.at->next = __alloca (sizeof (struct gaih_addrtuple)); - memset (res.at->next, '\0', sizeof (struct gaih_addrtuple)); - } - - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - { - res.at->family = AF_INET6; - if ((req->ai_flags & AI_PASSIVE) == 0) - memcpy (res.at->addr, &in6addr_loopback, sizeof (struct in6_addr)); - atr = res.at->next; - } + if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) - { - atr->family = AF_INET; - if ((req->ai_flags & AI_PASSIVE) == 0) - atr->addr[0] = htonl (INADDR_LOOPBACK); - } - } + /* None of the lookups worked, so name not found. */ + result = -EAI_NONAME; + goto free_and_return; process_list: { From patchwork Tue Mar 8 10:07:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602862 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=kmTObS7d; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWN71t68z9sGL for ; Tue, 8 Mar 2022 21:12:23 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5B8273857820 for ; Tue, 8 Mar 2022 10:12:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B8273857820 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734341; bh=Hh3n/bUeuR/ivM3uJkPb0kkSjz/iunzNun7yMJVrlVQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=kmTObS7dB9D5y9x3owdKIsPEeSFO2SrM6pwjCgwztNMpW/85Y0gxUfjpnLhWm6IXG TSefstAZlV/VxxN97568wNVX6igQlzMqrPwBa2MvXY9l1Heyj1oU8lEj9NufhbJLHK RVUNGPmLLA6LCMXaYWbJopqjr9mLFjB4pc3yGEg4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from dog.birch.relay.mailchannels.net (dog.birch.relay.mailchannels.net [23.83.209.48]) by sourceware.org (Postfix) with ESMTPS id D862A385AC2D for ; Tue, 8 Mar 2022 10:08:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D862A385AC2D 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 4D6DA281D5D; Tue, 8 Mar 2022 10:08:27 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 919A0281C6E; Tue, 8 Mar 2022 10:08:11 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734106; a=rsa-sha256; cv=none; b=kAWVBCpp9FA+WH/ND4eb1vyJBdNoIuZCRmnnSaZC4EzZkj9uTBdGJ7HrCkEmwjjspV8sTA PluB9KAV8BzYY3QDkVDvtlWX+nQUo/jne0HP+doT4Gq1C2gvJPaSmpe34A2hWbWfVyIVY3 D8d1qnlMqHmupwROn0B8++cAQoJH04HnywHnHM/lI9h30Sm1Rja8Yp7d6sQwy7wnGj2kpa CcYKE1sRRNIyaez6tj4Rz+oCaYEhlERTNRlCs/E4RuhrICzT5oxUPxEq4d8iCsvRMbs/r+ MN7j5dOQHoMDaDgFjTxCse0qpdPKHTmT5wpRvsIvTpdjW6sjwKNFYSOuP1EUyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734106; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Hh3n/bUeuR/ivM3uJkPb0kkSjz/iunzNun7yMJVrlVQ=; b=ZkqzAnQFSn4YO3HnvGVi9qT4cNKkaHGss8fIVAFBOOuZXaWJFQzvuCJJcljpCRMFncTtka E1WC06R9BuW24NN7tskYU5U6AQvrxC7dZuHq5R+DPAg5k/+CTYje9brm2Gpqf4Y3LF1ejM 2v8borFPoIagenoSogvg+R4hcAV/kGcaGttLowflX8rttBNFG3IgD+F2FLr84HUFOB1ivX SbBDUgq3muiyVyEPsMFAlUa6h3bX9dGI5ao7bW5VYa7hbcXl2hBZ7x4lrkZ5O1IxH4J53A ult+dzYpvwvsjoRc5TT8ZOxmCdh2MVuqLSauzd7StY+KmgDjA1jiRtm4pvXX3w== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-6rkcb; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.114.196.240 (trex/6.5.3); Tue, 08 Mar 2022 10:08:27 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Belong-Minister: 39aa3dac7dc2904b_1646734107144_2332377655 X-MC-Loop-Signature: 1646734107144:2415872622 X-MC-Ingress-Time: 1646734107144 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWHB5rj6z1Nj; Tue, 8 Mar 2022 02:08:06 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 11/12] gaih_inet: Split result generation into its own function Date: Tue, 8 Mar 2022 15:37:16 +0530 Message-Id: <20220308100717.1006126-12-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Simplify the loop a wee bit and clean up variable names too. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 176 ++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 90 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 7258fa6f7e..6cbbd5dac1 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1028,6 +1028,87 @@ get_local_addresses (const struct addrinfo *req, struct gaih_result *res) } } +/* Generate results in PAI and its count in NADDRS. Return 0 on success or an + error code on failure. */ + +static int +generate_addrinfo (const struct addrinfo *req, struct gaih_result *res, + const struct gaih_servtuple *st, struct addrinfo **pai, + unsigned int *naddrs) +{ + size_t socklen; + sa_family_t family; + + /* Buffer is the size of an unformatted IPv6 address in printable format. */ + for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next) + { + family = at->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 (res->got_ipv6 + && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED + && IN6_IS_ADDR_V4MAPPED (at->addr)) + continue; + } + else + socklen = sizeof (struct sockaddr_in); + + for (int i = 0; st[i].set; i++) + { + struct addrinfo *ai; + ai = *pai = malloc (sizeof (struct addrinfo) + socklen); + if (ai == NULL) + return -EAI_MEMORY; + + ai->ai_flags = req->ai_flags; + ai->ai_family = family; + ai->ai_socktype = st[i].socktype; + ai->ai_protocol = st[i].protocol; + ai->ai_addrlen = socklen; + ai->ai_addr = (void *) (ai + 1); + + /* We only add the canonical name once. */ + ai->ai_canonname = res->canon; + res->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 = st[i].port; + sin6p->sin6_flowinfo = 0; + memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr)); + sin6p->sin6_scope_id = at->scopeid; + } + else + { + struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr; + sinp->sin_port = st[i].port; + memcpy (&sinp->sin_addr, at->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, @@ -1094,98 +1175,13 @@ gaih_inet (const char *name, const struct gaih_service *service, goto free_and_return; process_list: - { - /* Set up the canonical name if we need it. */ - if ((result = process_canonname (req, orig_name, &res)) != 0) - goto free_and_return; - - struct gaih_addrtuple *at2 = res.at; - size_t socklen; - sa_family_t family; - - /* - buffer is the size of an unformatted IPv6 address in printable format. - */ - while (at2 != NULL) - { - 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 (res.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 (int i = 0; st[i].set; i++) - { - struct addrinfo *ai; - ai = *pai = malloc (sizeof (struct addrinfo) + socklen); - if (ai == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - - ai->ai_flags = req->ai_flags; - ai->ai_family = family; - ai->ai_socktype = st[i].socktype; - ai->ai_protocol = st[i].protocol; - ai->ai_addrlen = socklen; - ai->ai_addr = (void *) (ai + 1); - - /* We only add the canonical name once. */ - ai->ai_canonname = res.canon; - res.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 = st[i].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 = st[i].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; + /* Set up the canonical name if we need it. */ + if ((result = process_canonname (req, orig_name, &res)) != 0) + goto free_and_return; - ignore: - at2 = at2->next; - } - } + result = generate_addrinfo (req, &res, st, pai, naddrs); - free_and_return: +free_and_return: if (malloc_name) free ((char *) name); free (addrmem); From patchwork Tue Mar 8 10:07:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1602864 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=cdTEcAvP; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KCWPl4Mx7z9sGL for ; Tue, 8 Mar 2022 21:13:47 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 39C8B385AC32 for ; Tue, 8 Mar 2022 10:13:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 39C8B385AC32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646734425; bh=6yKM17nxKvO4525e7lbmpg3vR7MhwbtJW5i+qk/d0bA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=cdTEcAvPxQgVheluKZ/4PBSiPdxmGpZ32u+Gwvup0cD/yLw2qpl05OlI/8dHyYx5w OXNUtRBuMjbZxlHSPi7UGEWKsvKnY6DPJg93cBWJMOlRIUVKl2bqINYVSRHiPqBnUW VbB64hLnpFuxe7/cK9ioPaHi6yMRs3lpVA8IyEhg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from quail.birch.relay.mailchannels.net (quail.birch.relay.mailchannels.net [23.83.209.151]) by sourceware.org (Postfix) with ESMTPS id BA357385741B for ; Tue, 8 Mar 2022 10:08:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BA357385741B 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 B06CD921C25; Tue, 8 Mar 2022 10:08:24 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 9C514922337; Tue, 8 Mar 2022 10:08:14 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1646734103; a=rsa-sha256; cv=none; b=wrCQF4mMpYlQ/AP3DOmW1v4mTqtMh56RPMlWh6TRMDsFsnQj+ep2NosixtYiRp2ErIbyVf G12ZY2f+88f2hBXFuEFTwjMNuqcyy8sCqRLP/wQFSJPiJNraDB8AoC8uQdfH7dWihJZa49 jmkZzYfnRxbhHwRGVn0xvfwoQsWnmjNgu4E3/DnGVIZugVzovMicnQIu43JBjFy/8I2/Ms x2fWEYcoQokOZ3t2OkZORAd121C9UVOFfztHYhGNCXH8jHeqm57S8R2LNpwkKoyJIH9MaI Koot1544PpbhzmiIfG7UyTnw8BlpQTE45CxrVGJJ5YFmfgdpjfMRu0bRfD8iew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1646734103; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6yKM17nxKvO4525e7lbmpg3vR7MhwbtJW5i+qk/d0bA=; b=4+LfgX76K+dHInDE5RWK58RH2lhgNxGvFJ4YYlDMhjnpNaFbXPt0n67LEiR08FiRBNcGLf +MaphcDy6Ds3U2kQEQhCjFUxOpl1pvm0e+TyX2zn5wyEIF81me+Onnd98Rs7TAgKjMjeDM S4rt0B5ebPfa//wUFF2XM2f3/PCa6dTiI9wAn4qWmSwIMUSB3ok7D08md2Bssij6ewBOyu 3hFNmeB32ar9IqVMsS7hl/RbpD6o29k9ARPxrXJ+bgg9/ERoIvo5iD5lUN/JEmVjwV+t/W 6chSA/jWLMzfF45QbLIwraeYSv2+VeGDzuu48pJobAdZuUctepYagmvHLTmZ+g== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-nvpxh; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.124.31.75 (trex/6.5.3); Tue, 08 Mar 2022 10:08:24 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Interest-Duck: 10dfe6f572cd89d8_1646734104527_1626133179 X-MC-Loop-Signature: 1646734104526:44038372 X-MC-Ingress-Time: 1646734104526 Received: from rhbox.redhat.com (unknown [1.186.224.155]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KCWHF3Whqz1Pr; Tue, 8 Mar 2022 02:08:09 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 12/12] gethosts: Return EAI_MEMORY on allocation failure Date: Tue, 8 Mar 2022 15:37:17 +0530 Message-Id: <20220308100717.1006126-13-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220308100717.1006126-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.4 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, T_SCC_BODY_TEXT_LINE 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 Cc: fweimer@redhat.com Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" All other cases of failures due to lack of memory return EAI_MEMORY, so it seems wrong to return EAI_SYSTEM here. The only reason convert_hostent_to_gaih_addrtuple could fail is on calloc failure. Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 6cbbd5dac1..7c7565ac6d 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -303,13 +303,13 @@ gethosts (nss_gethostbyname3_r fct, int family, const char *name, else if (status == NSS_STATUS_SUCCESS) { if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res)) - return -EAI_SYSTEM; + return -EAI_MEMORY; if (localcanon != NULL && res->canon == NULL) { char *canonbuf = __strdup (localcanon); if (canonbuf == NULL) - return -EAI_SYSTEM; + return -EAI_MEMORY; res->canon = canonbuf; } }