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