|
|
6ca6e8 |
commit d9c979abf9307ef3e27dbe65317430977bb322c7
|
|
|
6ca6e8 |
Author: Florian Weimer <fweimer@redhat.com>
|
|
|
6ca6e8 |
Date: Tue Aug 30 10:02:49 2022 +0200
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
nss_dns: Split getanswer_ptr from getanswer_r
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
And expand the use of name_ok and qtype in getanswer_ptr (the
|
|
|
6ca6e8 |
former also in getanswer_r).
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
After further cleanups, not much code will be shared between the
|
|
|
6ca6e8 |
two functions.
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
|
|
6ca6e8 |
(cherry picked from commit 0dcc43e9981005540bf39dc7bf33fbab62cf9e84)
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
|
|
6ca6e8 |
index 6e83fca1c5b1f98c..a6bf73a091968358 100644
|
|
|
6ca6e8 |
--- a/resolv/nss_dns/dns-host.c
|
|
|
6ca6e8 |
+++ b/resolv/nss_dns/dns-host.c
|
|
|
6ca6e8 |
@@ -117,6 +117,11 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
struct hostent *result, char *buffer,
|
|
|
6ca6e8 |
size_t buflen, int *errnop, int *h_errnop,
|
|
|
6ca6e8 |
int map, int32_t *ttlp, char **canonp);
|
|
|
6ca6e8 |
+static enum nss_status getanswer_ptr (const querybuf *answer, int anslen,
|
|
|
6ca6e8 |
+ const char *qname,
|
|
|
6ca6e8 |
+ struct hostent *result, char *buffer,
|
|
|
6ca6e8 |
+ size_t buflen, int *errnop,
|
|
|
6ca6e8 |
+ int *h_errnop, int32_t *ttlp);
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
|
|
|
6ca6e8 |
const querybuf *answer2, int anslen2,
|
|
|
6ca6e8 |
@@ -562,9 +567,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
|
|
|
6ca6e8 |
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- status = getanswer_r
|
|
|
6ca6e8 |
- (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
|
|
|
6ca6e8 |
- errnop, h_errnop, 0 /* XXX */, ttlp, NULL);
|
|
|
6ca6e8 |
+ status = getanswer_ptr (host_buffer.buf, n, qbuf, result,
|
|
|
6ca6e8 |
+ buffer, buflen, errnop, h_errnop, ttlp);
|
|
|
6ca6e8 |
if (host_buffer.buf != orig_host_buffer)
|
|
|
6ca6e8 |
free (host_buffer.buf);
|
|
|
6ca6e8 |
if (status != NSS_STATUS_SUCCESS)
|
|
|
6ca6e8 |
@@ -660,8 +664,6 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
int haveanswer, had_error;
|
|
|
6ca6e8 |
char *bp, **ap, **hap;
|
|
|
6ca6e8 |
char tbuf[MAXDNAME];
|
|
|
6ca6e8 |
- const char *tname;
|
|
|
6ca6e8 |
- int (*name_ok) (const char *);
|
|
|
6ca6e8 |
u_char packtmp[NS_MAXCDNAME];
|
|
|
6ca6e8 |
int have_to_map = 0;
|
|
|
6ca6e8 |
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
|
|
|
6ca6e8 |
@@ -680,22 +682,8 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
if (buflen - sizeof (struct host_data) != linebuflen)
|
|
|
6ca6e8 |
linebuflen = INT_MAX;
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- tname = qname;
|
|
|
6ca6e8 |
result->h_name = NULL;
|
|
|
6ca6e8 |
end_of_message = answer->buf + anslen;
|
|
|
6ca6e8 |
- switch (qtype)
|
|
|
6ca6e8 |
- {
|
|
|
6ca6e8 |
- case T_A:
|
|
|
6ca6e8 |
- case T_AAAA:
|
|
|
6ca6e8 |
- name_ok = __libc_res_hnok;
|
|
|
6ca6e8 |
- break;
|
|
|
6ca6e8 |
- case T_PTR:
|
|
|
6ca6e8 |
- name_ok = __libc_res_dnok;
|
|
|
6ca6e8 |
- break;
|
|
|
6ca6e8 |
- default:
|
|
|
6ca6e8 |
- *errnop = ENOENT;
|
|
|
6ca6e8 |
- return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */
|
|
|
6ca6e8 |
- }
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
/*
|
|
|
6ca6e8 |
* find first satisfactory answer
|
|
|
6ca6e8 |
@@ -730,7 +718,7 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
*h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
return NSS_STATUS_UNAVAIL;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
- if (__glibc_unlikely (name_ok (bp) == 0))
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (__libc_res_hnok (bp) == 0))
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
errno = EBADMSG;
|
|
|
6ca6e8 |
*errnop = EBADMSG;
|
|
|
6ca6e8 |
@@ -784,7 +772,7 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
n = -1;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0))
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
++had_error;
|
|
|
6ca6e8 |
continue;
|
|
|
6ca6e8 |
@@ -817,7 +805,7 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME)
|
|
|
6ca6e8 |
+ if (type == T_CNAME)
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
/* A CNAME could also have a TTL entry. */
|
|
|
6ca6e8 |
if (ttlp != NULL && ttl < *ttlp)
|
|
|
6ca6e8 |
@@ -827,7 +815,7 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
continue;
|
|
|
6ca6e8 |
n = __libc_dn_expand (answer->buf, end_of_message, cp,
|
|
|
6ca6e8 |
tbuf, sizeof tbuf);
|
|
|
6ca6e8 |
- if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0))
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
++had_error;
|
|
|
6ca6e8 |
continue;
|
|
|
6ca6e8 |
@@ -858,7 +846,260 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
continue;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- if (qtype == T_PTR && type == T_CNAME)
|
|
|
6ca6e8 |
+ if (type == T_A && qtype == T_AAAA && map)
|
|
|
6ca6e8 |
+ have_to_map = 1;
|
|
|
6ca6e8 |
+ else if (__glibc_unlikely (type != qtype))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ switch (type)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ case T_A:
|
|
|
6ca6e8 |
+ case T_AAAA:
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ /* Stop parsing at a record whose length is incorrect. */
|
|
|
6ca6e8 |
+ if (n != rrtype_to_rdata_length (type))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ ++had_error;
|
|
|
6ca6e8 |
+ break;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ /* Skip records of the wrong type. */
|
|
|
6ca6e8 |
+ if (n != result->h_length)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ continue;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ if (!haveanswer)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ int nn;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ /* We compose a single hostent out of the entire chain of
|
|
|
6ca6e8 |
+ entries, so the TTL of the hostent is essentially the lowest
|
|
|
6ca6e8 |
+ TTL in the chain. */
|
|
|
6ca6e8 |
+ if (ttlp != NULL && ttl < *ttlp)
|
|
|
6ca6e8 |
+ *ttlp = ttl;
|
|
|
6ca6e8 |
+ if (canonp != NULL)
|
|
|
6ca6e8 |
+ *canonp = bp;
|
|
|
6ca6e8 |
+ result->h_name = bp;
|
|
|
6ca6e8 |
+ nn = strlen (bp) + 1; /* for the \0 */
|
|
|
6ca6e8 |
+ bp += nn;
|
|
|
6ca6e8 |
+ linebuflen -= nn;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ /* Provide sufficient alignment for both address
|
|
|
6ca6e8 |
+ families. */
|
|
|
6ca6e8 |
+ enum { align = 4 };
|
|
|
6ca6e8 |
+ _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
|
|
|
6ca6e8 |
+ "struct in_addr alignment");
|
|
|
6ca6e8 |
+ _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
|
|
|
6ca6e8 |
+ "struct in6_addr alignment");
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ char *new_bp = PTR_ALIGN_UP (bp, align);
|
|
|
6ca6e8 |
+ linebuflen -= new_bp - bp;
|
|
|
6ca6e8 |
+ bp = new_bp;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (n > linebuflen))
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+ bp = __mempcpy (*hap++ = bp, cp, n);
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ linebuflen -= n;
|
|
|
6ca6e8 |
+ break;
|
|
|
6ca6e8 |
+ default:
|
|
|
6ca6e8 |
+ abort ();
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ if (had_error == 0)
|
|
|
6ca6e8 |
+ ++haveanswer;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (haveanswer > 0)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ *ap = NULL;
|
|
|
6ca6e8 |
+ *hap = NULL;
|
|
|
6ca6e8 |
+ /*
|
|
|
6ca6e8 |
+ * Note: we sort even if host can take only one address
|
|
|
6ca6e8 |
+ * in its return structures - should give it the "best"
|
|
|
6ca6e8 |
+ * address in that case, not some random one
|
|
|
6ca6e8 |
+ */
|
|
|
6ca6e8 |
+ if (haveanswer > 1 && qtype == T_A
|
|
|
6ca6e8 |
+ && __resolv_context_sort_count (ctx) > 0)
|
|
|
6ca6e8 |
+ addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (result->h_name == NULL)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ n = strlen (qname) + 1; /* For the \0. */
|
|
|
6ca6e8 |
+ if (n > linebuflen)
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+ if (n >= MAXHOSTNAMELEN)
|
|
|
6ca6e8 |
+ goto no_recovery;
|
|
|
6ca6e8 |
+ result->h_name = bp;
|
|
|
6ca6e8 |
+ bp = __mempcpy (bp, qname, n); /* Cannot overflow. */
|
|
|
6ca6e8 |
+ linebuflen -= n;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (have_to_map)
|
|
|
6ca6e8 |
+ if (map_v4v6_hostent (result, &bp, &linebuflen))
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+ *h_errnop = NETDB_SUCCESS;
|
|
|
6ca6e8 |
+ return NSS_STATUS_SUCCESS;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ no_recovery:
|
|
|
6ca6e8 |
+ *h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
+ *errnop = ENOENT;
|
|
|
6ca6e8 |
+ /* Special case here: if the resolver sent a result but it only
|
|
|
6ca6e8 |
+ contains a CNAME while we are looking for a T_A or T_AAAA record,
|
|
|
6ca6e8 |
+ we fail with NOTFOUND instead of TRYAGAIN. */
|
|
|
6ca6e8 |
+ return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
|
|
|
6ca6e8 |
+ ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
|
|
|
6ca6e8 |
+}
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+static enum nss_status
|
|
|
6ca6e8 |
+getanswer_ptr (const querybuf *answer, int anslen, const char *qname,
|
|
|
6ca6e8 |
+ struct hostent *result, char *buffer, size_t buflen,
|
|
|
6ca6e8 |
+ int *errnop, int *h_errnop, int32_t *ttlp)
|
|
|
6ca6e8 |
+{
|
|
|
6ca6e8 |
+ struct host_data
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ char *aliases[MAX_NR_ALIASES];
|
|
|
6ca6e8 |
+ unsigned char host_addr[16]; /* IPv4 or IPv6 */
|
|
|
6ca6e8 |
+ char *h_addr_ptrs[0];
|
|
|
6ca6e8 |
+ } *host_data;
|
|
|
6ca6e8 |
+ int linebuflen;
|
|
|
6ca6e8 |
+ const HEADER *hp;
|
|
|
6ca6e8 |
+ const u_char *end_of_message, *cp;
|
|
|
6ca6e8 |
+ int n, ancount, qdcount;
|
|
|
6ca6e8 |
+ int haveanswer, had_error;
|
|
|
6ca6e8 |
+ char *bp, **ap, **hap;
|
|
|
6ca6e8 |
+ char tbuf[MAXDNAME];
|
|
|
6ca6e8 |
+ const char *tname;
|
|
|
6ca6e8 |
+ u_char packtmp[NS_MAXCDNAME];
|
|
|
6ca6e8 |
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
|
|
|
6ca6e8 |
+ buffer += pad;
|
|
|
6ca6e8 |
+ buflen = buflen > pad ? buflen - pad : 0;
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ /* The buffer is too small. */
|
|
|
6ca6e8 |
+ too_small:
|
|
|
6ca6e8 |
+ *errnop = ERANGE;
|
|
|
6ca6e8 |
+ *h_errnop = NETDB_INTERNAL;
|
|
|
6ca6e8 |
+ return NSS_STATUS_TRYAGAIN;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ host_data = (struct host_data *) buffer;
|
|
|
6ca6e8 |
+ linebuflen = buflen - sizeof (struct host_data);
|
|
|
6ca6e8 |
+ if (buflen - sizeof (struct host_data) != linebuflen)
|
|
|
6ca6e8 |
+ linebuflen = INT_MAX;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ tname = qname;
|
|
|
6ca6e8 |
+ result->h_name = NULL;
|
|
|
6ca6e8 |
+ end_of_message = answer->buf + anslen;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ /*
|
|
|
6ca6e8 |
+ * find first satisfactory answer
|
|
|
6ca6e8 |
+ */
|
|
|
6ca6e8 |
+ hp = &answer->hdr;
|
|
|
6ca6e8 |
+ ancount = ntohs (hp->ancount);
|
|
|
6ca6e8 |
+ qdcount = ntohs (hp->qdcount);
|
|
|
6ca6e8 |
+ cp = answer->buf + HFIXEDSZ;
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (qdcount != 1))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ *h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
+ return NSS_STATUS_UNAVAIL;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+ bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
|
|
|
6ca6e8 |
+ linebuflen -= (ancount + 1) * sizeof (char *);
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ n = __ns_name_unpack (answer->buf, end_of_message, cp,
|
|
|
6ca6e8 |
+ packtmp, sizeof packtmp);
|
|
|
6ca6e8 |
+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (errno == EMSGSIZE))
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ n = -1;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (n < 0))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ *errnop = errno;
|
|
|
6ca6e8 |
+ *h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
+ return NSS_STATUS_UNAVAIL;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (__libc_res_dnok (bp) == 0))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ errno = EBADMSG;
|
|
|
6ca6e8 |
+ *errnop = EBADMSG;
|
|
|
6ca6e8 |
+ *h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
+ return NSS_STATUS_UNAVAIL;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ cp += n + QFIXEDSZ;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ ap = host_data->aliases;
|
|
|
6ca6e8 |
+ *ap = NULL;
|
|
|
6ca6e8 |
+ result->h_aliases = host_data->aliases;
|
|
|
6ca6e8 |
+ hap = host_data->h_addr_ptrs;
|
|
|
6ca6e8 |
+ *hap = NULL;
|
|
|
6ca6e8 |
+ result->h_addr_list = host_data->h_addr_ptrs;
|
|
|
6ca6e8 |
+ haveanswer = 0;
|
|
|
6ca6e8 |
+ had_error = 0;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ int type, class;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ n = __ns_name_unpack (answer->buf, end_of_message, cp,
|
|
|
6ca6e8 |
+ packtmp, sizeof packtmp);
|
|
|
6ca6e8 |
+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (errno == EMSGSIZE))
|
|
|
6ca6e8 |
+ goto too_small;
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ n = -1;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ ++had_error;
|
|
|
6ca6e8 |
+ continue;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+ cp += n; /* name */
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (cp + 10 > end_of_message))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ ++had_error;
|
|
|
6ca6e8 |
+ continue;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ NS_GET16 (type, cp);
|
|
|
6ca6e8 |
+ NS_GET16 (class, cp);
|
|
|
6ca6e8 |
+ int32_t ttl;
|
|
|
6ca6e8 |
+ NS_GET32 (ttl, cp);
|
|
|
6ca6e8 |
+ NS_GET16 (n, cp); /* RDATA length. */
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (end_of_message - cp < n)
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ /* RDATA extends beyond the end of the packet. */
|
|
|
6ca6e8 |
+ ++had_error;
|
|
|
6ca6e8 |
+ continue;
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (__glibc_unlikely (class != C_IN))
|
|
|
6ca6e8 |
+ {
|
|
|
6ca6e8 |
+ /* XXX - debug? syslog? */
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
+ }
|
|
|
6ca6e8 |
+
|
|
|
6ca6e8 |
+ if (type == T_CNAME)
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
/* A CNAME could also have a TTL entry. */
|
|
|
6ca6e8 |
if (ttlp != NULL && ttl < *ttlp)
|
|
|
6ca6e8 |
@@ -887,14 +1128,6 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
continue;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- if (type == T_A && qtype == T_AAAA && map)
|
|
|
6ca6e8 |
- have_to_map = 1;
|
|
|
6ca6e8 |
- else if (__glibc_unlikely (type != qtype))
|
|
|
6ca6e8 |
- {
|
|
|
6ca6e8 |
- cp += n;
|
|
|
6ca6e8 |
- continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
- }
|
|
|
6ca6e8 |
-
|
|
|
6ca6e8 |
switch (type)
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
case T_PTR:
|
|
|
6ca6e8 |
@@ -956,8 +1189,6 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
TTL in the chain. */
|
|
|
6ca6e8 |
if (ttlp != NULL && ttl < *ttlp)
|
|
|
6ca6e8 |
*ttlp = ttl;
|
|
|
6ca6e8 |
- if (canonp != NULL)
|
|
|
6ca6e8 |
- *canonp = bp;
|
|
|
6ca6e8 |
result->h_name = bp;
|
|
|
6ca6e8 |
nn = strlen (bp) + 1; /* for the \0 */
|
|
|
6ca6e8 |
bp += nn;
|
|
|
6ca6e8 |
@@ -984,7 +1215,8 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
linebuflen -= n;
|
|
|
6ca6e8 |
break;
|
|
|
6ca6e8 |
default:
|
|
|
6ca6e8 |
- abort ();
|
|
|
6ca6e8 |
+ cp += n;
|
|
|
6ca6e8 |
+ continue; /* XXX - had_error++ ? */
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
if (had_error == 0)
|
|
|
6ca6e8 |
++haveanswer;
|
|
|
6ca6e8 |
@@ -994,14 +1226,6 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
*ap = NULL;
|
|
|
6ca6e8 |
*hap = NULL;
|
|
|
6ca6e8 |
- /*
|
|
|
6ca6e8 |
- * Note: we sort even if host can take only one address
|
|
|
6ca6e8 |
- * in its return structures - should give it the "best"
|
|
|
6ca6e8 |
- * address in that case, not some random one
|
|
|
6ca6e8 |
- */
|
|
|
6ca6e8 |
- if (haveanswer > 1 && qtype == T_A
|
|
|
6ca6e8 |
- && __resolv_context_sort_count (ctx) > 0)
|
|
|
6ca6e8 |
- addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
if (result->h_name == NULL)
|
|
|
6ca6e8 |
{
|
|
|
6ca6e8 |
@@ -1015,23 +1239,15 @@ getanswer_r (struct resolv_context *ctx,
|
|
|
6ca6e8 |
linebuflen -= n;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
- if (have_to_map)
|
|
|
6ca6e8 |
- if (map_v4v6_hostent (result, &bp, &linebuflen))
|
|
|
6ca6e8 |
- goto too_small;
|
|
|
6ca6e8 |
*h_errnop = NETDB_SUCCESS;
|
|
|
6ca6e8 |
return NSS_STATUS_SUCCESS;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
no_recovery:
|
|
|
6ca6e8 |
*h_errnop = NO_RECOVERY;
|
|
|
6ca6e8 |
*errnop = ENOENT;
|
|
|
6ca6e8 |
- /* Special case here: if the resolver sent a result but it only
|
|
|
6ca6e8 |
- contains a CNAME while we are looking for a T_A or T_AAAA record,
|
|
|
6ca6e8 |
- we fail with NOTFOUND instead of TRYAGAIN. */
|
|
|
6ca6e8 |
- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
|
|
|
6ca6e8 |
- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
|
|
|
6ca6e8 |
+ return NSS_STATUS_TRYAGAIN;
|
|
|
6ca6e8 |
}
|
|
|
6ca6e8 |
|
|
|
6ca6e8 |
-
|
|
|
6ca6e8 |
static enum nss_status
|
|
|
6ca6e8 |
gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
|
|
|
6ca6e8 |
struct gaih_addrtuple ***patp,
|