public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup
@ 2022-03-01  2:40 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-03-01  2:40 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6e70668051767f146eeaad1bbe184a3092944892

commit 6e70668051767f146eeaad1bbe184a3092944892
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Mon Feb 28 19:01:43 2022 +0530

    gaih_inet: Split out nscd lookup
    
    Split the nscd address lookup code into its own function.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

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

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index fbb8139d5a..010360986a 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -121,6 +121,8 @@ struct gaih_lookup_result
   struct gaih_addrtuple *at;		/* The first result tuple.  */
   struct scratch_buffer *allocs;	/* Pointers to allocated tuples.  */
   size_t nallocs;			/* Count of such pointers.  */
+  bool got_ipv6;			/* True if an IPv6 result was
+					   returned. */
 };
 
 /* Initialize RES with BUF, an initialized scratch buffer.  */
@@ -453,6 +455,133 @@ 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 int
+get_nscd_addresses (const char *name, const struct addrinfo *req,
+		    struct gaih_lookup_result *res)
+{
+  res->at = NULL;
+
+  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])
+    return 0;
+
+  /* Try to use nscd.  */
+  struct nscd_ai_result *air = NULL;
+  int err = __nscd_getai (name, &air, &h_errno);
+
+  if (air != NULL)
+    {
+      int result = 0;
+      /* Transform into gaih_addrtuple list.  */
+      char *addrs = air->addrs;
+
+      struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
+
+      if (at == NULL)
+	{
+	  result = -EAI_MEMORY;
+	  goto out;
+	}
+
+      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;
+	    }
+	  at[0].name = canonbuf;
+	}
+
+      if (count == 0)
+	{
+	  result = -EAI_NONAME;
+	  goto out;
+	}
+
+      at[count - 1].next = NULL;
+
+      if (!gaih_lookup_result_push_alloc (res, at))
+	{
+	  result = -EAI_MEMORY;
+	  goto out;
+	}
+
+      res->at = at;
+
+out:
+      if (result != 0)
+	free (at);
+
+      free (air);
+      return result;
+    }
+
+  if (err == 0)
+    /* The database contains a negative entry.  */
+    return 0;
+
+  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;
+}
+#endif
+
 /* Allocate an address tuple and pass back to caller in PAT; caller must free
    it once it is done.  On failure, PAT is set to NULL and an error code is
    returned.  If AI_NUMERIC_HOST is not requested and the function cannot
@@ -698,6 +827,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	    }
 	}
 
+#ifdef USE_NSCD
+      if ((result = get_nscd_addresses (name, req, &res)) != 0)
+	goto free_and_return;
+      else if (res.at != NULL)
+	{
+	  at = res.at;
+	  canon = canonbuf = at->name;
+	  got_ipv6 = res.got_ipv6;
+	  goto process_list;
+	}
+#endif
+
       struct gaih_addrtuple **pat = &at;
       int no_data = 0;
       int no_inet6_data = 0;
@@ -707,113 +848,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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup
@ 2022-02-23 10:07 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-02-23 10:07 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=98964e703ac62ee0d5e5d52f575b4813264e72f8

commit 98964e703ac62ee0d5e5d52f575b4813264e72f8
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 cf7de73d52..45c351d4ab 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
@@ -654,6 +770,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;
@@ -663,113 +790,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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup
@ 2022-02-23  9:02 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-02-23  9:02 UTC (permalink / raw)
  To: glibc-cvs

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup
@ 2022-02-22 13:51 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-02-22 13:51 UTC (permalink / raw)
  To: glibc-cvs

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

commit d2fb8cb39ff91398b5269d7e53b7ed9b16104a53
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 ad2ae73afe..86c81e7e94 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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-03-01  2:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-01  2:40 [glibc/siddhesh/gai-cleanup2] gaih_inet: Split out nscd lookup Siddhesh Poyarekar
  -- strict thread matches above, loose matches on Subject: below --
2022-02-23 10:07 Siddhesh Poyarekar
2022-02-23  9:02 Siddhesh Poyarekar
2022-02-22 13:51 Siddhesh Poyarekar

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).