[PATCH] resolv: Add test for getaddrinfo returning EAI_AGAIN on DNS failure

Sergey Kolosov skolosov@redhat.com
Tue Sep 16 19:42:31 GMT 2025


Test for BZ #16849. This test verifies that getaddrinfo correctly
returns the EAI_AGAIN error code when DNS queries fail due to a network
failure. The test queries with AF_INET, AF_INET6, AF_UNSPEC address
families and expects getaddrinfo to return EAI_AGAIN in each case.
---
To validate the test, I manually reverted the fix for BZ #16849 in
nss/getaddrinfo.c, specifically the condition:

  -  if (h_errno == TRY_AGAIN)
  +  if (status == NSS_STATUS_TRYAGAIN && h_errno == TRY_AGAIN)

With this reversion in place, the test fails as expected (getaddrinfo
returns EAI_NONAME instead of EAI_AGAIN), confirming that the test
detects the broken behavior.

With the fix present, the test passes.
---
 resolv/Makefile                    |  2 +
 resolv/tst-getaddrinfo-eai-again.c | 71 ++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 resolv/tst-getaddrinfo-eai-again.c

diff --git a/resolv/Makefile b/resolv/Makefile
index 8fa3398d76..4d6f0ebe82 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -136,6 +136,7 @@ tests-static += tst-ns_rr_cursor
 # These tests need libdl.
 ifeq (yes,$(build-shared))
 tests += \
+  tst-getaddrinfo-eai-again \
   tst-resolv-ai_idn \
   tst-resolv-ai_idn-latin1 \
   tst-resolv-ai_idn-nolibidn2 \
@@ -280,6 +281,7 @@ $(objpfx)mtrace-tst-resolv-res_ninit.out: $(objpfx)tst-resolv-res_ninit.out
 
 $(objpfx)tst-bug18665-tcp: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-bug18665: $(objpfx)libresolv.so $(shared-thread-library)
+$(objpfx)tst-getaddrinfo-eai-again: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-resolv-ai_idn: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-resolv-ai_idn-latin1: \
   $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/tst-getaddrinfo-eai-again.c b/resolv/tst-getaddrinfo-eai-again.c
new file mode 100644
index 0000000000..0c2d8deb96
--- /dev/null
+++ b/resolv/tst-getaddrinfo-eai-again.c
@@ -0,0 +1,71 @@
+/* Test for BZ #16849. Verify that getaddrinfo correctly returns
+   EAI_AGAIN error code if DNS query fails due to a network failure.
+   Copyright (C) 2025 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <resolv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+
+/* DNS stub callback that simulates a network failure.  */
+static void
+response (const struct resolv_response_context *ctx,
+          struct resolv_response_builder *b,
+          const char *qname, uint16_t qclass, uint16_t qtype)
+{
+}
+
+static void
+query_host (const char *host_name)
+{
+  int family[] = { AF_INET, AF_INET6, AF_UNSPEC };
+  const char *family_names[] = { "AF_INET", "AF_INET6", "AF_UNSPEC" };
+
+  for (int i = 0; i < 3; i++)
+    {
+      struct addrinfo hints = {
+        .ai_socktype = 0,
+        .ai_protocol = 0,
+        .ai_family = family[i],
+        .ai_flags = 0,
+      };
+      struct addrinfo *result;
+      int res = getaddrinfo (host_name, NULL, &hints, &result);
+      if (res != EAI_AGAIN)
+        FAIL_EXIT1 ("getaddrinfo (%s, %s): %s\n should return EAI_AGAIN \n",
+                    host_name, family_names[i], gai_strerror (res));
+    }
+}
+
+static int
+do_test (void)
+{
+  struct resolv_test *aux = resolv_test_start
+    ((struct resolv_redirect_config)
+     {
+       .response_callback = response,
+     });
+  query_host("site.example");
+  resolv_test_end (aux);
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.51.0



More information about the Libc-alpha mailing list