about summary refs log tree commit diff
path: root/resolv/nss_dns
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-06-24 18:16:41 +0200
committerFlorian Weimer <fweimer@redhat.com>2022-06-24 18:18:44 +0200
commitf282cdbe7f436c75864e5640a409a10485e9abb2 (patch)
tree82983c97f959dd19508b1ef3c89f2aa1b8e8db30 /resolv/nss_dns
parent62a321b12d0e397af88fa422db65079332f971dc (diff)
downloadglibc-f282cdbe7f436c75864e5640a409a10485e9abb2.tar.gz
glibc-f282cdbe7f436c75864e5640a409a10485e9abb2.tar.xz
glibc-f282cdbe7f436c75864e5640a409a10485e9abb2.zip
resolv: Implement no-aaaa stub resolver option
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'resolv/nss_dns')
-rw-r--r--resolv/nss_dns/dns-host.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 913a5cb82f..544cffbecd 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -124,6 +124,14 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
 				       char *buffer, size_t buflen,
 				       int *errnop, int *h_errnop,
 				       int32_t *ttlp);
+static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
+					      int anslen1,
+					      const char *qname,
+					      struct gaih_addrtuple **pat,
+					      char *buffer, size_t buflen,
+					      int *errnop, int *h_errnop,
+					      int32_t *ttlp);
+
 
 static enum nss_status gethostbyname3_context (struct resolv_context *ctx,
 					       const char *name, int af,
@@ -369,18 +377,32 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   int resplen2 = 0;
   int ans2p_malloced = 0;
 
+
   int olderr = errno;
-  int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
+  int n;
+
+  if ((ctx->resp->options & RES_NOAAAA) == 0)
+    {
+      n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
 				host_buffer.buf->buf, 2048, &host_buffer.ptr,
 				&ans2p, &nans2p, &resplen2, &ans2p_malloced);
-  if (n >= 0)
-    {
-      status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
-			       resplen2, name, pat, buffer, buflen,
-			       errnop, herrnop, ttlp);
+      if (n >= 0)
+	status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+				 resplen2, name, pat, buffer, buflen,
+				 errnop, herrnop, ttlp);
     }
   else
     {
+      n = __res_context_search (ctx, name, C_IN, T_A,
+				host_buffer.buf->buf, 2048, NULL,
+				NULL, NULL, NULL, NULL);
+      if (n >= 0)
+	status = gaih_getanswer_noaaaa (host_buffer.buf, n,
+					name, pat, buffer, buflen,
+					errnop, herrnop, ttlp);
+    }
+  if (n < 0)
+    {
       switch (errno)
 	{
 	case ESRCH:
@@ -1387,3 +1409,21 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
 
   return status;
 }
+
+/* Variant of gaih_getanswer without a second (AAAA) response.  */
+static enum nss_status
+gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
+		       struct gaih_addrtuple **pat,
+		       char *buffer, size_t buflen,
+		       int *errnop, int *h_errnop, int32_t *ttlp)
+{
+  int first = 1;
+
+  enum nss_status status = NSS_STATUS_NOTFOUND;
+  if (anslen1 > 0)
+    status = gaih_getanswer_slice (answer1, anslen1, qname,
+				   &pat, &buffer, &buflen,
+				   errnop, h_errnop, ttlp,
+				   &first);
+  return status;
+}