Update.
* nscd/aicache.c: Prefer using gethostbyname3_r NSS callback to also get ttl and canonical name. Use these two values. * resolv/Versions: Export _nss_dns_gethostbyname3_r from libnss_dns. * resolv/nss_dns/dns-host.c (getanswer_r): Take two new parameters. If nonnull fill with TTL and pointer to canonical name respectively. (_nss_dns_gethostbyaddr_r): Pass NULL in new parameters of getanswer_r. (_nss_dns_gethostbyname2_r): Just wrapper around _nss_dns_gethostbyname3_r. (_nss_dns_gethostbyname3_r): Renamed from _nss_dns_gethostbyname2_r. Take two new parameters which as passed to getanswer_r.
This commit is contained in:
parent
dc4f1624fc
commit
d1fe1f2219
11
ChangeLog
11
ChangeLog
@ -1,5 +1,16 @@
|
||||
2004-09-15 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/aicache.c: Prefer using gethostbyname3_r NSS callback to also
|
||||
get ttl and canonical name. Use these two values.
|
||||
* resolv/Versions: Export _nss_dns_gethostbyname3_r from libnss_dns.
|
||||
* resolv/nss_dns/dns-host.c (getanswer_r): Take two new parameters.
|
||||
If nonnull fill with TTL and pointer to canonical name respectively.
|
||||
(_nss_dns_gethostbyaddr_r): Pass NULL in new parameters of getanswer_r.
|
||||
(_nss_dns_gethostbyname2_r): Just wrapper around
|
||||
_nss_dns_gethostbyname3_r.
|
||||
(_nss_dns_gethostbyname3_r): Renamed from _nss_dns_gethostbyname2_r.
|
||||
Take two new parameters which as passed to getanswer_r.
|
||||
|
||||
* nscd/Makefile (rountines): Add nscd_getai.
|
||||
(nscd-modules): Add aicache.
|
||||
* nscd/aicache.c: New file.
|
||||
|
102
nscd/aicache.c
102
nscd/aicache.c
@ -30,10 +30,10 @@
|
||||
#include <nscd.h>
|
||||
|
||||
|
||||
typedef enum nss_status (*nss_gethostbyname2_r)
|
||||
typedef enum nss_status (*nss_gethostbyname3_r)
|
||||
(const char *name, int af, struct hostent *host,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *h_errnop);
|
||||
int *h_errnop, int32_t *, char **);
|
||||
typedef enum nss_status (*nss_getcanonname_r)
|
||||
(const char *name, char *buffer, size_t buflen, char **result,
|
||||
int *errnop, int *h_errnop);
|
||||
@ -114,19 +114,23 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
size_t tmpbuf4len = 0;
|
||||
char *tmpbuf4 = NULL;
|
||||
char *canon = NULL;
|
||||
int32_t ttl = UINT32_MAX;
|
||||
ssize_t total = 0;
|
||||
char *key_copy = NULL;
|
||||
bool alloca_used = false;
|
||||
|
||||
while (!no_more)
|
||||
{
|
||||
nss_gethostbyname2_r fct = __nss_lookup_function (nip,
|
||||
"gethostbyname2_r");
|
||||
int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
|
||||
|
||||
/* Prefer the function which also returns the TTL and canonical name. */
|
||||
nss_gethostbyname3_r fct = __nss_lookup_function (nip,
|
||||
"gethostbyname3_r");
|
||||
if (fct == NULL)
|
||||
fct = __nss_lookup_function (nip, "gethostbyname2_r");
|
||||
|
||||
if (fct != NULL)
|
||||
{
|
||||
printf("fct=%p\n",fct);
|
||||
struct hostent th[2];
|
||||
|
||||
/* Collect IPv6 information first. */
|
||||
@ -134,7 +138,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
{
|
||||
rc6 = 0;
|
||||
status[0] = DL_CALL_FCT (fct, (key, AF_INET6, &th[0], tmpbuf6,
|
||||
tmpbuf6len, &rc6, &herrno));
|
||||
tmpbuf6len, &rc6, &herrno,
|
||||
&ttl, &canon));
|
||||
if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
|
||||
break;
|
||||
tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
|
||||
@ -161,10 +166,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
{
|
||||
rc4 = 0;
|
||||
status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1], tmpbuf4,
|
||||
tmpbuf4len, &rc4, &herrno));
|
||||
tmpbuf4len, &rc4, &herrno,
|
||||
ttl == UINT32_MAX ? &ttl : NULL,
|
||||
canon == NULL ? &canon : NULL));
|
||||
if (rc4 != ERANGE || herrno != NETDB_INTERNAL)
|
||||
break;
|
||||
tmpbuf4 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
|
||||
tmpbuf4 = extend_alloca (tmpbuf4, tmpbuf4len, 2 * tmpbuf4len);
|
||||
}
|
||||
|
||||
if (rc4 != 0 || herrno == NETDB_INTERNAL)
|
||||
@ -184,26 +191,69 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
addrslen += th[j].h_length;
|
||||
}
|
||||
|
||||
/* Determine the canonical name. */
|
||||
nss_getcanonname_r cfct;
|
||||
cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||
if (cfct != NULL)
|
||||
if (canon == NULL)
|
||||
{
|
||||
const size_t max_fqdn_len = 256;
|
||||
char *buf = alloca (max_fqdn_len);
|
||||
char *s;
|
||||
int rc;
|
||||
/* Determine the canonical name. */
|
||||
nss_getcanonname_r cfct;
|
||||
cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||
if (cfct != NULL)
|
||||
{
|
||||
const size_t max_fqdn_len = 256;
|
||||
char *buf = alloca (max_fqdn_len);
|
||||
char *s;
|
||||
int rc;
|
||||
|
||||
if (DL_CALL_FCT (cfct, (key, buf, max_fqdn_len, &s, &rc,
|
||||
&herrno)) == NSS_STATUS_SUCCESS)
|
||||
canon = s;
|
||||
if (DL_CALL_FCT (cfct, (key, buf, max_fqdn_len, &s, &rc,
|
||||
&herrno)) == NSS_STATUS_SUCCESS)
|
||||
canon = s;
|
||||
else
|
||||
/* Set to name now to avoid using gethostbyaddr. */
|
||||
canon = key;
|
||||
}
|
||||
else
|
||||
/* Set to name now to avoid using gethostbyaddr. */
|
||||
canon = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX use gethostbyaddr
|
||||
{
|
||||
struct hostent *he = NULL;
|
||||
int herrno;
|
||||
struct hostent he_mem;
|
||||
void *addr;
|
||||
size_t addrlen;
|
||||
int addrfamily;
|
||||
|
||||
if (status[1] == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
addr = th[1].h_addr_list[0];
|
||||
addrlen = sizeof (struct in_addr);
|
||||
addrfamily = AF_INET;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = th[0].h_addr_list[0];
|
||||
addrlen = sizeof (struct in6_addr);
|
||||
addrfamily = AF_INET6;
|
||||
}
|
||||
|
||||
size_t tmpbuflen = 512;
|
||||
char *tmpbuf = alloca (tmpbuflen);
|
||||
int rc;
|
||||
while (1)
|
||||
{
|
||||
rc = __gethostbyaddr_r (addr, addrlen, addrfamily,
|
||||
&he_mem, tmpbuf, tmpbuflen,
|
||||
&he, &herrno);
|
||||
if (rc != ERANGE || herrno != NETDB_INTERNAL)
|
||||
break;
|
||||
tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
|
||||
tmpbuflen * 2);
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (he != NULL)
|
||||
canon = he->h_name;
|
||||
else
|
||||
canon = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t canonlen = canon == NULL ? 0 : (strlen (canon) + 1);
|
||||
|
||||
@ -237,7 +287,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
dataset->head.usable = true;
|
||||
|
||||
/* Compute the timeout time. */
|
||||
dataset->head.timeout = time (NULL) + db->postimeout;
|
||||
dataset->head.timeout = time (NULL) + MIN (db->postimeout, ttl);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
|
@ -126,7 +126,7 @@ endif
|
||||
endif
|
||||
|
||||
CFLAGS-regex.c = -Wno-strict-prototypes
|
||||
CFLAGS-getaddrinfo.c = -DRESOLVER -fexceptions
|
||||
CFLAGS-getaddrinfo.c = -DRESOLVER -fexceptions -DUSE_NSCD
|
||||
CFLAGS-pread.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-pread64.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-pwrite.c = -fexceptions -fasynchronous-unwind-tables
|
||||
|
@ -77,7 +77,7 @@ libresolv {
|
||||
GLIBC_PRIVATE {
|
||||
# Needed in libnss_dns.
|
||||
__ns_name_unpack; __ns_name_ntop;
|
||||
__ns_get16;
|
||||
__ns_get16; __ns_get32;
|
||||
__libc_res_nquery; __libc_res_nsearch;
|
||||
}
|
||||
}
|
||||
@ -85,6 +85,7 @@ libresolv {
|
||||
libnss_dns {
|
||||
GLIBC_PRIVATE {
|
||||
_nss_dns_gethostbyaddr_r; _nss_dns_gethostbyname2_r;
|
||||
_nss_dns_gethostbyname3_r;
|
||||
_nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r;
|
||||
_nss_dns_getnetbyname_r; _nss_dns_getcanonname_r;
|
||||
}
|
||||
|
@ -125,12 +125,12 @@ static enum nss_status getanswer_r (const querybuf *answer, int anslen,
|
||||
const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer,
|
||||
size_t buflen, int *errnop, int *h_errnop,
|
||||
int map);
|
||||
int map, int32_t *ttlp, char **canonp);
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
_nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *h_errnop)
|
||||
int *h_errnop, int32_t *ttlp, char **canonp)
|
||||
{
|
||||
union
|
||||
{
|
||||
@ -211,13 +211,23 @@ _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
}
|
||||
|
||||
status = getanswer_r (host_buffer.buf, n, name, type, result, buffer, buflen,
|
||||
errnop, h_errnop, map);
|
||||
errnop, h_errnop, map, ttlp, canonp);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *h_errnop)
|
||||
{
|
||||
return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
|
||||
h_errnop, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname_r (const char *name, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
@ -355,7 +365,7 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
|
||||
|
||||
got_it_already:
|
||||
status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
|
||||
errnop, h_errnop, 0 /* XXX */);
|
||||
errnop, h_errnop, 0 /* XXX */, NULL, NULL);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
@ -439,7 +449,7 @@ addrsort (char **ap, int num)
|
||||
static enum nss_status
|
||||
getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer, size_t buflen,
|
||||
int *errnop, int *h_errnop, int map)
|
||||
int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp)
|
||||
{
|
||||
struct host_data
|
||||
{
|
||||
@ -458,6 +468,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
int (*name_ok) (const char *);
|
||||
u_char packtmp[NS_MAXCDNAME];
|
||||
int have_to_map = 0;
|
||||
int32_t ttl = 0;
|
||||
|
||||
if (__builtin_expect (linebuflen, 0) < 0)
|
||||
{
|
||||
@ -577,7 +588,9 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
type = ns_get16 (cp);
|
||||
cp += INT16SZ; /* type */
|
||||
class = ns_get16 (cp);
|
||||
cp += INT16SZ + INT32SZ; /* class, TTL */
|
||||
cp += INT16SZ; /* class */
|
||||
ttl = ns_get32 (cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
n = ns_get16 (cp);
|
||||
cp += INT16SZ; /* len */
|
||||
if (class != C_IN)
|
||||
@ -749,6 +762,10 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
{
|
||||
register int nn;
|
||||
|
||||
if (ttlp != NULL && ttl != 0)
|
||||
*ttlp = ttl;
|
||||
if (canonp != NULL)
|
||||
*canonp = bp;
|
||||
result->h_name = bp;
|
||||
nn = strlen (bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
|
Loading…
Reference in New Issue
Block a user