public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
To: glibc-cvs@sourceware.org
Subject: [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup
Date: Wed, 23 Feb 2022 09:02:56 +0000 (GMT)	[thread overview]
Message-ID: <20220223090256.1D5533947C3A@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2906e90170910f176edaceb69476b69d21be5fb3

commit 2906e90170910f176edaceb69476b69d21be5fb3
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Thu Feb 17 12:59:26 2022 +0530

    gaih_inet: Split out nscd lookup
    
    Split the nscd address lookup code into its own function.

Diff:
---
 sysdeps/posix/getaddrinfo.c | 234 ++++++++++++++++++++++++--------------------
 1 file changed, 127 insertions(+), 107 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 876e590c48..593d99c2dc 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -409,6 +409,122 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
   return 0;
 }
 
+#ifdef USE_NSCD
+/* Query addresses from nscd cache, return true if a result is found and no
+   more further lookups are needed.  RC contains the result code that is zero
+   on successful lookup.  PAT points to a tuple list that must be NULL on
+   entry.  */
+
+static struct gaih_addrtuple *
+get_nscd_addresses (const char *name, const struct addrinfo *req,
+		    bool *got_ipv6, int *rc)
+{
+  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.  */
+	  char *addrs = air->addrs;
+
+	  struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
+
+	  if (at == NULL)
+	    {
+	      *rc = -EAI_MEMORY;
+	      return NULL;
+	    }
+
+	  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)
+		    *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)
+		{
+		  free (at);
+		  *rc = -EAI_MEMORY;
+		  return NULL;
+		}
+	      at[0].name = canonbuf;
+	    }
+
+	  if (count == 0)
+	    {
+	      free (at);
+	      *rc = -EAI_NONAME;
+	      return NULL;
+	    }
+	  at[count - 1].next = NULL;
+
+	  free (air);
+
+	  return at;
+	}
+      else if (err == 0)
+	/* The database contains a negative entry.  */
+	return NULL;
+      else if (__nss_not_use_nscd_hosts == 0)
+	{
+	  if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
+	    *rc = -EAI_MEMORY;
+	  else if (h_errno == TRY_AGAIN)
+	    *rc = -EAI_AGAIN;
+	  else
+	    *rc = -EAI_SYSTEM;
+
+	  return NULL;
+	}
+    }
+
+  *rc = 0;
+  return NULL;
+}
+#endif
+
+
 /* Return a numeric result in a dynamically allocated address tuple to be freed
    by the caller. Also set *CANONP if successful.  On failure, set RETP to the
    error code, except when AI_NUMERICHOST is not requested, where NULL is
@@ -636,6 +752,17 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	    goto free_and_return;
 	}
 
+#ifdef USE_NSCD
+      if ((at = get_nscd_addresses (name, req, &got_ipv6, &result)) != NULL)
+	{
+	  canon = canonbuf = at->name;
+	  addrmem = at;
+	  goto process_list;
+	}
+      else if (result != 0)
+	goto free_and_return;
+#endif
+
       struct gaih_addrtuple **pat = &at;
       int no_data = 0;
       int no_inet6_data = 0;
@@ -645,113 +772,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
       int no_more;
       struct resolv_context *res_ctx = NULL;
 
-#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;
-	      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 (canonbuf == NULL)
-		    {
-		      canonbuf = __strdup (air->canon);
-		      if (canonbuf == NULL)
-			{
-			  result = -EAI_MEMORY;
-			  goto free_and_return;
-			}
-		      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


             reply	other threads:[~2022-02-23  9:02 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-23  9:02 Siddhesh Poyarekar [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-03-01  2:40 Siddhesh Poyarekar
2022-02-23 10:07 Siddhesh Poyarekar
2022-02-22 13:51 Siddhesh Poyarekar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220223090256.1D5533947C3A@sourceware.org \
    --to=siddhesh@sourceware.org \
    --cc=glibc-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).