From patchwork Thu Mar 17 08:11:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52029 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 737C0394FC33 for ; Thu, 17 Mar 2022 08:13:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 737C0394FC33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647504785; bh=14Fd/aTFTdna5uhI4z745GB1fBkgx7XtBfdoFmGY0zk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=TGngFHdC3KwCXtAbodMKHwhV7lAjQAhB8Db8iPgxW04e0noeYjWJXO4PDXwm7oN4J bWFd/xMJv0dCqDI3ZYBdWq3rlKXXSELAfUUT6jeBYQ5/kYkOEgDNOWCo+ZCDPS2qpZ Bwmx82YKcD7XfvQ/huBDpGaUavbDbdSeYczRn+70= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from brown.birch.relay.mailchannels.net (brown.birch.relay.mailchannels.net [23.83.209.23]) by sourceware.org (Postfix) with ESMTPS id 6D21E385782D for ; Thu, 17 Mar 2022 08:12:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6D21E385782D 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 D82002156F; Thu, 17 Mar 2022 08:12:01 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 33A0F216F7; Thu, 17 Mar 2022 08:12:01 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504721; a=rsa-sha256; cv=none; b=AVzpvzqZfdvNLPC/arnL+H/hQIlYtvyOrh7TgaxcFu3aiMKX2anqSRPZfcuVVn6VL00XnV h2st+uZlB0abGK3GdtAg2aC7zSXQXbKB5sE6x1b2ms4aFZIssjcrzEzkbw90fjgzhWcz93 GbyyOG3G96STxxsQU6mUfSQHzHvIX54iiXsBWguF4kfZfwiQ3bEOyDrXO5WjIflrLp94mU Ja5SCYzz4+CYaX94iJ9BJj5ACf0pc+oUqAUhLclWkbTSmxBZ2+joCylsTUoi/G9ojC28Z2 Vf/zrjw6aHY23bmSkmk+oKXh3XoELT96xjDtYbtYDUNXbNlpn9ImX+AD+IstPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504721; 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=14Fd/aTFTdna5uhI4z745GB1fBkgx7XtBfdoFmGY0zk=; b=ZmsDUcRK6bkvw4EOyAjb7JsugAh7PcRR8JxuAUSF7keY8HmCBMqA2wpEVkmUr6hdbimumD TOsxuSB57EvPK0cGBQBSDBIAADG1x+bQvpdshSsKCmArHok4VQb+EqY5hBRWmawLazCaYd Hnz8Tf6LOtsDZbR1ofkw7MN9i2UNH17IWq7ingVTlZv8gODxRH1aeswYns3miSeIhyzMnQ WpbabKcfGs20/mbCg4nzV+V3436ziwQBlvOdcas4Q6kxcN78J1Z0r1sXgB9mPLG20o5+tX 2ePJG5kgfvmQ2597ruPNZ95iWF3fL36w2+YZoPr4gnc1dbVEH1hOcfJI9NGLTw== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-qgm8m; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.124.238.100 (trex/6.5.3); Thu, 17 Mar 2022 08:12:01 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Fumbling-Fumbling: 26cdb06a26809287_1647504721773_3069174257 X-MC-Loop-Signature: 1647504721773:334034215 X-MC-Ingress-Time: 1647504721773 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0H26Zn9z2n; Thu, 17 Mar 2022 01:11:58 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 01/12] Simplify allocations and fix merge and continue actions [BZ #28931] Date: Thu, 17 Mar 2022 13:41:29 +0530 Message-Id: <20220317081140.3098156-2-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3496.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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. Resolves: BZ #28931 Signed-off-by: Siddhesh Poyarekar --- nss/Makefile | 1 + nss/tst-nss-gai-actions.c | 149 ++++++ nss/tst-nss-gai-actions.root/etc/host.conf | 1 + nss/tst-nss-gai-actions.root/etc/hosts | 508 +++++++++++++++++++++ sysdeps/posix/getaddrinfo.c | 143 +++--- 5 files changed, 750 insertions(+), 52 deletions(-) create mode 100644 nss/tst-nss-gai-actions.c create mode 100644 nss/tst-nss-gai-actions.root/etc/host.conf create mode 100644 nss/tst-nss-gai-actions.root/etc/hosts diff --git a/nss/Makefile b/nss/Makefile index 42a59535cb..d8b06b44fb 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -76,6 +76,7 @@ tests-container := \ tst-nss-db-endgrent \ tst-nss-db-endpwent \ tst-nss-files-hosts-long \ + tst-nss-gai-actions \ tst-nss-test3 \ tst-reload1 \ tst-reload2 \ diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c new file mode 100644 index 0000000000..efca6cd183 --- /dev/null +++ b/nss/tst-nss-gai-actions.c @@ -0,0 +1,149 @@ +/* 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 + +enum +{ + ACTION_MERGE = 0, + ACTION_CONTINUE, +}; + +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 * +action_str (int action) +{ + switch (action) + { + case ACTION_MERGE: + return "merge"; + case ACTION_CONTINUE: + return "continue"; + default: + __builtin_unreachable (); + } +} + +static void +do_one_test (int action, int family, bool canon) +{ + struct addrinfo hints = + { + .ai_family = family, + }; + + struct addrinfo *ai; + + if (canon) + hints.ai_flags = AI_CANONNAME; + + printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n", + action_str (action), family_str (family), + canon ? "AI_CANONNAME" : ""); + + int ret = getaddrinfo ("example.org", "80", &hints, &ai); + + switch (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); + + /* 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 (); + } + + free (formatted); + break; + } + default: + __builtin_unreachable (); + } +} + +static void +do_one_test_set (int action) +{ + char buf[32]; + + snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files", + action_str (action)); + __nss_configure_lookup ("hosts", buf); + + do_one_test (action, AF_UNSPEC, false); + do_one_test (action, AF_INET, false); + do_one_test (action, AF_INET, true); +} + +static int +do_test (void) +{ + do_one_test_set (ACTION_CONTINUE); + do_one_test_set (ACTION_MERGE); + return 0; +} + +#include diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf new file mode 100644 index 0000000000..d1a59f73a9 --- /dev/null +++ b/nss/tst-nss-gai-actions.root/etc/host.conf @@ -0,0 +1 @@ +multi on diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts new file mode 100644 index 0000000000..50ce9774dc --- /dev/null +++ b/nss/tst-nss-gai-actions.root/etc/hosts @@ -0,0 +1,508 @@ +192.0.0.1 example.org +192.0.0.2 example.org +192.0.0.3 example.org +192.0.0.4 example.org +192.0.0.5 example.org +192.0.0.6 example.org +192.0.0.7 example.org +192.0.0.8 example.org +192.0.0.9 example.org +192.0.0.10 example.org +192.0.0.11 example.org +192.0.0.12 example.org +192.0.0.13 example.org +192.0.0.14 example.org +192.0.0.15 example.org +192.0.0.16 example.org +192.0.0.17 example.org +192.0.0.18 example.org +192.0.0.19 example.org +192.0.0.20 example.org +192.0.0.21 example.org +192.0.0.22 example.org +192.0.0.23 example.org +192.0.0.24 example.org +192.0.0.25 example.org +192.0.0.26 example.org +192.0.0.27 example.org +192.0.0.28 example.org +192.0.0.29 example.org +192.0.0.30 example.org +192.0.0.31 example.org +192.0.0.32 example.org +192.0.0.33 example.org +192.0.0.34 example.org +192.0.0.35 example.org +192.0.0.36 example.org +192.0.0.37 example.org +192.0.0.38 example.org +192.0.0.39 example.org +192.0.0.40 example.org +192.0.0.41 example.org +192.0.0.42 example.org +192.0.0.43 example.org +192.0.0.44 example.org +192.0.0.45 example.org +192.0.0.46 example.org +192.0.0.47 example.org +192.0.0.48 example.org +192.0.0.49 example.org +192.0.0.50 example.org +192.0.0.51 example.org +192.0.0.52 example.org +192.0.0.53 example.org +192.0.0.54 example.org +192.0.0.55 example.org +192.0.0.56 example.org +192.0.0.57 example.org +192.0.0.58 example.org +192.0.0.59 example.org +192.0.0.60 example.org +192.0.0.61 example.org +192.0.0.62 example.org +192.0.0.63 example.org +192.0.0.64 example.org +192.0.0.65 example.org +192.0.0.66 example.org +192.0.0.67 example.org +192.0.0.68 example.org +192.0.0.69 example.org +192.0.0.70 example.org +192.0.0.71 example.org +192.0.0.72 example.org +192.0.0.73 example.org +192.0.0.74 example.org +192.0.0.75 example.org +192.0.0.76 example.org +192.0.0.77 example.org +192.0.0.78 example.org +192.0.0.79 example.org +192.0.0.80 example.org +192.0.0.81 example.org +192.0.0.82 example.org +192.0.0.83 example.org +192.0.0.84 example.org +192.0.0.85 example.org +192.0.0.86 example.org +192.0.0.87 example.org +192.0.0.88 example.org +192.0.0.89 example.org +192.0.0.90 example.org +192.0.0.91 example.org +192.0.0.92 example.org +192.0.0.93 example.org +192.0.0.94 example.org +192.0.0.95 example.org +192.0.0.96 example.org +192.0.0.97 example.org +192.0.0.98 example.org +192.0.0.99 example.org +192.0.0.100 example.org +192.0.0.101 example.org +192.0.0.102 example.org +192.0.0.103 example.org +192.0.0.104 example.org +192.0.0.105 example.org +192.0.0.106 example.org +192.0.0.107 example.org +192.0.0.108 example.org +192.0.0.109 example.org +192.0.0.110 example.org +192.0.0.111 example.org +192.0.0.112 example.org +192.0.0.113 example.org +192.0.0.114 example.org +192.0.0.115 example.org +192.0.0.116 example.org +192.0.0.117 example.org +192.0.0.118 example.org +192.0.0.119 example.org +192.0.0.120 example.org +192.0.0.121 example.org +192.0.0.122 example.org +192.0.0.123 example.org +192.0.0.124 example.org +192.0.0.125 example.org +192.0.0.126 example.org +192.0.0.127 example.org +192.0.0.128 example.org +192.0.0.129 example.org +192.0.0.130 example.org +192.0.0.131 example.org +192.0.0.132 example.org +192.0.0.133 example.org +192.0.0.134 example.org +192.0.0.135 example.org +192.0.0.136 example.org +192.0.0.137 example.org +192.0.0.138 example.org +192.0.0.139 example.org +192.0.0.140 example.org +192.0.0.141 example.org +192.0.0.142 example.org +192.0.0.143 example.org +192.0.0.144 example.org +192.0.0.145 example.org +192.0.0.146 example.org +192.0.0.147 example.org +192.0.0.148 example.org +192.0.0.149 example.org +192.0.0.150 example.org +192.0.0.151 example.org +192.0.0.152 example.org +192.0.0.153 example.org +192.0.0.154 example.org +192.0.0.155 example.org +192.0.0.156 example.org +192.0.0.157 example.org +192.0.0.158 example.org +192.0.0.159 example.org +192.0.0.160 example.org +192.0.0.161 example.org +192.0.0.162 example.org +192.0.0.163 example.org +192.0.0.164 example.org +192.0.0.165 example.org +192.0.0.166 example.org +192.0.0.167 example.org +192.0.0.168 example.org +192.0.0.169 example.org +192.0.0.170 example.org +192.0.0.171 example.org +192.0.0.172 example.org +192.0.0.173 example.org +192.0.0.174 example.org +192.0.0.175 example.org +192.0.0.176 example.org +192.0.0.177 example.org +192.0.0.178 example.org +192.0.0.179 example.org +192.0.0.180 example.org +192.0.0.181 example.org +192.0.0.182 example.org +192.0.0.183 example.org +192.0.0.184 example.org +192.0.0.185 example.org +192.0.0.186 example.org +192.0.0.187 example.org +192.0.0.188 example.org +192.0.0.189 example.org +192.0.0.190 example.org +192.0.0.191 example.org +192.0.0.192 example.org +192.0.0.193 example.org +192.0.0.194 example.org +192.0.0.195 example.org +192.0.0.196 example.org +192.0.0.197 example.org +192.0.0.198 example.org +192.0.0.199 example.org +192.0.0.200 example.org +192.0.0.201 example.org +192.0.0.202 example.org +192.0.0.203 example.org +192.0.0.204 example.org +192.0.0.205 example.org +192.0.0.206 example.org +192.0.0.207 example.org +192.0.0.208 example.org +192.0.0.209 example.org +192.0.0.210 example.org +192.0.0.211 example.org +192.0.0.212 example.org +192.0.0.213 example.org +192.0.0.214 example.org +192.0.0.215 example.org +192.0.0.216 example.org +192.0.0.217 example.org +192.0.0.218 example.org +192.0.0.219 example.org +192.0.0.220 example.org +192.0.0.221 example.org +192.0.0.222 example.org +192.0.0.223 example.org +192.0.0.224 example.org +192.0.0.225 example.org +192.0.0.226 example.org +192.0.0.227 example.org +192.0.0.228 example.org +192.0.0.229 example.org +192.0.0.230 example.org +192.0.0.231 example.org +192.0.0.232 example.org +192.0.0.233 example.org +192.0.0.234 example.org +192.0.0.235 example.org +192.0.0.236 example.org +192.0.0.237 example.org +192.0.0.238 example.org +192.0.0.239 example.org +192.0.0.240 example.org +192.0.0.241 example.org +192.0.0.242 example.org +192.0.0.243 example.org +192.0.0.244 example.org +192.0.0.245 example.org +192.0.0.246 example.org +192.0.0.247 example.org +192.0.0.248 example.org +192.0.0.249 example.org +192.0.0.250 example.org +192.0.0.251 example.org +192.0.0.252 example.org +192.0.0.253 example.org +192.0.0.254 example.org +192.0.1.1 example.org +192.0.1.2 example.org +192.0.1.3 example.org +192.0.1.4 example.org +192.0.1.5 example.org +192.0.1.6 example.org +192.0.1.7 example.org +192.0.1.8 example.org +192.0.1.9 example.org +192.0.1.10 example.org +192.0.1.11 example.org +192.0.1.12 example.org +192.0.1.13 example.org +192.0.1.14 example.org +192.0.1.15 example.org +192.0.1.16 example.org +192.0.1.17 example.org +192.0.1.18 example.org +192.0.1.19 example.org +192.0.1.20 example.org +192.0.1.21 example.org +192.0.1.22 example.org +192.0.1.23 example.org +192.0.1.24 example.org +192.0.1.25 example.org +192.0.1.26 example.org +192.0.1.27 example.org +192.0.1.28 example.org +192.0.1.29 example.org +192.0.1.30 example.org +192.0.1.31 example.org +192.0.1.32 example.org +192.0.1.33 example.org +192.0.1.34 example.org +192.0.1.35 example.org +192.0.1.36 example.org +192.0.1.37 example.org +192.0.1.38 example.org +192.0.1.39 example.org +192.0.1.40 example.org +192.0.1.41 example.org +192.0.1.42 example.org +192.0.1.43 example.org +192.0.1.44 example.org +192.0.1.45 example.org +192.0.1.46 example.org +192.0.1.47 example.org +192.0.1.48 example.org +192.0.1.49 example.org +192.0.1.50 example.org +192.0.1.51 example.org +192.0.1.52 example.org +192.0.1.53 example.org +192.0.1.54 example.org +192.0.1.55 example.org +192.0.1.56 example.org +192.0.1.57 example.org +192.0.1.58 example.org +192.0.1.59 example.org +192.0.1.60 example.org +192.0.1.61 example.org +192.0.1.62 example.org +192.0.1.63 example.org +192.0.1.64 example.org +192.0.1.65 example.org +192.0.1.66 example.org +192.0.1.67 example.org +192.0.1.68 example.org +192.0.1.69 example.org +192.0.1.70 example.org +192.0.1.71 example.org +192.0.1.72 example.org +192.0.1.73 example.org +192.0.1.74 example.org +192.0.1.75 example.org +192.0.1.76 example.org +192.0.1.77 example.org +192.0.1.78 example.org +192.0.1.79 example.org +192.0.1.80 example.org +192.0.1.81 example.org +192.0.1.82 example.org +192.0.1.83 example.org +192.0.1.84 example.org +192.0.1.85 example.org +192.0.1.86 example.org +192.0.1.87 example.org +192.0.1.88 example.org +192.0.1.89 example.org +192.0.1.90 example.org +192.0.1.91 example.org +192.0.1.92 example.org +192.0.1.93 example.org +192.0.1.94 example.org +192.0.1.95 example.org +192.0.1.96 example.org +192.0.1.97 example.org +192.0.1.98 example.org +192.0.1.99 example.org +192.0.1.100 example.org +192.0.1.101 example.org +192.0.1.102 example.org +192.0.1.103 example.org +192.0.1.104 example.org +192.0.1.105 example.org +192.0.1.106 example.org +192.0.1.107 example.org +192.0.1.108 example.org +192.0.1.109 example.org +192.0.1.110 example.org +192.0.1.111 example.org +192.0.1.112 example.org +192.0.1.113 example.org +192.0.1.114 example.org +192.0.1.115 example.org +192.0.1.116 example.org +192.0.1.117 example.org +192.0.1.118 example.org +192.0.1.119 example.org +192.0.1.120 example.org +192.0.1.121 example.org +192.0.1.122 example.org +192.0.1.123 example.org +192.0.1.124 example.org +192.0.1.125 example.org +192.0.1.126 example.org +192.0.1.127 example.org +192.0.1.128 example.org +192.0.1.129 example.org +192.0.1.130 example.org +192.0.1.131 example.org +192.0.1.132 example.org +192.0.1.133 example.org +192.0.1.134 example.org +192.0.1.135 example.org +192.0.1.136 example.org +192.0.1.137 example.org +192.0.1.138 example.org +192.0.1.139 example.org +192.0.1.140 example.org +192.0.1.141 example.org +192.0.1.142 example.org +192.0.1.143 example.org +192.0.1.144 example.org +192.0.1.145 example.org +192.0.1.146 example.org +192.0.1.147 example.org +192.0.1.148 example.org +192.0.1.149 example.org +192.0.1.150 example.org +192.0.1.151 example.org +192.0.1.152 example.org +192.0.1.153 example.org +192.0.1.154 example.org +192.0.1.155 example.org +192.0.1.156 example.org +192.0.1.157 example.org +192.0.1.158 example.org +192.0.1.159 example.org +192.0.1.160 example.org +192.0.1.161 example.org +192.0.1.162 example.org +192.0.1.163 example.org +192.0.1.164 example.org +192.0.1.165 example.org +192.0.1.166 example.org +192.0.1.167 example.org +192.0.1.168 example.org +192.0.1.169 example.org +192.0.1.170 example.org +192.0.1.171 example.org +192.0.1.172 example.org +192.0.1.173 example.org +192.0.1.174 example.org +192.0.1.175 example.org +192.0.1.176 example.org +192.0.1.177 example.org +192.0.1.178 example.org +192.0.1.179 example.org +192.0.1.180 example.org +192.0.1.181 example.org +192.0.1.182 example.org +192.0.1.183 example.org +192.0.1.184 example.org +192.0.1.185 example.org +192.0.1.186 example.org +192.0.1.187 example.org +192.0.1.188 example.org +192.0.1.189 example.org +192.0.1.190 example.org +192.0.1.191 example.org +192.0.1.192 example.org +192.0.1.193 example.org +192.0.1.194 example.org +192.0.1.195 example.org +192.0.1.196 example.org +192.0.1.197 example.org +192.0.1.198 example.org +192.0.1.199 example.org +192.0.1.200 example.org +192.0.1.201 example.org +192.0.1.202 example.org +192.0.1.203 example.org +192.0.1.204 example.org +192.0.1.205 example.org +192.0.1.206 example.org +192.0.1.207 example.org +192.0.1.208 example.org +192.0.1.209 example.org +192.0.1.210 example.org +192.0.1.211 example.org +192.0.1.212 example.org +192.0.1.213 example.org +192.0.1.214 example.org +192.0.1.215 example.org +192.0.1.216 example.org +192.0.1.217 example.org +192.0.1.218 example.org +192.0.1.219 example.org +192.0.1.220 example.org +192.0.1.221 example.org +192.0.1.222 example.org +192.0.1.223 example.org +192.0.1.224 example.org +192.0.1.225 example.org +192.0.1.226 example.org +192.0.1.227 example.org +192.0.1.228 example.org +192.0.1.229 example.org +192.0.1.230 example.org +192.0.1.231 example.org +192.0.1.232 example.org +192.0.1.233 example.org +192.0.1.234 example.org +192.0.1.235 example.org +192.0.1.236 example.org +192.0.1.237 example.org +192.0.1.238 example.org +192.0.1.239 example.org +192.0.1.240 example.org +192.0.1.241 example.org +192.0.1.242 example.org +192.0.1.243 example.org +192.0.1.244 example.org +192.0.1.245 example.org +192.0.1.246 example.org +192.0.1.247 example.org +192.0.1.248 example.org +192.0.1.249 example.org +192.0.1.250 example.org +192.0.1.251 example.org +192.0.1.252 example.org +192.0.1.253 example.org +192.0.1.254 example.org diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 18dccd5924..3d9bea60c6 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,22 @@ 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; + got_ipv6 = false; + + if (do_merge) + { + __set_h_errno (NETDB_INTERNAL); + __set_errno (EBUSY); + break; + } + no_data = 0; nss_gethostbyname4_r *fct4 = NULL; @@ -744,12 +773,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 +805,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 +859,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 +934,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 +969,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 Thu Mar 17 08:11:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52030 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F3069395200A for ; Thu, 17 Mar 2022 08:13:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3069395200A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647504833; bh=I0LSZcnOGw8/YMDb0wP1PuPmhdbvAR2Mi2Eq3CR5M70=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=HxQ5YentCE1gaMN82VN1s0VaeMZd4G2DG7qkOhAD0cZ2pm+NRxt3hAfufHM5TqOBG VCSVlv/dD0Tc7qFu1uG8X2cfgAE1JeWM+nFFUATRszWj1YMP/ksVpJAkyXccIf2zd1 ovXS744wVldgeQlu1DOZV38Pw6mgu5BmuPgZkY/c= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from brown.elm.relay.mailchannels.net (brown.elm.relay.mailchannels.net [23.83.212.23]) by sourceware.org (Postfix) with ESMTPS id 07198395200A for ; Thu, 17 Mar 2022 08:12:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 07198395200A 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 8F5F04C1C20; Thu, 17 Mar 2022 08:12:05 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 0D97A4C1606; Thu, 17 Mar 2022 08:12:04 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504724; a=rsa-sha256; cv=none; b=REGQ1d5xVdoj4HYg9qiEYvVXhev4p//YaXWpB6iAbkYrkJbudTvdNqpmCdjlDxv9lsFsXM UiHZ+NtRPTxxVTyjJGS1rAN/xJxe/A66hay0eBzM/3gZIAfimBzLfvTEagLBGVCFyRO+I+ 35g1F4xC/SOFClxJpuqv7YtO8oQMTkeHNlwBeQ8ROwn0h31+RUKE8dyzaECQvIGRfFUs+4 O5qyUCEAlyQUVZSnsEauQbPsqxpNkFXE65PpGyP8LM5dcm+6FJCPPUwzxEdCFoxAv6G8Gt Fq3xv9khhjVi5TZnKy4qgZ/8U25ItGANss82j6SqE5QN4LH3WxYbh/T9nbBpMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504724; 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=I0LSZcnOGw8/YMDb0wP1PuPmhdbvAR2Mi2Eq3CR5M70=; b=TShnlPgT/tdS7i6vEvXF+jZdIXRsp5mP3toMzNKmFaKnVHRU6um2TzkhiJ1AHk12npyiJ9 n+EKg2NJKQyNNFp2ndUA7uYtX0CeJinUit2tqYeebApmpmze4H+z9uHP0cQwYXc77SD1BH AazF0Dm3f56nkaXfJKtPmw9x4ie4arhF+RpIG0ChCTj+h7zGB6VUox+O9gsGZdCtnkk+yP Pe9w10WkMPSTL0mvzVO4q2YfucTSsTtUy/sf9SK/Y9ObcYDqPz9hHYsMQDkj5EpzFAiR9X QxJxwwGjMDg4/PaHQxjH7SN1b4Pn0NohQupe7n+Qz+Q6IS8pIZz5+Rcyb5eXyQ== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-qgm8m; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.121.210.153 (trex/6.5.3); Thu, 17 Mar 2022 08:12:05 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Stop-Invention: 07279fe623e1362e_1647504725164_1800344969 X-MC-Loop-Signature: 1647504725164:2589490195 X-MC-Ingress-Time: 1647504725164 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0H55jQqz21; Thu, 17 Mar 2022 01:12:01 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 02/12] gaih_inet: Simplify canon name resolution Date: Thu, 17 Mar 2022 13:41:30 +0530 Message-Id: <20220317081140.3098156-3-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- 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 3d9bea60c6..0629fd147b 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; got_ipv6 = false; @@ -805,7 +855,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; @@ -893,7 +952,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); @@ -1004,6 +1063,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; @@ -1014,48 +1077,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) { @@ -1078,7 +1099,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; } @@ -1138,7 +1158,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 Thu Mar 17 08:11:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52031 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E02573952004 for ; Thu, 17 Mar 2022 08:14:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E02573952004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647504877; bh=CnNLfgNs5YXNncSldPLE2XVcwmsWu+vrnppJCoiYHnI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=TfNtmigJM50COMNbDhtcK1eHYSZnVbgZbgSEDqOk6X1uFlXIoRms4NdYEWJsy5imD AQyyqm0FmxQrTVKERnKejstAWBsZkpyGqqhSnu98wMBcf+0XFSUd0rOgwpC7Tnzl8s 1g3hGClYE6/FCCv0P3RR8qrO8FvzNGNMrsejVNBQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from brown.elm.relay.mailchannels.net (brown.elm.relay.mailchannels.net [23.83.212.23]) by sourceware.org (Postfix) with ESMTPS id EBE393952005 for ; Thu, 17 Mar 2022 08:12:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EBE393952005 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 5A0AB2C17C0; Thu, 17 Mar 2022 08:12:07 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 29F262C1171; Thu, 17 Mar 2022 08:12:06 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504726; a=rsa-sha256; cv=none; b=E2lecW/5Rlx71sZi0lv0pooS+Nrpgu5Tvohhm1MiM0/qpSg2OfLqxs5oi+0KavokiRjYZs yPYVlhvbfVf9yV4BH/Pk4FGvREOC+eiV/Yb1R5pD6xvyB4deOuKroT0Bls4bBaqxJ1l/NW ZFaP58rKbNv/9DM3KGGM3wSVYEs5cbGBY2sRg150R9NBO6+xd9wOH41HIjfHz7y60Z7qKp CUKH3CswSOD4PmSwi7qTH6h7LnQqrzS9Txv4kl1VTKRpsnhc6qvzxtG91VT4Yd+54h36+Y wYKZOp1OWNGdGYUeNqtJELNFsPzd07hS2Gs/N/qXoaNOnjAmvyi7Dhm+uEfGrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504726; 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=CnNLfgNs5YXNncSldPLE2XVcwmsWu+vrnppJCoiYHnI=; b=gSQa+BUfhbV9SXrchkiMdWPtItW9UMbZ7FUOxiJYNgyBX5dSo33pe4vxqrnQ549WqyyQVS 3RicINE2yr+D5dwIqA5hOQbylRvfMvgH7uXqJnzXnmBvbly/xrKSrlY+Pv6k4Ry/aHrvQs j381ne1OhoE6oLoyLF+PR/wJWuVuJXOVpoMAxDZIRhBZGGIuVfTap6puz3jGaVVAAk7AWZ rT7wdmzT00zyygykE3bO7/4xXCYg7V20zaaut0ScGI8r7xno3EhwON56GbaxxIcSm7TfMH iWnhMBEMNfbYMiv1s7kbmlryLdef0SqXP+82E63m8C0XYYYjPDTXfJWZV+b9Hw== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-5855h; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.120.38.157 (trex/6.5.3); Thu, 17 Mar 2022 08:12:07 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Hook-Power: 51a41661259f4534_1647504726899_301947724 X-MC-Loop-Signature: 1647504726899:4271083930 X-MC-Ingress-Time: 1647504726899 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0H82gCSz2n; Thu, 17 Mar 2022 01:12:03 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852] Date: Thu, 17 Mar 2022 13:41:31 +0530 Message-Id: <20220317081140.3098156-4-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- sysdeps/posix/getaddrinfo.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 0629fd147b..e9deb2da6a 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -189,19 +189,16 @@ 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. The new addresses are appended to the tuple array in + RESULT. */ static bool convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, 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 != NULL) + { + 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 Thu Mar 17 08:11:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52035 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EE37B385782D for ; Thu, 17 Mar 2022 08:17:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE37B385782D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505058; bh=R+opd4772gqjyYMToQ0sfIRD/BX9SYOBnRHNOjKY9Eg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=kZrw0NwH00GxeS2edAoFEChBO55wnLJGKLijEALo5WF4dmVT1Nqp3r/o00VJ8Kefz iVkk2ho2ILl6v4pyKZE0LJ/48ianlnOhy0dzs7QPzbLyyBW+rLeGMAJkNXaI7qhwAW fEV/+Kc3/NRdDV8yIUGGGFdxofs7P6r1o8sJmrF8= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from brown.elm.relay.mailchannels.net (brown.elm.relay.mailchannels.net [23.83.212.23]) by sourceware.org (Postfix) with ESMTPS id 56C06394FC3D for ; Thu, 17 Mar 2022 08:12:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 56C06394FC3D 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 3A41B120847; Thu, 17 Mar 2022 08:12:20 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 3EEE2120951; Thu, 17 Mar 2022 08:12:09 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504729; a=rsa-sha256; cv=none; b=Csxyhqj+EISALVSe2gzx8eAzMOdQBe8mHgqXUZdmUZYueRLqAqouIoyNp6mVCjHD4bdQPN cDjOXJo7DWkJuUlrYoJIyWyfh3y5AkbUnLblm0Ppf8luvDkfpRkJ4bv6EzhrcEhMvE7nsb dxFTl4Af7g7/FGVqTGqAzKtwYVMrsh3yR6B4GF3cNvK8ExVJ9XsWNjrOTeY1ArdE68oOJ6 YfmQ7ft3UbT5/DMWTZssGjZORQuG9VQNAw8DL9exVGaWdvkD0N3ofc8TIjJ7fdulW/ldZa d0dnUyTiKfDsb5N9yo35d+NlqWvN88fxWebPm5C217wajoAqIWLxn2HPbEtVrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504729; 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=R+opd4772gqjyYMToQ0sfIRD/BX9SYOBnRHNOjKY9Eg=; b=ir1IpFLefMhLFWLcfqP/3BTgZ16eK4Zb1dXNArZEl9wGd4RflypO0DpGzkqGIEe6fHNh0S NOHRhJlTQiYNRdUflMF4a6IrkNbeBjGy2W72sX8kYBX8gw/i+U1jL+2QOXE3rBzmjmTfGg 2TXEk+xv5DGH0SyO+QvTEzj0TxRPpKcflWo0oJjk86hG9gfgmpEtaC+mRtK7RlLgku+NyB LwkvBHr8wRDpggTlY5u2gMheRAovcxfK3hqPiifhP4I3jUAiY6jXJGFLF0su6jzcXvM97T DEOeemmaZhY9QoZLVBwSL68lHchdkzaT0hTJHvibGfXKFw1SOpZU9T7z53Yc1g== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-s9pd7; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.120.38.157 (trex/6.5.3); Thu, 17 Mar 2022 08:12:20 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Obese-Shade: 2c8b9bab08a1a1cb_1647504729816_565995004 X-MC-Loop-Signature: 1647504729816:663544828 X-MC-Ingress-Time: 1647504729815 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HC3lFfz1Q; Thu, 17 Mar 2022 01:12:06 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 04/12] gaih_inet: Simplify service resolution Date: Thu, 17 Mar 2022 13:41:32 +0530 Message-Id: <20220317081140.3098156-5-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- 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 e9deb2da6a..dae5e9f55f 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; @@ -1083,7 +1062,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; @@ -1109,7 +1087,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); @@ -1121,8 +1099,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); @@ -1144,7 +1122,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)); @@ -1154,7 +1132,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 Thu Mar 17 08:11:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52032 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 08073394FC3F for ; Thu, 17 Mar 2022 08:15:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 08073394FC3F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647504921; bh=3K3WL6pS4YdvGr8uRYGMEOA5QTmKslq+r7GzUUyxo5c=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=eJ4JIXLAAgTD+vdfkWQF+yfqKvRtcr1elugAnrO5tyeYpSCXkHwcb1VpNs/yvebGU zbWP/nUbFTyqLQfpqK7zyzkZBO9KN3TRoPK/SQWuYXfrHg1kwyCVE9iNb0A+8K6Uqm tXLKnFXtk+RV3HZ0gSpuvO+v3wKV7pFq7vXZz5vY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from bat.birch.relay.mailchannels.net (bat.birch.relay.mailchannels.net [23.83.209.13]) by sourceware.org (Postfix) with ESMTPS id AC176394FC35 for ; Thu, 17 Mar 2022 08:12:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AC176394FC35 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 509B72C1599; Thu, 17 Mar 2022 08:12:13 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 0CB852C13EA; Thu, 17 Mar 2022 08:12:12 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504732; a=rsa-sha256; cv=none; b=1eyYRuQDSj0Aec/a8EO18vvHiwXxKl7Ojg4I+6rlaDhp3rdq7hDaO87RwxyENmBL6RE9U/ Sgt3RhPkkAPCVcLdCaiBMi4nwX0HIgS1nV8NmmjIT4o63c94CcJY5ks3AaBjkjdX4DhkEe KP7HQdBnyDGgmelnuQFaupFPzqJyn4xKpTl3sb08ujUv+IeYiq4JGMpIs/ASnLt9J69f0B ynfKHVFMqWEHucBt3URNXooI2i5m8W434Bt9h3Q/KaWuZaqOzEBKXzhCCnWijY6XEwXsPC uxtfWAPZfntQMk/deIYVxu4j4WHIuqnoK+BnYffAlPgM88YeBxAP+UYsFvNcAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504732; 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=3K3WL6pS4YdvGr8uRYGMEOA5QTmKslq+r7GzUUyxo5c=; b=juLxQaW1rSy6dBv14dYG5vFKeJ6ci+Dx+NmEtTTLb2sDkTUeStjyqdq2G5VJhVGAOOJHG2 9gba5FU1K3Xee8bRUNIIO/jXdMKK4BnNeszLmIxbHfDSWx+phooiKSm7/nTi9u6JO2lDJw mSWNQDCws5NH8DAUAZX1C1EZFfw9D8Xf6Q78P3u6m5OsxF8QW1id+3GnVe99aYE+pV078j 5TSuoWogWE8xbLJ+OeqD4jtqfG4oWqciuZi6oJZb8N8TfZx1FdlHNiaVUpuGlDuVvIPgk1 Uq9k50JiyNJoOEOA9SvAqpiuU9rbM8ROWQgtreEdD+lcCCh20yDDFJYPIuKO0g== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-gfzgt; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.112.55.223 (trex/6.5.3); Thu, 17 Mar 2022 08:12:13 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Wipe-Trouble: 147ab0bf37727c30_1647504733159_2637232201 X-MC-Loop-Signature: 1647504733159:415873258 X-MC-Ingress-Time: 1647504733159 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HF5MbTz2n; Thu, 17 Mar 2022 01:12:09 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 05/12] gaih_inet: make numeric lookup a separate routine Date: Thu, 17 Mar 2022 13:41:33 +0530 Message-Id: <20220317081140.3098156-6-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- sysdeps/posix/getaddrinfo.c | 891 ++++++++++++++++++------------------ 1 file changed, 452 insertions(+), 439 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index dae5e9f55f..19bb13db59 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,533 +601,441 @@ 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; + got_ipv6 = false; + + 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; - got_ipv6 = false; - - 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; @@ -1032,21 +1044,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) @@ -1059,10 +1072,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; @@ -1105,8 +1118,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; @@ -1152,7 +1165,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 Thu Mar 17 08:11:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52033 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 313F23952004 for ; Thu, 17 Mar 2022 08:16:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 313F23952004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647504965; bh=9hXHN5c4QQc5KqACvYlgkmOispDW9uK42seWkUpzZ4Y=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Fr3ekr99CbS0pSjUpKQuT7BRmAtJnoiJpJsiqTqJUa2Cbq3x+ogpII/9SGP57wKMk fjNxj3uPXbc25v3wW951Tta0+bJ7sHn/VBOzjzi3f4asOEjyDe80Df1uYatZ8+5hZa Wn46dKNKnLjlsOap2Ma6elWANwaXoHEx7MHNNSdY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from brown.elm.relay.mailchannels.net (brown.elm.relay.mailchannels.net [23.83.212.23]) by sourceware.org (Postfix) with ESMTPS id 8FF52394FC3D for ; Thu, 17 Mar 2022 08:12:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8FF52394FC3D 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 52C2F2130B; Thu, 17 Mar 2022 08:12:15 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 8003921B23; Thu, 17 Mar 2022 08:12:14 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504734; a=rsa-sha256; cv=none; b=RlYIulMfNYPW2wo9syh8f9slJetLph2fqmKzdnYuSNABcBdBNYT0xNvJyRsrsjLUyzjGVy Ja8Xye+bDLEirzF+ey/mNbUEWHWhao24PbKPpHOm6Yzs7C2sWN+gdLPkv+dFVCoa1Wi2S5 ll4yZ/S2Y+bAyS7gt+30K2K36hYBWx/Y123klQ/iq6EiZ5K9cKpebksLx+nxw22kCKIQBr uIX6Nd2S5Qz4k+Nr7AB5mh0Q7n2RQxZcl2QqukSLgPgXfJG4LPwwAmdgGlQzOnsTEWpkF1 407efcmNuadfacD/ZaX0vS7WYHHNV1yvVUgRsdnaHEcXneRH7T04ExO2ctfaeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504734; 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=9hXHN5c4QQc5KqACvYlgkmOispDW9uK42seWkUpzZ4Y=; b=Qi8nC7d8/Zi7pevnOnWkkRoKQYbA8KBQgZ9l+C4hdHdmu7swi7AELW/DVwK+WoK1K8yUIX NtctCfAfem7QYZz37vTmpevKX6mgmK1R3Qf78TvHt3SfPvElJHcpcb/KaOGVm3lBKX2lE/ iQhDJEdfK+Yknf5bVWB6U8aSO2d+I4GwOFgBE3lDVMbf8ewRi/Dga2Uf6Wvw/VtTshTq9j ecvKluvrqmXweuaes2d+ZqjEQlz94ptMc9MD/itpHx0Iom5+/t/Wwgx0jiI5BtXFOPRrVY P94aEYXxjdzKk4e/XDQnkoqwgBuLjiWQCQXm+5PWs6pfUToM+vHXJF22MmZ7yA== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-fgp5v; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.112.55.223 (trex/6.5.3); Thu, 17 Mar 2022 08:12:14 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Invention-Blushing: 623b747018a6cecf_1647504734807_1074485310 X-MC-Loop-Signature: 1647504734807:3674670565 X-MC-Ingress-Time: 1647504734807 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HJ3Qmwz21; Thu, 17 Mar 2022 01:12:12 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 06/12] gaih_inet: Split simple gethostbyname into its own function Date: Thu, 17 Mar 2022 13:41:34 +0530 Message-Id: <20220317081140.3098156-7-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3493.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- sysdeps/posix/getaddrinfo.c | 127 ++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 19bb13db59..1137c959ac 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,62 @@ 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. RES->AT from the conversion will + either be an allocated block or NULL, both of which are safe to + pass to free (). */ + 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 +667,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 +681,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) @@ -1165,6 +1164,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 Thu Mar 17 08:11:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52034 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C6790394FC30 for ; Thu, 17 Mar 2022 08:16:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6790394FC30 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505012; bh=S6BKUZAkeaDzgNe6WKwVwfediK2Q5QJLowJx9yXsicg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=ifbyiAxO7lmgDyHvS/Th1fNyLQMXk8tHHQ2W5EXFSvEnK4fqQ5XnOfF4QggTNkhrY Y1ghZzU0csI38WWgUu2GB8tf+9q4x5op3GBXNUOpTJWM++NogqErN2P+Yi2SNa82tv qPYTd+lMBWqeywBbM0muZeoUv/28NTADVBZm3rvM= 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 5925A395201A for ; Thu, 17 Mar 2022 08:12:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5925A395201A 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 CA516620DCB; Thu, 17 Mar 2022 08:12:18 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 34ADE620E2B; Thu, 17 Mar 2022 08:12:18 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.119.141.221 (trex/6.5.3); Thu, 17 Mar 2022 08:12:18 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Bored-Society: 0fa46f567a6a5e97_1647504738304_3704053855 X-MC-Loop-Signature: 1647504738304:3147531030 X-MC-Ingress-Time: 1647504738303 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HL6jgBz2n; Thu, 17 Mar 2022 01:12:14 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 07/12] gaih_inet: Split nscd lookup code into its own function. Date: Thu, 17 Mar 2022 13:41:35 +0530 Message-Id: <20220317081140.3098156-8-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 1137c959ac..01be932b3f 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 @@ -630,7 +753,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 @@ -672,6 +794,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; @@ -681,115 +810,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 @@ -897,7 +917,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); @@ -940,7 +960,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); @@ -1091,7 +1111,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 Thu Mar 17 08:11:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52037 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9C8DD394FC39 for ; Thu, 17 Mar 2022 08:19:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C8DD394FC39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505147; bh=P9LmA9uN9EDHsHvucHFmIK1aHpuBimPgT1GZLrLcg+Q=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=wI/C5XGsjMfbUXWKfUQaDyq9s2sLqs+exQOXtK/3/ivJi53dCSg5O3p9beCR++drE gBGzfxIc8CZSdIHDiLPieTNM+q6ZKcI5aDMAQbv+/LzTVpx8Dc+OlE52Xep0q4cqPV BlAF1I5wJr9NKBSs5ibtrbJfRD7pDpz8HNP/EhBw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from burlywood.elm.relay.mailchannels.net (burlywood.elm.relay.mailchannels.net [23.83.212.26]) by sourceware.org (Postfix) with ESMTPS id 22144394FC3F for ; Thu, 17 Mar 2022 08:12:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 22144394FC3F 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 9DD766C23C3; Thu, 17 Mar 2022 08:12:21 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 0376A6C22E0; Thu, 17 Mar 2022 08:12:20 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504741; a=rsa-sha256; cv=none; b=1lJRiyb2hi9indwJuIVe4PBwLgJ4Bl/eX7M2CxliNkrUvJfc6dIJWikn0nyyEcAHqnpx+J MgOTwvQjX/C54frPw5rCW15hAi2acHz0bgGsH4gUHQa02nWt0oxiQiGfg3z/DGUS7vllls WSqfxfduYZlcCTcBaJnr9xJNXrkU646u+brIx/jz/j94pnmT3x3AAE+6BmMmqNv71QhL5M pli1RnQ6hi0oXXBEamBNPcQqNKrVCX5Bx5+ShkgaVAd76JwBG109NDDATp5e34Ig/Yv3kw DOJM8KVvR5msqnzH7Qi9AywwV3ENBWYpjGMUDzYnWPddCbDu5203k2YRkhwbfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504741; 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=P9LmA9uN9EDHsHvucHFmIK1aHpuBimPgT1GZLrLcg+Q=; b=nmJEhowGRsgqXBh8aXNNk0f56pKPD6E0fYOHAqO02JutqespwKxFkFs9O4JHLGVe9e9N99 DmqyxWdvIaJUFBZl3tO9a/afaeY8pxzJvtSXQaVo0kdGpuAfKDiIyf/qWVOTpBnq0pd5Gc 1KAhTQU8GNgZP/xTc+riKz8VZiYsSqcnuGg2bmHB+/amBCCoSgpyXY91UAVTingheEa0ve X02xKtfWLxE3Ynpo7tPBZUaq5Uq1jwntfwvGDPavyfzUPU5HsCADCQJC49JoQhI5mndsTw sibV1qMLuF8HFjNddpg1w2vWdop8YFrMDD7xQsf8fvfMsh5+/QZFE1S0ffNVEg== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-z6b84; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.109.126.219 (trex/6.5.3); Thu, 17 Mar 2022 08:12:21 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Trail-Tasty: 31a4041a72126372_1647504741329_2371594393 X-MC-Loop-Signature: 1647504741328:2576290667 X-MC-Ingress-Time: 1647504741328 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HP2b09z35; Thu, 17 Mar 2022 01:12:16 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 08/12] gaih_inet: separate nss lookup loop into its own function Date: Thu, 17 Mar 2022 13:41:36 +0530 Message-Id: <20220317081140.3098156-9-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Signed-off-by: Siddhesh Poyarekar --- sysdeps/posix/getaddrinfo.c | 563 ++++++++++++++++++------------------ 1 file changed, 286 insertions(+), 277 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 01be932b3f..f70ce2c76b 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, @@ -197,13 +205,10 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, /* 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. The new addresses are appended to the tuple array in - RESULT. */ + prematurely. The new addresses are appended to the tuple array in RES. */ 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 +220,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 != NULL) @@ -224,12 +229,14 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, array = array->next; } - array = realloc (*result, (old + count) * sizeof (*array)); + array = realloc (res->at, (old + count) * sizeof (*array)); if (array == NULL) return false; - *result = array; + res->got_ipv6 = family == AF_INET6; + res->at = array; + 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 @@ -723,7 +981,7 @@ try_simple_gethostbyname (const char *name, const struct addrinfo *req, /* We found data, convert it. RES->AT from the conversion will either be an allocated block or NULL, both of which are safe to pass to free (). */ - 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; @@ -801,264 +1059,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; - got_ipv6 = false; - - 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 { @@ -1089,6 +1097,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 Thu Mar 17 08:11:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52036 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DAA67395200B for ; Thu, 17 Mar 2022 08:18:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DAA67395200B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505104; bh=iAcRDD0g+Amugsdsfu64bFFOV5OzPRfwdyap8Z2y7Ac=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=ta1M/YqtpWZBbm8okSzsSI3iW+KL4nWKWqSkfHzV3FGtABLQiyX/sySZExwwOe22S MVJdREGwzqG/dRl5R5IZr1J4BmPaa6HExZiJGh2A0j8prZNoo0mcUxrG6EgsVVtueV Tj1QFSAYAu4MW7NlYDkgKkei64S7gETkxbAY3Fwc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from bat.birch.relay.mailchannels.net (bat.birch.relay.mailchannels.net [23.83.209.13]) by sourceware.org (Postfix) with ESMTPS id 36CF5395200E for ; Thu, 17 Mar 2022 08:12:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 36CF5395200E 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 0B805621676; Thu, 17 Mar 2022 08:12:22 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id A50C0621613; Thu, 17 Mar 2022 08:12:21 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504741; a=rsa-sha256; cv=none; b=pP10+Snnbg7/Pzs78DyZnBgIslgAoyPmxR9KHqMHKE+Mb9Mg8WM3lWwGBfyfwAjPW/vnP1 SUKhWpt1Kr117qpdtGSZEByG32gx3EVBooeA+fz0XrWiyjD/SH36y9tIet5UBRGmOWAM++ 3uG28rVxYJiIewgUyXD+R5YPsp8pERvAqhyniQG/Ykj/oBkNDDW4aTcMt/JQM5GOcfppD3 jmCASLqByWlDQZsEoASv0Clh5CHlg8QsTUcFcSyHkh07WdNHpSCbm2+hzfgIINSQ+DRo2L 41g4f743iS0oZGcn8cpGRAxJY5cDl4TIss4zCpJcESEyWRn7cVn2WzpP8vroIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504741; 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=iAcRDD0g+Amugsdsfu64bFFOV5OzPRfwdyap8Z2y7Ac=; b=Elv9mdYiitB/+GnPjc1d9JYNf2L4jUuIrFB75BQfz1LUYc4w+niXQiWPAi/Sw50wNvNWPg hOOPMcjkb7ecW5wvmzGFr0ZcYU4ptlp25ntRrXBCj+grhZkn/Kq0kCCJdvnXf+rvzT6BHj GYrSFWZ96JQPkGnCbeZOVPNUaJIBGwmZklFH51N3TZEQw6BsQ4cPm70dmfcgYg7oDfeZS8 qSxePPzOQfkjatrps07KioVt3Qj7UwaVP3cdxfT7c+TXEi8MmGtkCUxrWRjyXaJ1Oi5pQS YP5ukqVLm5wayAVT+nfh/5bj0yO1kIFKE8zCBaDQ/KKShiulzMN4I58x5XDUqw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-drv7b; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.119.141.221 (trex/6.5.3); Thu, 17 Mar 2022 08:12:22 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Stretch-Shrill: 191c92605151d1a0_1647504741918_2269380621 X-MC-Loop-Signature: 1647504741917:336861812 X-MC-Ingress-Time: 1647504741917 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HR56vCz21; Thu, 17 Mar 2022 01:12:19 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 09/12] gaih_inet: make gethosts into a function Date: Thu, 17 Mar 2022 13:41:37 +0530 Message-Id: <20220317081140.3098156-10-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- 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 f70ce2c76b..bc385dd322 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 Thu Mar 17 08:11:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52039 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 88CFF394FC35 for ; Thu, 17 Mar 2022 08:20:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 88CFF394FC35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505237; bh=lplm7I6GwX7WlTJjwwhVm1On8CatjaivBAgdQucnXKA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=u+N2AEJkPMTgTj+0kYYL5nvIxBzjKJU7MlYxLIKl3+eRX5m6lcek3wMKw1NPuS7bB 6qJVBe+cvotI6rDsZQZOSYvQCbN9whwPLZ/VlVQ+cd3wtqLiJvYw582f636igDmULh 08mODCOUySFlAlMxyTEqnCWNRCgHCORXTudvwcpQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from bat.birch.relay.mailchannels.net (bat.birch.relay.mailchannels.net [23.83.209.13]) by sourceware.org (Postfix) with ESMTPS id 4CEE0395200B for ; Thu, 17 Mar 2022 08:12:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4CEE0395200B 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 97ED78219E8; Thu, 17 Mar 2022 08:12:24 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id D7B0A8214E2; Thu, 17 Mar 2022 08:12:23 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504743; a=rsa-sha256; cv=none; b=Evqemq/1fURCTkIExcYnrStlBd8BP0UYC1h3xGyiP7d75S2oLHM76eKX6eYS5u0UV4FTS0 uqQdgO5b7gG64B/mFxdmhTrW5FOftWYJp21MOtDnGde1+YYhfOLZCTe0B5yANjsyXEih2o edQjdeP73aUT+wWVeYEahLo1Wwugio2IG8/9alIWx2Jv5l8kyoou/Oes2worOy6ZYtFkZE Kw8EPm818Ufpgt4ZqS7pa0j265fSF24a4b9e8LjV6g0QKzwuy/4BaEQ7kWDdKVmxIir6eq BMkf4NgEKXxE2OAB0T2XHteYpuy2tPta54Y3WjBqR1P5hjlQR/jtpf3zS5nBPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504743; 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=lplm7I6GwX7WlTJjwwhVm1On8CatjaivBAgdQucnXKA=; b=bCq/L3Tv1PWHb3/03hXyfsuMEpcimONOIiA01sR4ckBa/2PEg1lbha6YwSqZFOwpKmjQUZ tYchX/Cm7SsuPviq96izixxBzP5rqAkTPrZqeIuhr+vY3sRpfsCEKRsVG/gzlvYOAKfz6D f0bem3A84phsjeuQ+P7EPpWhYHdvRNBZWOhv5uGq+iX/yNkabUk/bt5+YiuVpajE3fhI7Z SskR7kEF3+T4oIZOhOU3IlZl+voPFhk9CHZqmJj+eRGs6VTEPseKoE58pz2WtNOLHQdHty JxhkiQy0F9hPnQbZanUlvtSb1buh7esk+eCstK4XgJyUYXIer3AO53cYPjDlBw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-5f7zz; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.102.3.17 (trex/6.5.3); Thu, 17 Mar 2022 08:12:24 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Power-Shoe: 73a8ebbb5d2e0c7b_1647504744419_3226048014 X-MC-Loop-Signature: 1647504744419:437542687 X-MC-Ingress-Time: 1647504744419 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HV12b6z1Q; Thu, 17 Mar 2022 01:12:21 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 10/12] gaih_inet: split loopback lookup into its own function Date: Thu, 17 Mar 2022 13:41:38 +0530 Message-Id: <20220317081140.3098156-11-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- 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 bc385dd322..47c41d332d 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1004,6 +1004,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, @@ -1014,10 +1040,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; @@ -1027,76 +1049,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 Thu Mar 17 08:11:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52038 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AC6603952002 for ; Thu, 17 Mar 2022 08:19:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC6603952002 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505194; bh=KqUFmzIGcUaNC4WtiqpkJIzXFIRaFFjX9KAQZLkteE0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=du9R0t7T7KZm9VPWfyb7YSQ1YYIyVOA2OHUhg+eK7H+XpyROo0CbSvJIVkDAUQrQl yAmUo6RhKQKWuPaFL2i+Ak8TxvbDgx/JpV6Z1xmmTPC3asv81oLHJyc+lWymPL0+Tz Tyq57nDU6pCZzw/ULgI5BRXp0YuRD2pD5Q7HVtEc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from bat.birch.relay.mailchannels.net (bat.birch.relay.mailchannels.net [23.83.209.13]) by sourceware.org (Postfix) with ESMTPS id 65A643952002 for ; Thu, 17 Mar 2022 08:12:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 65A643952002 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 96DEB4619EB; Thu, 17 Mar 2022 08:12:26 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 28B8A46208B; Thu, 17 Mar 2022 08:12:26 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504746; a=rsa-sha256; cv=none; b=4v3mc1zFHdcIpMY8Cr86Ypz+1+zVcJpTH0268y/pXM7muUA0C7UkRsvtJrzG8aLezkhb8/ TF+n3Tt+16BYwlN735GbjhBGuYDSHDh4LnnTD2PJTM2geS20a8jouoyuXAMv0Zqutvkco9 1gIZAZ1S6V7E96KmKXOItyzbMJeHhhFv6y4A9rIzZcKYe3tpwMATIRSwEsK7t/t0ozNjcD EkO8RGpFi5vPK8mBtw+KVt+oDLw3nJjQ/0wLX66f9STlOojU1E0XJ723jezDzIXdcCGV8z 6UM/5yoS2OIHlEWqHwOQTwsH8RicdKHln/KwHIHij4BfV5OXt4guovTlI08tag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504746; 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=KqUFmzIGcUaNC4WtiqpkJIzXFIRaFFjX9KAQZLkteE0=; b=hRGv6bGE/cdkSAkCyPbMnp0wQd/rB0WtI9CLqGx18gjD4muHdIcZqZ8ME3dUyMy9bpCxaO aV2P7vm6qQKMmBhVbi22QVEPqmwEL4rPebsYy3NSaMcZCM2nbiqAjPiQXNWkBK6IPFsEn8 LFarH1WaSrJlnJ4c6iUpV+lLJmh/+LqPTlUMvNjAvMveNwMJfl+MttsNmLfD9yJjYbmFcF sITft661MmWYkIjIgdwzp5jXNUcf9MSNBh1s/9IN8ujjkyob654YY0LNW/+R35VRjG6dp1 g7R9FKMqidw2mrjwvs8qa2dt/KY/tgL4TSw0kAY5O9eu1akW9t/iz8KjhvZCMw== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-v8wrk; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.109.126.219 (trex/6.5.3); Thu, 17 Mar 2022 08:12:26 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Illegal-Abiding: 3dc0a1cb6682daf6_1647504746432_975533317 X-MC-Loop-Signature: 1647504746432:1672184615 X-MC-Ingress-Time: 1647504746432 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HX3595z21; Thu, 17 Mar 2022 01:12:24 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 11/12] gaih_inet: Split result generation into its own function Date: Thu, 17 Mar 2022 13:41:39 +0530 Message-Id: <20220317081140.3098156-12-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Simplify the loop a wee bit and clean up variable names too. Signed-off-by: Siddhesh Poyarekar Reviewed-by: DJ Delorie --- 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 47c41d332d..f5d4a5cfd9 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1030,6 +1030,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, @@ -1096,98 +1177,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 Thu Mar 17 08:11:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 52040 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 119EE395200E for ; Thu, 17 Mar 2022 08:21:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 119EE395200E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647505280; bh=u11TagLvQeFUy6GvHTipQVqq24Hf9aGsofKOwSIESBo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=TWf1svXAH+B3sQnq4aaAYHfKMgttmFzAA+KWZMWFtCJs/DJsCGwvKa+03vmrnB5/A n4C9848lbQ/drBdgSLUXMEJqaWSAHlG5nR2TYakMfbuKx2ilM7oWofOEEgTXOX7Etx baZvUdzW/8TZkBOMTNaBGO+K+r4oOTZbrLpbz4P4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from burlywood.elm.relay.mailchannels.net (burlywood.elm.relay.mailchannels.net [23.83.212.26]) by sourceware.org (Postfix) with ESMTPS id 61F84394FC30 for ; Thu, 17 Mar 2022 08:12:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 61F84394FC30 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 77B446C24C3; Thu, 17 Mar 2022 08:12:29 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 814516C1FF3; Thu, 17 Mar 2022 08:12:28 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504748; a=rsa-sha256; cv=none; b=raj52U1Tcx+o16PEYI5yqzkYnDlzxVSWTWlhwEdk+1qWKcTfYrN8NjfeKP61HBBHLoDBff qZk3Q49/BnqhIDLPctfMLGmI21j62JSHAo1R5fHAO12ygt3loKUf/4SUMozAYcTOT+6l+C Pn8nahrmHLB24fn0uJo4syhFg/Cqrz6hW7MyOT2+U7VLeuPsjTANhBvUEDWsttFRq1ElWg jqKz2pIY8hTIWIhAadZAcvUr829o3g4Fj9dvOUYinQR8qal9kTgB0Zflvaj675hzpcQWsL zNKWm9gbwaj0QaPBN1bON9GjH50+IM/EStcgEiR8pBWCb8tozcZR4wcS32ck2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504748; 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=u11TagLvQeFUy6GvHTipQVqq24Hf9aGsofKOwSIESBo=; b=F9bksLpNdcfWj8SJJo+N1tGvSKHdmxxGHgecEOEhxn4eiZiLGetIFxLUlZKq1yJf+UbD1R q8c0KMFzQJluuilAE/2frqs/8hcOv3Ry5ptmJQ86u7cnPt0BqjV1pzv+ol16+Ofh1c6imq 4Dc2csL2+LkynsA13iCkeuSRIycmprIzjtrWlrdBXNc3BJWPAnVH7JQkDqB/2QFOoWFkE/ 6XOu4RnfaAWgjpPWQIU+nJ5apnUhL4waG9UqbYZs3+kplugDZ+Zpku9Bf1FPsiHKXaZPQN ltAZJWr/QMbcptMsSTWUy5tG74ydbGt4fSOrxWyKOm+WWwkArNXO7zWGgy13UQ== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-szwtj; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.112.20.208 (trex/6.5.3); Thu, 17 Mar 2022 08:12:29 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Cellar-Society: 69383f445e8d0184_1647504749257_660557005 X-MC-Loop-Signature: 1647504749257:2212357599 X-MC-Ingress-Time: 1647504749257 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (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-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HZ5fDcz21; Thu, 17 Mar 2022 01:12:26 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v3 12/12] gethosts: Return EAI_MEMORY on allocation failure Date: Thu, 17 Mar 2022 13:41:40 +0530 Message-Id: <20220317081140.3098156-13-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3495.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H2, RCVD_IN_SBL, 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 Errors-To: libc-alpha-bounces+patchwork=sourceware.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 Reviewed-by: DJ Delorie --- 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 f5d4a5cfd9..0ece3b46b7 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; } }