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