public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/siddhesh/gai-cleanup2] gaih_inet: WIP: Make SUCCESS=merge work with hosts
@ 2022-02-23  9:03 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-02-23  9:03 UTC (permalink / raw)
  To: glibc-cvs

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

commit d82ffede30901bbaab7889af971bd38124337a9f
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Tue Feb 22 20:08:21 2022 +0530

    gaih_inet: WIP: Make SUCCESS=merge work with hosts
    
    It fails in weird ways, which is obvious since subsequent responses will
    write to the same scratch buffer.  Allocate proper memory and start
    accounting using a scratch buffer.  This should be useful for
    gethostbyname3, etc. too.
    
    The broken out function will look different though, lets see.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

Diff:
---
 sysdeps/posix/getaddrinfo.c | 101 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 84 insertions(+), 17 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 593d99c2dc..7e087a763e 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -151,6 +151,32 @@ static const struct addrinfo default_hints =
     .ai_next = NULL
   };
 
+/* Record PTR in the ALLOCSP scratch buffer to be freed later in FUNC_CLEANUP.
+   Increment NALLOCSP by 1 and return true if successful, false otherwise.  */
+
+static bool
+func_cleanup_push (struct scratch_buffer *allocsp, size_t *nallocsp, void *ptr)
+{
+  size_t nallocs = *nallocsp + 1;
+  if (nallocs * sizeof (void *) > allocsp->length
+      && !scratch_buffer_grow_preserve (allocsp))
+    return false;
+
+  ((void **) allocsp->data)[nallocs - 1] = ptr;
+  *nallocsp = nallocs;
+  return true;
+}
+
+/* Free NALLOCS pointers recorded in ALLOCSP.  */
+
+static void
+func_cleanup (struct scratch_buffer *allocsp, size_t nallocs)
+{
+  while (nallocs-- > 0)
+    free (((void **) allocsp->data)[nallocs]);
+
+  scratch_buffer_free (allocsp);
+}
 
 static int
 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
@@ -417,6 +443,7 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
 
 static struct gaih_addrtuple *
 get_nscd_addresses (const char *name, const struct addrinfo *req,
+		    struct scratch_buffer *allocsp, size_t *nallocsp,
 		    bool *got_ipv6, int *rc)
 {
   if (__nss_not_use_nscd_hosts > 0
@@ -501,6 +528,13 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
 
 	  free (air);
 
+	  if (!func_cleanup_push (allocsp, nallocsp, at))
+	    {
+	      free (at);
+	      *rc = -EAI_MEMORY;
+	      return NULL;
+	    }
+
 	  return at;
 	}
       else if (err == 0)
@@ -531,7 +565,8 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
    returned, but RETP is set to 0.  */
 
 static struct gaih_addrtuple *
-get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
+get_numeric_res (const char *name, const struct addrinfo *req,
+		 struct scratch_buffer *allocsp, size_t *nallocsp, int *retp)
 {
   uint32_t addr[4] = {0};
 
@@ -566,6 +601,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
       if (req->ai_flags & AI_CANONNAME)
 	at->name = __strdup (name);
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -617,6 +659,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
       if (req->ai_flags & AI_CANONNAME)
 	at->name = __strdup (name);
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -637,6 +686,7 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
 
 static struct gaih_addrtuple *
 simple_gethostbyname (const char *name, const struct addrinfo *req,
+		      struct scratch_buffer *allocsp, size_t *nallocsp,
 		      struct scratch_buffer *tmpbuf, int *retp)
 {
   int rc;
@@ -688,6 +738,13 @@ simple_gethostbyname (const char *name, const struct addrinfo *req,
 	*retp = -EAI_NODATA;
     }
 
+  if (!func_cleanup_push (allocsp, nallocsp, at))
+    {
+      free (at);
+      *retp = -EAI_MEMORY;
+      return NULL;
+    }
+
   return at;
 }
 
@@ -717,6 +774,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
   char *canonbuf = NULL;
   int result = 0;
 
+  struct scratch_buffer allocs;
+  size_t nallocs = 0;
+  scratch_buffer_init (&allocs);
+
   if (name != NULL)
     {
       if (req->ai_flags & AI_IDN)
@@ -729,9 +790,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	  malloc_name = true;
 	}
 
-      if ((at = get_numeric_res (name, req, &result)) != NULL)
+      if ((at = get_numeric_res (name, req, &allocs, &nallocs, &result))
+	  != NULL)
 	{
-	  addrmem = at;
 	  canon = canonbuf = at->name;
 	  goto process_list;
 	}
@@ -743,20 +804,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	 IPv6 scope ids, nor retrieving the canonical name.  */
       if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0)
 	{
-	  if ((at = simple_gethostbyname (name, req, tmpbuf, &result)) != NULL)
-	    {
-	      addrmem = at;
-	      goto process_list;
-	    }
+	  if ((at = simple_gethostbyname (name, req, &allocs, &nallocs, tmpbuf,
+					  &result)) != NULL)
+	    goto process_list;
 	  else if (result != 0)
 	    goto free_and_return;
 	}
 
 #ifdef USE_NSCD
-      if ((at = get_nscd_addresses (name, req, &got_ipv6, &result)) != NULL)
+      if ((at = get_nscd_addresses (name, req, &allocs, &nallocs, &got_ipv6,
+				    &result)) != NULL)
 	{
 	  canon = canonbuf = at->name;
-	  addrmem = at;
 	  goto process_list;
 	}
       else if (result != 0)
@@ -782,10 +841,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
       if (res_ctx == NULL)
 	no_more = 1;
 
-      at = __alloca (sizeof (*at));
-      at->next = NULL;
-      at->family = AF_UNSPEC;
-
       while (!no_more)
 	{
 	  no_data = 0;
@@ -798,10 +853,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  if (fct4 != NULL)
 	    {
+	      size_t length = 1024;
+	      char *buf = malloc (length);
+
 	      while (1)
 		{
+		  *pat = NULL;
 		  status = DL_CALL_FCT (fct4, (name, pat,
-					       tmpbuf->data, tmpbuf->length,
+					       buf, length,
 					       &errno, &h_errno,
 					       NULL));
 		  if (status == NSS_STATUS_SUCCESS)
@@ -816,7 +875,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		      break;
 		    }
 
-		  if (!scratch_buffer_grow (tmpbuf))
+		  length *= 2;
+		  free (buf);
+		  if ((buf = malloc (length)) == NULL)
 		    {
 		      __resolv_context_put (res_ctx);
 		      result = -EAI_MEMORY;
@@ -824,6 +885,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		    }
 		}
 
+	      if (!func_cleanup_push (&allocs, &nallocs, buf))
+		{
+		  result = -EAI_MEMORY;
+		  goto free_and_return;
+		}
+
 	      if (status == NSS_STATUS_SUCCESS)
 		{
 		  assert (!no_data);
@@ -1152,7 +1219,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
  free_and_return:
   if (malloc_name)
     free ((char *) name);
-  free (addrmem);
+  func_cleanup (&allocs, nallocs);
   free (canonbuf);
 
   return result;


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

* [glibc/siddhesh/gai-cleanup2] gaih_inet: WIP: Make SUCCESS=merge work with hosts
@ 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=3302b87c2b799cc50b686b1ecd407ca485cdd538

commit 3302b87c2b799cc50b686b1ecd407ca485cdd538
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Tue Feb 22 20:08:21 2022 +0530

    gaih_inet: WIP: Make SUCCESS=merge work with hosts
    
    It fails in weird ways, which is obvious since subsequent responses will
    write to the same scratch buffer.  Allocate proper memory and start
    accounting using a scratch buffer.  This should be useful for
    gethostbyname3, etc. too.
    
    The broken out function will look different though, lets see.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

Diff:
---
 sysdeps/posix/getaddrinfo.c | 101 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 84 insertions(+), 17 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 45c351d4ab..6b6fdef376 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -151,6 +151,32 @@ static const struct addrinfo default_hints =
     .ai_next = NULL
   };
 
+/* Record PTR in the ALLOCSP scratch buffer to be freed later in FUNC_CLEANUP.
+   Increment NALLOCSP by 1 and return true if successful, false otherwise.  */
+
+static bool
+func_cleanup_push (struct scratch_buffer *allocsp, size_t *nallocsp, void *ptr)
+{
+  size_t nallocs = *nallocsp + 1;
+  if (nallocs * sizeof (void *) > allocsp->length
+      && !scratch_buffer_grow_preserve (allocsp))
+    return false;
+
+  ((void **) allocsp->data)[nallocs - 1] = ptr;
+  *nallocsp = nallocs;
+  return true;
+}
+
+/* Free NALLOCS pointers recorded in ALLOCSP.  */
+
+static void
+func_cleanup (struct scratch_buffer *allocsp, size_t nallocs)
+{
+  while (nallocs-- > 0)
+    free (((void **) allocsp->data)[nallocs]);
+
+  scratch_buffer_free (allocsp);
+}
 
 static int
 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
@@ -417,6 +443,7 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
 
 static struct gaih_addrtuple *
 get_nscd_addresses (const char *name, const struct addrinfo *req,
+		    struct scratch_buffer *allocsp, size_t *nallocsp,
 		    bool *got_ipv6, int *rc)
 {
   if (__nss_not_use_nscd_hosts > 0
@@ -501,6 +528,13 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
 
 	  free (air);
 
+	  if (!func_cleanup_push (allocsp, nallocsp, at))
+	    {
+	      free (at);
+	      *rc = -EAI_MEMORY;
+	      return NULL;
+	    }
+
 	  return at;
 	}
       else if (err == 0)
@@ -531,7 +565,8 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
    returned, but RETP is set to 0.  */
 
 static struct gaih_addrtuple *
-get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
+get_numeric_res (const char *name, const struct addrinfo *req,
+		 struct scratch_buffer *allocsp, size_t *nallocsp, int *retp)
 {
   uint32_t addr[4] = {0};
 
@@ -575,6 +610,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
 	  at->name = canonbuf;
 	}
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -635,6 +677,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
 	  at->name = canonbuf;
 	}
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -655,6 +704,7 @@ get_numeric_res (const char *name, const struct addrinfo *req, int *retp)
 
 static struct gaih_addrtuple *
 simple_gethostbyname (const char *name, const struct addrinfo *req,
+		      struct scratch_buffer *allocsp, size_t *nallocsp,
 		      struct scratch_buffer *tmpbuf, int *retp)
 {
   int rc;
@@ -706,6 +756,13 @@ simple_gethostbyname (const char *name, const struct addrinfo *req,
 	*retp = -EAI_NODATA;
     }
 
+  if (!func_cleanup_push (allocsp, nallocsp, at))
+    {
+      free (at);
+      *retp = -EAI_MEMORY;
+      return NULL;
+    }
+
   return at;
 }
 
@@ -735,6 +792,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
   char *canonbuf = NULL;
   int result = 0;
 
+  struct scratch_buffer allocs;
+  size_t nallocs = 0;
+  scratch_buffer_init (&allocs);
+
   if (name != NULL)
     {
       if (req->ai_flags & AI_IDN)
@@ -747,9 +808,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	  malloc_name = true;
 	}
 
-      if ((at = get_numeric_res (name, req, &result)) != NULL)
+      if ((at = get_numeric_res (name, req, &allocs, &nallocs, &result))
+	  != NULL)
 	{
-	  addrmem = at;
 	  canon = canonbuf = at->name;
 	  goto process_list;
 	}
@@ -761,20 +822,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	 IPv6 scope ids, nor retrieving the canonical name.  */
       if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0)
 	{
-	  if ((at = simple_gethostbyname (name, req, tmpbuf, &result)) != NULL)
-	    {
-	      addrmem = at;
-	      goto process_list;
-	    }
+	  if ((at = simple_gethostbyname (name, req, &allocs, &nallocs, tmpbuf,
+					  &result)) != NULL)
+	    goto process_list;
 	  else if (result != 0)
 	    goto free_and_return;
 	}
 
 #ifdef USE_NSCD
-      if ((at = get_nscd_addresses (name, req, &got_ipv6, &result)) != NULL)
+      if ((at = get_nscd_addresses (name, req, &allocs, &nallocs, &got_ipv6,
+				    &result)) != NULL)
 	{
 	  canon = canonbuf = at->name;
-	  addrmem = at;
 	  goto process_list;
 	}
       else if (result != 0)
@@ -800,10 +859,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
       if (res_ctx == NULL)
 	no_more = 1;
 
-      at = __alloca (sizeof (*at));
-      at->next = NULL;
-      at->family = AF_UNSPEC;
-
       while (!no_more)
 	{
 	  no_data = 0;
@@ -816,10 +871,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  if (fct4 != NULL)
 	    {
+	      size_t length = 1024;
+	      char *buf = malloc (length);
+
 	      while (1)
 		{
+		  *pat = NULL;
 		  status = DL_CALL_FCT (fct4, (name, pat,
-					       tmpbuf->data, tmpbuf->length,
+					       buf, length,
 					       &errno, &h_errno,
 					       NULL));
 		  if (status == NSS_STATUS_SUCCESS)
@@ -834,7 +893,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		      break;
 		    }
 
-		  if (!scratch_buffer_grow (tmpbuf))
+		  length *= 2;
+		  free (buf);
+		  if ((buf = malloc (length)) == NULL)
 		    {
 		      __resolv_context_put (res_ctx);
 		      result = -EAI_MEMORY;
@@ -842,6 +903,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		    }
 		}
 
+	      if (!func_cleanup_push (&allocs, &nallocs, buf))
+		{
+		  result = -EAI_MEMORY;
+		  goto free_and_return;
+		}
+
 	      if (status == NSS_STATUS_SUCCESS)
 		{
 		  assert (!no_data);
@@ -1170,7 +1237,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
  free_and_return:
   if (malloc_name)
     free ((char *) name);
-  free (addrmem);
+  func_cleanup (&allocs, nallocs);
   free (canonbuf);
 
   return result;


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

* [glibc/siddhesh/gai-cleanup2] gaih_inet: WIP: Make SUCCESS=merge work with hosts
@ 2022-02-22 14:56 Siddhesh Poyarekar
  0 siblings, 0 replies; 4+ messages in thread
From: Siddhesh Poyarekar @ 2022-02-22 14:56 UTC (permalink / raw)
  To: glibc-cvs

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

commit 9a11875d494ca6f89f2794fcf327d80f89a2cc48
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Tue Feb 22 20:08:21 2022 +0530

    gaih_inet: WIP: Make SUCCESS=merge work with hosts
    
    It fails in weird ways, which is obvious since subsequent responses will
    write to the same scratch buffer.  Allocate proper memory and start
    accounting using a scratch buffer.  This should be useful for
    gethostbyname3, etc. too.
    
    The broken out function will look different though, lets see.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

Diff:
---
 sysdeps/posix/getaddrinfo.c | 103 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 84 insertions(+), 19 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 86c81e7e94..c4f48acfd0 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -151,6 +151,32 @@ static const struct addrinfo default_hints =
     .ai_next = NULL
   };
 
+/* Record PTR in the ALLOCSP scratch buffer to be freed later in FUNC_CLEANUP.
+   Increment NALLOCSP by 1 and return true if successful, false otherwise.  */
+
+static bool
+func_cleanup_push (struct scratch_buffer *allocsp, size_t *nallocsp, void *ptr)
+{
+  size_t nallocs = *nallocsp + 1;
+  if (nallocs * sizeof (void *) > allocsp->length
+      && !scratch_buffer_grow_preserve (allocsp))
+    return false;
+
+  ((void **) allocsp->data)[nallocs - 1] = ptr;
+  *nallocsp = nallocs;
+  return true;
+}
+
+/* Free NALLOCS pointers recorded in ALLOCSP.  */
+
+static void
+func_cleanup (struct scratch_buffer *allocsp, size_t nallocs)
+{
+  while (nallocs-- > 0)
+    free (((void **) allocsp->data)[nallocs]);
+
+  scratch_buffer_free (allocsp);
+}
 
 static int
 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
@@ -417,6 +443,7 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
 
 static struct gaih_addrtuple *
 get_nscd_addresses (const char *name, const struct addrinfo *req,
+		    struct scratch_buffer *allocsp, size_t *nallocsp,
 		    bool *got_ipv6, int *rc)
 {
   if (__nss_not_use_nscd_hosts > 0
@@ -501,6 +528,13 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
 
 	  free (air);
 
+	  if (!func_cleanup_push (allocsp, nallocsp, at))
+	    {
+	      free (at);
+	      *rc = -EAI_MEMORY;
+	      return NULL;
+	    }
+
 	  return at;
 	}
       else if (err == 0)
@@ -532,6 +566,7 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
 
 static struct gaih_addrtuple *
 get_numeric_res (const char *name, const struct addrinfo *req,
+		 struct scratch_buffer *allocsp, size_t *nallocsp,
 		 const char **canonp, int *retp)
 {
   uint32_t addr[4] = {0};
@@ -567,6 +602,13 @@ get_numeric_res (const char *name, const struct addrinfo *req,
       if (req->ai_flags & AI_CANONNAME)
 	*canonp = name;
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -618,6 +660,13 @@ get_numeric_res (const char *name, const struct addrinfo *req,
       if (req->ai_flags & AI_CANONNAME)
 	*canonp = name;
 
+      if (!func_cleanup_push (allocsp, nallocsp, at))
+	{
+	  free (at);
+	  *retp = -EAI_MEMORY;
+	  return NULL;
+	}
+
       *retp = 0;
       return at;
     }
@@ -638,6 +687,7 @@ get_numeric_res (const char *name, const struct addrinfo *req,
 
 static struct gaih_addrtuple *
 simple_gethostbyname (const char *name, const struct addrinfo *req,
+		      struct scratch_buffer *allocsp, size_t *nallocsp,
 		      struct scratch_buffer *tmpbuf, int *retp)
 {
   int rc;
@@ -689,6 +739,13 @@ simple_gethostbyname (const char *name, const struct addrinfo *req,
 	*retp = -EAI_NODATA;
     }
 
+  if (!func_cleanup_push (allocsp, nallocsp, at))
+    {
+      free (at);
+      *retp = -EAI_MEMORY;
+      return NULL;
+    }
+
   return at;
 }
 
@@ -718,6 +775,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
   char *canonbuf = NULL;
   int result = 0;
 
+  struct scratch_buffer allocs;
+  size_t nallocs = 0;
+  scratch_buffer_init (&allocs);
+
   if (name != NULL)
     {
       if (req->ai_flags & AI_IDN)
@@ -730,11 +791,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	  malloc_name = true;
 	}
 
-      if ((at = get_numeric_res (name, req, &canon, &result)) != NULL)
-	{
-	  addrmem = at;
-	  goto process_list;
-	}
+      if ((at = get_numeric_res (name, req, &allocs, &nallocs, &canon,
+				 &result)) != NULL)
+	goto process_list;
       else if (result != 0)
 	goto free_and_return;
 
@@ -743,20 +802,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	 IPv6 scope ids, nor retrieving the canonical name.  */
       if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0)
 	{
-	  if ((at = simple_gethostbyname (name, req, tmpbuf, &result)) != NULL)
-	    {
-	      addrmem = at;
-	      goto process_list;
-	    }
+	  if ((at = simple_gethostbyname (name, req, &allocs, &nallocs, tmpbuf,
+					  &result)) != NULL)
+	    goto process_list;
 	  else if (result != 0)
 	    goto free_and_return;
 	}
 
 #ifdef USE_NSCD
-      if ((at = get_nscd_addresses (name, req, &got_ipv6, &result)) != NULL)
+      if ((at = get_nscd_addresses (name, req, &allocs, &nallocs, &got_ipv6,
+				    &result)) != NULL)
 	{
 	  canon = canonbuf = at->name;
-	  addrmem = at;
 	  goto process_list;
 	}
       else if (result != 0)
@@ -782,10 +839,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
       if (res_ctx == NULL)
 	no_more = 1;
 
-      at = __alloca (sizeof (*at));
-      at->next = NULL;
-      at->family = AF_UNSPEC;
-
       while (!no_more)
 	{
 	  no_data = 0;
@@ -798,10 +851,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  if (fct4 != NULL)
 	    {
+	      size_t length = 1024;
+	      char *buf = malloc (length);
+
 	      while (1)
 		{
+		  *pat = NULL;
 		  status = DL_CALL_FCT (fct4, (name, pat,
-					       tmpbuf->data, tmpbuf->length,
+					       buf, length,
 					       &errno, &h_errno,
 					       NULL));
 		  if (status == NSS_STATUS_SUCCESS)
@@ -816,7 +873,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		      break;
 		    }
 
-		  if (!scratch_buffer_grow (tmpbuf))
+		  length *= 2;
+		  free (buf);
+		  if ((buf = malloc (length)) == NULL)
 		    {
 		      __resolv_context_put (res_ctx);
 		      result = -EAI_MEMORY;
@@ -824,6 +883,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		    }
 		}
 
+	      if (!func_cleanup_push (&allocs, &nallocs, buf))
+		{
+		  result = -EAI_MEMORY;
+		  goto free_and_return;
+		}
+
 	      if (status == NSS_STATUS_SUCCESS)
 		{
 		  assert (!no_data);
@@ -1152,7 +1217,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
  free_and_return:
   if (malloc_name)
     free ((char *) name);
-  free (addrmem);
+  func_cleanup (&allocs, nallocs);
   free (canonbuf);
 
   return result;


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

* [glibc/siddhesh/gai-cleanup2] gaih_inet: WIP: Make SUCCESS=merge work with hosts
@ 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=b149cd3cc316fb147801c7f799c37e61451574d5

commit b149cd3cc316fb147801c7f799c37e61451574d5
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Tue Feb 22 19:19:30 2022 +0530

    gaih_inet: WIP: Make SUCCESS=merge work with hosts
    
    It fails in weird ways, which is obvious since subsequent responses will
    write to the same scratch buffer.  Allocate proper memory and start
    accounting using a scratch buffer.  This should be useful for
    gethostbyname3, etc. too.
    
    The broken out function will look different though, lets see.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

Diff:
---
 sysdeps/posix/getaddrinfo.c | 74 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 64 insertions(+), 10 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 86c81e7e94..7c1500048d 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -692,6 +692,33 @@ simple_gethostbyname (const char *name, const struct addrinfo *req,
   return at;
 }
 
+/* Record PTR in the ALLOCSP scratch buffer to be freed later in FUNC_CLEANUP.
+   Increment NALLOCSP by 1 and return true if successful, false otherwise.  */
+
+static bool
+func_cleanup_push (struct scratch_buffer *allocsp, size_t *nallocsp, void *ptr)
+{
+  size_t nallocs = *nallocsp + 1;
+  if (nallocs * sizeof (void *) > allocsp->length
+      && !scratch_buffer_grow_preserve (allocsp))
+    return false;
+
+  ((void **) allocsp->data)[nallocs - 1] = ptr;
+  *nallocsp = nallocs;
+  return true;
+}
+
+/* Free NALLOCS pointers recorded in ALLOCSP.  */
+
+static void
+func_cleanup (struct scratch_buffer *allocsp, size_t nallocs)
+{
+  while (nallocs-- > 0)
+    free (((void **) allocsp->data)[nallocs]);
+
+  scratch_buffer_free (allocsp);
+}
+
 static int
 gaih_inet (const char *name, const struct gaih_service *service,
 	   const struct addrinfo *req, struct addrinfo **pai,
@@ -718,6 +745,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
   char *canonbuf = NULL;
   int result = 0;
 
+  struct scratch_buffer allocs;
+  size_t nallocs = 0;
+  scratch_buffer_init (&allocs);
+
   if (name != NULL)
     {
       if (req->ai_flags & AI_IDN)
@@ -732,7 +763,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
       if ((at = get_numeric_res (name, req, &canon, &result)) != NULL)
 	{
-	  addrmem = at;
+	  if (!func_cleanup_push (&allocs, &nallocs, at))
+	    {
+	      result = -EAI_MEMORY;
+	      goto free_and_return;
+	    }
+
 	  goto process_list;
 	}
       else if (result != 0)
@@ -745,7 +781,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	{
 	  if ((at = simple_gethostbyname (name, req, tmpbuf, &result)) != NULL)
 	    {
-	      addrmem = at;
+	      if (!func_cleanup_push (&allocs, &nallocs, at))
+		{
+		  result = -EAI_MEMORY;
+		  goto free_and_return;
+		}
+
 	      goto process_list;
 	    }
 	  else if (result != 0)
@@ -756,7 +797,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
       if ((at = get_nscd_addresses (name, req, &got_ipv6, &result)) != NULL)
 	{
 	  canon = canonbuf = at->name;
-	  addrmem = at;
+	  if (!func_cleanup_push (&allocs, &nallocs, at))
+	    {
+	      result = -EAI_MEMORY;
+	      goto free_and_return;
+	    }
+
 	  goto process_list;
 	}
       else if (result != 0)
@@ -782,10 +828,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
       if (res_ctx == NULL)
 	no_more = 1;
 
-      at = __alloca (sizeof (*at));
-      at->next = NULL;
-      at->family = AF_UNSPEC;
-
       while (!no_more)
 	{
 	  no_data = 0;
@@ -798,10 +840,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  if (fct4 != NULL)
 	    {
+	      size_t length = 1024;
+	      char *buf = malloc (length);
+
 	      while (1)
 		{
+		  *pat = NULL;
 		  status = DL_CALL_FCT (fct4, (name, pat,
-					       tmpbuf->data, tmpbuf->length,
+					       buf, length,
 					       &errno, &h_errno,
 					       NULL));
 		  if (status == NSS_STATUS_SUCCESS)
@@ -816,7 +862,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		      break;
 		    }
 
-		  if (!scratch_buffer_grow (tmpbuf))
+		  length *= 2;
+		  free (buf);
+		  if ((buf = malloc (length)) == NULL)
 		    {
 		      __resolv_context_put (res_ctx);
 		      result = -EAI_MEMORY;
@@ -824,6 +872,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		    }
 		}
 
+	      if (!func_cleanup_push (&allocs, &nallocs, buf))
+		{
+		  result = -EAI_MEMORY;
+		  goto free_and_return;
+		}
+
 	      if (status == NSS_STATUS_SUCCESS)
 		{
 		  assert (!no_data);
@@ -1152,7 +1206,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
  free_and_return:
   if (malloc_name)
     free ((char *) name);
-  free (addrmem);
+  func_cleanup (&allocs, nallocs);
   free (canonbuf);
 
   return result;


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

end of thread, other threads:[~2022-02-23 10:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-23  9:03 [glibc/siddhesh/gai-cleanup2] gaih_inet: WIP: Make SUCCESS=merge work with hosts Siddhesh Poyarekar
  -- strict thread matches above, loose matches on Subject: below --
2022-02-23 10:07 Siddhesh Poyarekar
2022-02-22 14:56 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).