From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dormouse.elm.relay.mailchannels.net (dormouse.elm.relay.mailchannels.net [23.83.212.50]) by sourceware.org (Postfix) with ESMTPS id 6044B3857415 for ; Mon, 14 Mar 2022 09:49:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6044B3857415 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 1D24F281A2C for ; Mon, 14 Mar 2022 09:49:29 +0000 (UTC) Received: from pdx1-sub0-mail-a305.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 9FECC281A6D for ; Mon, 14 Mar 2022 09:49:13 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647251368; a=rsa-sha256; cv=none; b=c+gnSEt58AGO98+LLtyAjJ4+QU97568idCYVBzlCLsGh0KhnhCpXdoSlbvtK6z0S2ige1i Zv4qn80UducFwkFAX6YVU5BKqDQ0ZVMDNQAr2Lw9/T+BvkqaVwa9Ff/wqkeFB4QQSxG6wr W6rpJKdDRx4uu9kMSMWSm0CRfSJAHLTQeYep02Nz4Mbn/XGa3GVcG7fUmq9HNmUy8ovhvk l1hfjg5Q3HtkE8yeJZM+dd4AbknFmzSKf7heIt318JeZ4KAUl1zn9vQHqSn3vMsv+qPj/M OM9r/0w5/A7+EjxOjiUYwgk7YBMCXVCwaeW+HG6EXQPWelRghIhcWMsV4Vpypg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647251368; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uwgdywGoVoW+Ljpz4PAXg8sf2AYQ/j9TlgrGeFyH2dE=; b=6mhyZbb0rkpxWPFK8Uu/c2idpAsY1U/Uqq6yvd/YUuBcGY8FKK1ZVs+kFZJ4V+/rhCrITu CdxGmNZ0dlHBdkEDApyNDvDsAc3/nfZAArS6kMEtNzuxEVcGJmJ2s/SyokyZrqUn8DwOaq tTprtsL6YDKvOz6pSB1U4mSjQ7KuZMlDIJfCC1+MO0zeuxHhmx3tWBVSLOHdMt5gOpSdDd eZHKgVJEDyOTBAzDtYBtZ2r2rzmMPcX5LJhk0ernoCWrC4+EfRNoKAyYiUiUwnDoynBLWg 8D4ivOFt8galXfY5zGefVCy17oUKICXsX41o9Bvi/zVyhNeftckTwbonOIzuuA== ARC-Authentication-Results: i=1; rspamd-c9cb649d9-85c2d; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a305.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.112.20.197 (trex/6.5.3); Mon, 14 Mar 2022 09:49:28 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Cold-Inform: 33582afa547934d7_1647251368875_2368385538 X-MC-Loop-Signature: 1647251368875:1290621472 X-MC-Ingress-Time: 1647251368875 Received: from rhbox.redhat.com (unknown [106.220.192.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a305.dreamhost.com (Postfix) with ESMTPSA id 4KHBZK3ZpGz1NP for ; Mon, 14 Mar 2022 02:48:57 -0700 (PDT) From: Siddhesh Poyarekar To: libc-alpha@sourceware.org Subject: [PATCH v2 07/12] gaih_inet: Split nscd lookup code into its own function. Date: Mon, 14 Mar 2022 15:18:30 +0530 Message-Id: <20220314094835.1159523-8-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220314094835.1159523-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220314094835.1159523-1-siddhesh@sourceware.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1169.6 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_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Mar 2022 09:49:32 -0000 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 bcceab7d07..ba5028ad7b 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -121,6 +121,7 @@ struct gaih_result struct gaih_addrtuple *at; char *canon; bool free_at; + bool got_ipv6; }; /* Values for `protoflag'. */ @@ -316,7 +317,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, res.canon = canonbuf; \ } \ if (_family == AF_INET6 && *pat != NULL) \ - got_ipv6 = true; \ + res.got_ipv6 = true; \ } \ } @@ -467,6 +468,128 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req, return 0; } +#ifdef USE_NSCD +/* Query addresses from nscd cache, returning a non-zero value on error. + RES members have the lookup result; RES->AT is NULL if there were no errors + but also no results. */ + +static int +get_nscd_addresses (const char *name, const struct addrinfo *req, + struct gaih_result *res) +{ + if (__nss_not_use_nscd_hosts > 0 + && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) + __nss_not_use_nscd_hosts = 0; + + res->at = NULL; + + if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts]) + return 0; + + /* Try to use nscd. */ + struct nscd_ai_result *air = NULL; + int err = __nscd_getai (name, &air, &h_errno); + + if (__glibc_unlikely (air == NULL)) + { + /* The database contains a negative entry. */ + if (err == 0) + return -EAI_NONAME; + if (__nss_not_use_nscd_hosts == 0) + { + if (h_errno == NETDB_INTERNAL && errno == ENOMEM) + return -EAI_MEMORY; + if (h_errno == TRY_AGAIN) + return -EAI_AGAIN; + return -EAI_SYSTEM; + } + return 0; + } + + /* Transform into gaih_addrtuple list. */ + int result = 0; + char *addrs = air->addrs; + + struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree)); + struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at)); + if (at == NULL) + { + result = -EAI_MEMORY; + goto out; + } + + res->free_at = true; + + int count = 0; + for (int i = 0; i < air->naddrs; ++i) + { + socklen_t size = (air->family[i] == AF_INET + ? INADDRSZ : IN6ADDRSZ); + + if (!((air->family[i] == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) != 0) + || req->ai_family == AF_UNSPEC + || air->family[i] == req->ai_family)) + { + /* Skip over non-matching result. */ + addrs += size; + continue; + } + + if (air->family[i] == AF_INET && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED)) + { + at[count].family = AF_INET6; + at[count].addr[3] = *(uint32_t *) addrs; + at[count].addr[2] = htonl (0xffff); + } + else if (req->ai_family == AF_UNSPEC + || air->family[count] == req->ai_family) + { + at[count].family = air->family[count]; + memcpy (at[count].addr, addrs, size); + if (air->family[count] == AF_INET6) + res->got_ipv6 = true; + } + at[count].next = at + count + 1; + count++; + addrs += size; + } + + if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL) + { + char *canonbuf = __strdup (air->canon); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto out; + } + res->canon = canonbuf; + } + + if (count == 0) + { + result = -EAI_NONAME; + goto out; + } + + at[count - 1].next = NULL; + + res->at = at; + +out: + free (air); + if (result != 0) + { + free (at); + res->free_at = false; + } + + return result; +} +#endif + /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and the function cannot determine a result, RES->AT is set to NULL and 0 @@ -628,7 +751,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_servtuple st[sizeof (gaih_inet_typeproto) / sizeof (struct gaih_typeproto)] = {0}; - bool got_ipv6 = false; const char *orig_name = name; /* Reserve stack memory for the scratch buffer in the getaddrinfo @@ -670,6 +792,13 @@ gaih_inet (const char *name, const struct gaih_service *service, else if (res.at != NULL) goto process_list; +#ifdef USE_NSCD + if ((result = get_nscd_addresses (name, req, &res)) != 0) + goto free_and_return; + else if (res.at != NULL) + goto process_list; +#endif + int no_data = 0; int no_inet6_data = 0; nss_action_list nip; @@ -679,115 +808,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct resolv_context *res_ctx = NULL; bool do_merge = false; -#ifdef USE_NSCD - if (__nss_not_use_nscd_hosts > 0 - && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY) - __nss_not_use_nscd_hosts = 0; - - if (!__nss_not_use_nscd_hosts - && !__nss_database_custom[NSS_DBSIDX_hosts]) - { - /* Try to use nscd. */ - struct nscd_ai_result *air = NULL; - int err = __nscd_getai (name, &air, &h_errno); - if (air != NULL) - { - /* Transform into gaih_addrtuple list. */ - bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; - char *addrs = air->addrs; - - addrmem = calloc (air->naddrs, sizeof (*addrmem)); - if (addrmem == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - - struct gaih_addrtuple *addrfree = addrmem; - struct gaih_addrtuple **pat = &res.at; - - for (int i = 0; i < air->naddrs; ++i) - { - socklen_t size = (air->family[i] == AF_INET - ? INADDRSZ : IN6ADDRSZ); - - if (!((air->family[i] == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) != 0) - || req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family)) - { - /* Skip over non-matching result. */ - addrs += size; - continue; - } - - if (*pat == NULL) - { - *pat = addrfree++; - (*pat)->scopeid = 0; - } - uint32_t *pataddr = (*pat)->addr; - (*pat)->next = NULL; - if (added_canon || air->canon == NULL) - (*pat)->name = NULL; - else if (res.canon == NULL) - { - char *canonbuf = __strdup (air->canon); - if (canonbuf == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - res.canon = (*pat)->name = canonbuf; - } - - if (air->family[i] == AF_INET - && req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED)) - { - (*pat)->family = AF_INET6; - pataddr[3] = *(uint32_t *) addrs; - pataddr[2] = htonl (0xffff); - pataddr[1] = 0; - pataddr[0] = 0; - pat = &((*pat)->next); - added_canon = true; - } - else if (req->ai_family == AF_UNSPEC - || air->family[i] == req->ai_family) - { - (*pat)->family = air->family[i]; - memcpy (pataddr, addrs, size); - pat = &((*pat)->next); - added_canon = true; - if (air->family[i] == AF_INET6) - got_ipv6 = true; - } - addrs += size; - } - - free (air); - - goto process_list; - } - else if (err == 0) - /* The database contains a negative entry. */ - goto free_and_return; - else if (__nss_not_use_nscd_hosts == 0) - { - if (h_errno == NETDB_INTERNAL && errno == ENOMEM) - result = -EAI_MEMORY; - else if (h_errno == TRY_AGAIN) - result = -EAI_AGAIN; - else - result = -EAI_SYSTEM; - - goto free_and_return; - } - } -#endif - no_more = !__nss_database_get (nss_database_hosts, &nip); /* If we are looking for both IPv4 and IPv6 address we don't @@ -894,7 +914,7 @@ gaih_inet (const char *name, const struct gaih_service *service, no_data = 0; if (req->ai_family == AF_INET6) - got_ipv6 = true; + res.got_ipv6 = true; } else *pat = ((*pat)->next); @@ -937,7 +957,7 @@ gaih_inet (const char *name, const struct gaih_service *service, && (req->ai_flags & AI_V4MAPPED) /* Avoid generating the mapped addresses if we know we are not going to need them. */ - && ((req->ai_flags & AI_ALL) || !got_ipv6))) + && ((req->ai_flags & AI_ALL) || !res.got_ipv6))) { gethosts (AF_INET); @@ -1088,7 +1108,7 @@ gaih_inet (const char *name, const struct gaih_service *service, /* If we looked up IPv4 mapped address discard them here if the caller isn't interested in all address and we have found at least one IPv6 address. */ - if (got_ipv6 + if (res.got_ipv6 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED && IN6_IS_ADDR_V4MAPPED (at2->addr)) goto ignore; -- 2.35.1