980 lines
25 KiB
Diff
980 lines
25 KiB
Diff
|
commit 228cdb00a045ae3b68a91b35c7548bab6029446e
|
||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||
|
Date: Thu Mar 17 11:44:34 2022 +0530
|
||
|
|
||
|
Simplify allocations and fix merge and continue actions [BZ #28931]
|
||
|
|
||
|
Allocations for address tuples is currently a bit confusing because of
|
||
|
the pointer chasing through PAT, making it hard to observe the sequence
|
||
|
in which allocations have been made. Narrow scope of the pointer
|
||
|
chasing through PAT so that it is only used where necessary.
|
||
|
|
||
|
This also tightens actions behaviour with the hosts database in
|
||
|
getaddrinfo to comply with the manual text. The "continue" action
|
||
|
discards previous results and the "merge" action results in an immedate
|
||
|
lookup failure. Consequently, chaining of allocations across modules is
|
||
|
no longer necessary, thus opening up cleanup opportunities.
|
||
|
|
||
|
A test has been added that checks some combinations to ensure that they
|
||
|
work correctly.
|
||
|
|
||
|
Resolves: BZ #28931
|
||
|
|
||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||
|
(cherry picked from commit 1c37b8022e8763fedbb3f79c02e05c6acfe5a215)
|
||
|
|
||
|
Conflicts:
|
||
|
nss/Makefile
|
||
|
(Missing test cases)
|
||
|
sysdeps/posix/getaddrinfo.c
|
||
|
(RES_USE_INET6 still present in RHEL-8 and NSS module traversal rewrite
|
||
|
not in RHEL-8)
|
||
|
|
||
|
diff --git a/nss/Makefile b/nss/Makefile
|
||
|
index e8a7d9c7b3cefcdf..cfb255c6e7a3a4de 100644
|
||
|
--- a/nss/Makefile
|
||
|
+++ b/nss/Makefile
|
||
|
@@ -65,7 +65,8 @@ xtests = bug-erange
|
||
|
|
||
|
tests-container = \
|
||
|
tst-nss-db-endpwent \
|
||
|
- tst-nss-db-endgrent
|
||
|
+ tst-nss-db-endgrent \
|
||
|
+ tst-nss-gai-actions
|
||
|
|
||
|
# Tests which need libdl
|
||
|
ifeq (yes,$(build-shared))
|
||
|
diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
|
||
|
new file mode 100644
|
||
|
index 0000000000000000..efca6cd1837a172a
|
||
|
--- /dev/null
|
||
|
+++ b/nss/tst-nss-gai-actions.c
|
||
|
@@ -0,0 +1,149 @@
|
||
|
+/* Test continue and merge NSS actions for getaddrinfo.
|
||
|
+ Copyright The GNU Toolchain Authors.
|
||
|
+ 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 <dlfcn.h>
|
||
|
+#include <gnu/lib-names.h>
|
||
|
+#include <nss.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <stdlib.h>
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+#include <support/check.h>
|
||
|
+#include <support/format_nss.h>
|
||
|
+#include <support/support.h>
|
||
|
+#include <support/xstdio.h>
|
||
|
+#include <support/xunistd.h>
|
||
|
+
|
||
|
+enum
|
||
|
+{
|
||
|
+ ACTION_MERGE = 0,
|
||
|
+ ACTION_CONTINUE,
|
||
|
+};
|
||
|
+
|
||
|
+static const char *
|
||
|
+family_str (int family)
|
||
|
+{
|
||
|
+ switch (family)
|
||
|
+ {
|
||
|
+ case AF_UNSPEC:
|
||
|
+ return "AF_UNSPEC";
|
||
|
+ case AF_INET:
|
||
|
+ return "AF_INET";
|
||
|
+ default:
|
||
|
+ __builtin_unreachable ();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static const char *
|
||
|
+action_str (int action)
|
||
|
+{
|
||
|
+ switch (action)
|
||
|
+ {
|
||
|
+ case ACTION_MERGE:
|
||
|
+ return "merge";
|
||
|
+ case ACTION_CONTINUE:
|
||
|
+ return "continue";
|
||
|
+ default:
|
||
|
+ __builtin_unreachable ();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+do_one_test (int action, int family, bool canon)
|
||
|
+{
|
||
|
+ struct addrinfo hints =
|
||
|
+ {
|
||
|
+ .ai_family = family,
|
||
|
+ };
|
||
|
+
|
||
|
+ struct addrinfo *ai;
|
||
|
+
|
||
|
+ if (canon)
|
||
|
+ hints.ai_flags = AI_CANONNAME;
|
||
|
+
|
||
|
+ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
|
||
|
+ action_str (action), family_str (family),
|
||
|
+ canon ? "AI_CANONNAME" : "");
|
||
|
+
|
||
|
+ int ret = getaddrinfo ("example.org", "80", &hints, &ai);
|
||
|
+
|
||
|
+ switch (action)
|
||
|
+ {
|
||
|
+ case ACTION_MERGE:
|
||
|
+ if (ret == 0)
|
||
|
+ {
|
||
|
+ char *formatted = support_format_addrinfo (ai, ret);
|
||
|
+
|
||
|
+ printf ("merge unexpectedly succeeded:\n %s\n", formatted);
|
||
|
+ support_record_failure ();
|
||
|
+ free (formatted);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ return;
|
||
|
+ case ACTION_CONTINUE:
|
||
|
+ {
|
||
|
+ char *formatted = support_format_addrinfo (ai, ret);
|
||
|
+
|
||
|
+ /* Verify that the result appears exactly once. */
|
||
|
+ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
|
||
|
+ "address: DGRAM/UDP 192.0.0.1 80\n"
|
||
|
+ "address: RAW/IP 192.0.0.1 80\n";
|
||
|
+
|
||
|
+ const char *contains = strstr (formatted, expected);
|
||
|
+ const char *contains2 = NULL;
|
||
|
+
|
||
|
+ if (contains != NULL)
|
||
|
+ contains2 = strstr (contains + strlen (expected), expected);
|
||
|
+
|
||
|
+ if (contains == NULL || contains2 != NULL)
|
||
|
+ {
|
||
|
+ printf ("continue failed:\n%s\n", formatted);
|
||
|
+ support_record_failure ();
|
||
|
+ }
|
||
|
+
|
||
|
+ free (formatted);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ default:
|
||
|
+ __builtin_unreachable ();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+do_one_test_set (int action)
|
||
|
+{
|
||
|
+ char buf[32];
|
||
|
+
|
||
|
+ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
|
||
|
+ action_str (action));
|
||
|
+ __nss_configure_lookup ("hosts", buf);
|
||
|
+
|
||
|
+ do_one_test (action, AF_UNSPEC, false);
|
||
|
+ do_one_test (action, AF_INET, false);
|
||
|
+ do_one_test (action, AF_INET, true);
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+do_test (void)
|
||
|
+{
|
||
|
+ do_one_test_set (ACTION_CONTINUE);
|
||
|
+ do_one_test_set (ACTION_MERGE);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+#include <support/test-driver.c>
|
||
|
diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||
|
new file mode 100644
|
||
|
index 0000000000000000..d1a59f73a90f2993
|
||
|
--- /dev/null
|
||
|
+++ b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||
|
@@ -0,0 +1 @@
|
||
|
+multi on
|
||
|
diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts
|
||
|
new file mode 100644
|
||
|
index 0000000000000000..50ce9774dc2c21d9
|
||
|
--- /dev/null
|
||
|
+++ b/nss/tst-nss-gai-actions.root/etc/hosts
|
||
|
@@ -0,0 +1,508 @@
|
||
|
+192.0.0.1 example.org
|
||
|
+192.0.0.2 example.org
|
||
|
+192.0.0.3 example.org
|
||
|
+192.0.0.4 example.org
|
||
|
+192.0.0.5 example.org
|
||
|
+192.0.0.6 example.org
|
||
|
+192.0.0.7 example.org
|
||
|
+192.0.0.8 example.org
|
||
|
+192.0.0.9 example.org
|
||
|
+192.0.0.10 example.org
|
||
|
+192.0.0.11 example.org
|
||
|
+192.0.0.12 example.org
|
||
|
+192.0.0.13 example.org
|
||
|
+192.0.0.14 example.org
|
||
|
+192.0.0.15 example.org
|
||
|
+192.0.0.16 example.org
|
||
|
+192.0.0.17 example.org
|
||
|
+192.0.0.18 example.org
|
||
|
+192.0.0.19 example.org
|
||
|
+192.0.0.20 example.org
|
||
|
+192.0.0.21 example.org
|
||
|
+192.0.0.22 example.org
|
||
|
+192.0.0.23 example.org
|
||
|
+192.0.0.24 example.org
|
||
|
+192.0.0.25 example.org
|
||
|
+192.0.0.26 example.org
|
||
|
+192.0.0.27 example.org
|
||
|
+192.0.0.28 example.org
|
||
|
+192.0.0.29 example.org
|
||
|
+192.0.0.30 example.org
|
||
|
+192.0.0.31 example.org
|
||
|
+192.0.0.32 example.org
|
||
|
+192.0.0.33 example.org
|
||
|
+192.0.0.34 example.org
|
||
|
+192.0.0.35 example.org
|
||
|
+192.0.0.36 example.org
|
||
|
+192.0.0.37 example.org
|
||
|
+192.0.0.38 example.org
|
||
|
+192.0.0.39 example.org
|
||
|
+192.0.0.40 example.org
|
||
|
+192.0.0.41 example.org
|
||
|
+192.0.0.42 example.org
|
||
|
+192.0.0.43 example.org
|
||
|
+192.0.0.44 example.org
|
||
|
+192.0.0.45 example.org
|
||
|
+192.0.0.46 example.org
|
||
|
+192.0.0.47 example.org
|
||
|
+192.0.0.48 example.org
|
||
|
+192.0.0.49 example.org
|
||
|
+192.0.0.50 example.org
|
||
|
+192.0.0.51 example.org
|
||
|
+192.0.0.52 example.org
|
||
|
+192.0.0.53 example.org
|
||
|
+192.0.0.54 example.org
|
||
|
+192.0.0.55 example.org
|
||
|
+192.0.0.56 example.org
|
||
|
+192.0.0.57 example.org
|
||
|
+192.0.0.58 example.org
|
||
|
+192.0.0.59 example.org
|
||
|
+192.0.0.60 example.org
|
||
|
+192.0.0.61 example.org
|
||
|
+192.0.0.62 example.org
|
||
|
+192.0.0.63 example.org
|
||
|
+192.0.0.64 example.org
|
||
|
+192.0.0.65 example.org
|
||
|
+192.0.0.66 example.org
|
||
|
+192.0.0.67 example.org
|
||
|
+192.0.0.68 example.org
|
||
|
+192.0.0.69 example.org
|
||
|
+192.0.0.70 example.org
|
||
|
+192.0.0.71 example.org
|
||
|
+192.0.0.72 example.org
|
||
|
+192.0.0.73 example.org
|
||
|
+192.0.0.74 example.org
|
||
|
+192.0.0.75 example.org
|
||
|
+192.0.0.76 example.org
|
||
|
+192.0.0.77 example.org
|
||
|
+192.0.0.78 example.org
|
||
|
+192.0.0.79 example.org
|
||
|
+192.0.0.80 example.org
|
||
|
+192.0.0.81 example.org
|
||
|
+192.0.0.82 example.org
|
||
|
+192.0.0.83 example.org
|
||
|
+192.0.0.84 example.org
|
||
|
+192.0.0.85 example.org
|
||
|
+192.0.0.86 example.org
|
||
|
+192.0.0.87 example.org
|
||
|
+192.0.0.88 example.org
|
||
|
+192.0.0.89 example.org
|
||
|
+192.0.0.90 example.org
|
||
|
+192.0.0.91 example.org
|
||
|
+192.0.0.92 example.org
|
||
|
+192.0.0.93 example.org
|
||
|
+192.0.0.94 example.org
|
||
|
+192.0.0.95 example.org
|
||
|
+192.0.0.96 example.org
|
||
|
+192.0.0.97 example.org
|
||
|
+192.0.0.98 example.org
|
||
|
+192.0.0.99 example.org
|
||
|
+192.0.0.100 example.org
|
||
|
+192.0.0.101 example.org
|
||
|
+192.0.0.102 example.org
|
||
|
+192.0.0.103 example.org
|
||
|
+192.0.0.104 example.org
|
||
|
+192.0.0.105 example.org
|
||
|
+192.0.0.106 example.org
|
||
|
+192.0.0.107 example.org
|
||
|
+192.0.0.108 example.org
|
||
|
+192.0.0.109 example.org
|
||
|
+192.0.0.110 example.org
|
||
|
+192.0.0.111 example.org
|
||
|
+192.0.0.112 example.org
|
||
|
+192.0.0.113 example.org
|
||
|
+192.0.0.114 example.org
|
||
|
+192.0.0.115 example.org
|
||
|
+192.0.0.116 example.org
|
||
|
+192.0.0.117 example.org
|
||
|
+192.0.0.118 example.org
|
||
|
+192.0.0.119 example.org
|
||
|
+192.0.0.120 example.org
|
||
|
+192.0.0.121 example.org
|
||
|
+192.0.0.122 example.org
|
||
|
+192.0.0.123 example.org
|
||
|
+192.0.0.124 example.org
|
||
|
+192.0.0.125 example.org
|
||
|
+192.0.0.126 example.org
|
||
|
+192.0.0.127 example.org
|
||
|
+192.0.0.128 example.org
|
||
|
+192.0.0.129 example.org
|
||
|
+192.0.0.130 example.org
|
||
|
+192.0.0.131 example.org
|
||
|
+192.0.0.132 example.org
|
||
|
+192.0.0.133 example.org
|
||
|
+192.0.0.134 example.org
|
||
|
+192.0.0.135 example.org
|
||
|
+192.0.0.136 example.org
|
||
|
+192.0.0.137 example.org
|
||
|
+192.0.0.138 example.org
|
||
|
+192.0.0.139 example.org
|
||
|
+192.0.0.140 example.org
|
||
|
+192.0.0.141 example.org
|
||
|
+192.0.0.142 example.org
|
||
|
+192.0.0.143 example.org
|
||
|
+192.0.0.144 example.org
|
||
|
+192.0.0.145 example.org
|
||
|
+192.0.0.146 example.org
|
||
|
+192.0.0.147 example.org
|
||
|
+192.0.0.148 example.org
|
||
|
+192.0.0.149 example.org
|
||
|
+192.0.0.150 example.org
|
||
|
+192.0.0.151 example.org
|
||
|
+192.0.0.152 example.org
|
||
|
+192.0.0.153 example.org
|
||
|
+192.0.0.154 example.org
|
||
|
+192.0.0.155 example.org
|
||
|
+192.0.0.156 example.org
|
||
|
+192.0.0.157 example.org
|
||
|
+192.0.0.158 example.org
|
||
|
+192.0.0.159 example.org
|
||
|
+192.0.0.160 example.org
|
||
|
+192.0.0.161 example.org
|
||
|
+192.0.0.162 example.org
|
||
|
+192.0.0.163 example.org
|
||
|
+192.0.0.164 example.org
|
||
|
+192.0.0.165 example.org
|
||
|
+192.0.0.166 example.org
|
||
|
+192.0.0.167 example.org
|
||
|
+192.0.0.168 example.org
|
||
|
+192.0.0.169 example.org
|
||
|
+192.0.0.170 example.org
|
||
|
+192.0.0.171 example.org
|
||
|
+192.0.0.172 example.org
|
||
|
+192.0.0.173 example.org
|
||
|
+192.0.0.174 example.org
|
||
|
+192.0.0.175 example.org
|
||
|
+192.0.0.176 example.org
|
||
|
+192.0.0.177 example.org
|
||
|
+192.0.0.178 example.org
|
||
|
+192.0.0.179 example.org
|
||
|
+192.0.0.180 example.org
|
||
|
+192.0.0.181 example.org
|
||
|
+192.0.0.182 example.org
|
||
|
+192.0.0.183 example.org
|
||
|
+192.0.0.184 example.org
|
||
|
+192.0.0.185 example.org
|
||
|
+192.0.0.186 example.org
|
||
|
+192.0.0.187 example.org
|
||
|
+192.0.0.188 example.org
|
||
|
+192.0.0.189 example.org
|
||
|
+192.0.0.190 example.org
|
||
|
+192.0.0.191 example.org
|
||
|
+192.0.0.192 example.org
|
||
|
+192.0.0.193 example.org
|
||
|
+192.0.0.194 example.org
|
||
|
+192.0.0.195 example.org
|
||
|
+192.0.0.196 example.org
|
||
|
+192.0.0.197 example.org
|
||
|
+192.0.0.198 example.org
|
||
|
+192.0.0.199 example.org
|
||
|
+192.0.0.200 example.org
|
||
|
+192.0.0.201 example.org
|
||
|
+192.0.0.202 example.org
|
||
|
+192.0.0.203 example.org
|
||
|
+192.0.0.204 example.org
|
||
|
+192.0.0.205 example.org
|
||
|
+192.0.0.206 example.org
|
||
|
+192.0.0.207 example.org
|
||
|
+192.0.0.208 example.org
|
||
|
+192.0.0.209 example.org
|
||
|
+192.0.0.210 example.org
|
||
|
+192.0.0.211 example.org
|
||
|
+192.0.0.212 example.org
|
||
|
+192.0.0.213 example.org
|
||
|
+192.0.0.214 example.org
|
||
|
+192.0.0.215 example.org
|
||
|
+192.0.0.216 example.org
|
||
|
+192.0.0.217 example.org
|
||
|
+192.0.0.218 example.org
|
||
|
+192.0.0.219 example.org
|
||
|
+192.0.0.220 example.org
|
||
|
+192.0.0.221 example.org
|
||
|
+192.0.0.222 example.org
|
||
|
+192.0.0.223 example.org
|
||
|
+192.0.0.224 example.org
|
||
|
+192.0.0.225 example.org
|
||
|
+192.0.0.226 example.org
|
||
|
+192.0.0.227 example.org
|
||
|
+192.0.0.228 example.org
|
||
|
+192.0.0.229 example.org
|
||
|
+192.0.0.230 example.org
|
||
|
+192.0.0.231 example.org
|
||
|
+192.0.0.232 example.org
|
||
|
+192.0.0.233 example.org
|
||
|
+192.0.0.234 example.org
|
||
|
+192.0.0.235 example.org
|
||
|
+192.0.0.236 example.org
|
||
|
+192.0.0.237 example.org
|
||
|
+192.0.0.238 example.org
|
||
|
+192.0.0.239 example.org
|
||
|
+192.0.0.240 example.org
|
||
|
+192.0.0.241 example.org
|
||
|
+192.0.0.242 example.org
|
||
|
+192.0.0.243 example.org
|
||
|
+192.0.0.244 example.org
|
||
|
+192.0.0.245 example.org
|
||
|
+192.0.0.246 example.org
|
||
|
+192.0.0.247 example.org
|
||
|
+192.0.0.248 example.org
|
||
|
+192.0.0.249 example.org
|
||
|
+192.0.0.250 example.org
|
||
|
+192.0.0.251 example.org
|
||
|
+192.0.0.252 example.org
|
||
|
+192.0.0.253 example.org
|
||
|
+192.0.0.254 example.org
|
||
|
+192.0.1.1 example.org
|
||
|
+192.0.1.2 example.org
|
||
|
+192.0.1.3 example.org
|
||
|
+192.0.1.4 example.org
|
||
|
+192.0.1.5 example.org
|
||
|
+192.0.1.6 example.org
|
||
|
+192.0.1.7 example.org
|
||
|
+192.0.1.8 example.org
|
||
|
+192.0.1.9 example.org
|
||
|
+192.0.1.10 example.org
|
||
|
+192.0.1.11 example.org
|
||
|
+192.0.1.12 example.org
|
||
|
+192.0.1.13 example.org
|
||
|
+192.0.1.14 example.org
|
||
|
+192.0.1.15 example.org
|
||
|
+192.0.1.16 example.org
|
||
|
+192.0.1.17 example.org
|
||
|
+192.0.1.18 example.org
|
||
|
+192.0.1.19 example.org
|
||
|
+192.0.1.20 example.org
|
||
|
+192.0.1.21 example.org
|
||
|
+192.0.1.22 example.org
|
||
|
+192.0.1.23 example.org
|
||
|
+192.0.1.24 example.org
|
||
|
+192.0.1.25 example.org
|
||
|
+192.0.1.26 example.org
|
||
|
+192.0.1.27 example.org
|
||
|
+192.0.1.28 example.org
|
||
|
+192.0.1.29 example.org
|
||
|
+192.0.1.30 example.org
|
||
|
+192.0.1.31 example.org
|
||
|
+192.0.1.32 example.org
|
||
|
+192.0.1.33 example.org
|
||
|
+192.0.1.34 example.org
|
||
|
+192.0.1.35 example.org
|
||
|
+192.0.1.36 example.org
|
||
|
+192.0.1.37 example.org
|
||
|
+192.0.1.38 example.org
|
||
|
+192.0.1.39 example.org
|
||
|
+192.0.1.40 example.org
|
||
|
+192.0.1.41 example.org
|
||
|
+192.0.1.42 example.org
|
||
|
+192.0.1.43 example.org
|
||
|
+192.0.1.44 example.org
|
||
|
+192.0.1.45 example.org
|
||
|
+192.0.1.46 example.org
|
||
|
+192.0.1.47 example.org
|
||
|
+192.0.1.48 example.org
|
||
|
+192.0.1.49 example.org
|
||
|
+192.0.1.50 example.org
|
||
|
+192.0.1.51 example.org
|
||
|
+192.0.1.52 example.org
|
||
|
+192.0.1.53 example.org
|
||
|
+192.0.1.54 example.org
|
||
|
+192.0.1.55 example.org
|
||
|
+192.0.1.56 example.org
|
||
|
+192.0.1.57 example.org
|
||
|
+192.0.1.58 example.org
|
||
|
+192.0.1.59 example.org
|
||
|
+192.0.1.60 example.org
|
||
|
+192.0.1.61 example.org
|
||
|
+192.0.1.62 example.org
|
||
|
+192.0.1.63 example.org
|
||
|
+192.0.1.64 example.org
|
||
|
+192.0.1.65 example.org
|
||
|
+192.0.1.66 example.org
|
||
|
+192.0.1.67 example.org
|
||
|
+192.0.1.68 example.org
|
||
|
+192.0.1.69 example.org
|
||
|
+192.0.1.70 example.org
|
||
|
+192.0.1.71 example.org
|
||
|
+192.0.1.72 example.org
|
||
|
+192.0.1.73 example.org
|
||
|
+192.0.1.74 example.org
|
||
|
+192.0.1.75 example.org
|
||
|
+192.0.1.76 example.org
|
||
|
+192.0.1.77 example.org
|
||
|
+192.0.1.78 example.org
|
||
|
+192.0.1.79 example.org
|
||
|
+192.0.1.80 example.org
|
||
|
+192.0.1.81 example.org
|
||
|
+192.0.1.82 example.org
|
||
|
+192.0.1.83 example.org
|
||
|
+192.0.1.84 example.org
|
||
|
+192.0.1.85 example.org
|
||
|
+192.0.1.86 example.org
|
||
|
+192.0.1.87 example.org
|
||
|
+192.0.1.88 example.org
|
||
|
+192.0.1.89 example.org
|
||
|
+192.0.1.90 example.org
|
||
|
+192.0.1.91 example.org
|
||
|
+192.0.1.92 example.org
|
||
|
+192.0.1.93 example.org
|
||
|
+192.0.1.94 example.org
|
||
|
+192.0.1.95 example.org
|
||
|
+192.0.1.96 example.org
|
||
|
+192.0.1.97 example.org
|
||
|
+192.0.1.98 example.org
|
||
|
+192.0.1.99 example.org
|
||
|
+192.0.1.100 example.org
|
||
|
+192.0.1.101 example.org
|
||
|
+192.0.1.102 example.org
|
||
|
+192.0.1.103 example.org
|
||
|
+192.0.1.104 example.org
|
||
|
+192.0.1.105 example.org
|
||
|
+192.0.1.106 example.org
|
||
|
+192.0.1.107 example.org
|
||
|
+192.0.1.108 example.org
|
||
|
+192.0.1.109 example.org
|
||
|
+192.0.1.110 example.org
|
||
|
+192.0.1.111 example.org
|
||
|
+192.0.1.112 example.org
|
||
|
+192.0.1.113 example.org
|
||
|
+192.0.1.114 example.org
|
||
|
+192.0.1.115 example.org
|
||
|
+192.0.1.116 example.org
|
||
|
+192.0.1.117 example.org
|
||
|
+192.0.1.118 example.org
|
||
|
+192.0.1.119 example.org
|
||
|
+192.0.1.120 example.org
|
||
|
+192.0.1.121 example.org
|
||
|
+192.0.1.122 example.org
|
||
|
+192.0.1.123 example.org
|
||
|
+192.0.1.124 example.org
|
||
|
+192.0.1.125 example.org
|
||
|
+192.0.1.126 example.org
|
||
|
+192.0.1.127 example.org
|
||
|
+192.0.1.128 example.org
|
||
|
+192.0.1.129 example.org
|
||
|
+192.0.1.130 example.org
|
||
|
+192.0.1.131 example.org
|
||
|
+192.0.1.132 example.org
|
||
|
+192.0.1.133 example.org
|
||
|
+192.0.1.134 example.org
|
||
|
+192.0.1.135 example.org
|
||
|
+192.0.1.136 example.org
|
||
|
+192.0.1.137 example.org
|
||
|
+192.0.1.138 example.org
|
||
|
+192.0.1.139 example.org
|
||
|
+192.0.1.140 example.org
|
||
|
+192.0.1.141 example.org
|
||
|
+192.0.1.142 example.org
|
||
|
+192.0.1.143 example.org
|
||
|
+192.0.1.144 example.org
|
||
|
+192.0.1.145 example.org
|
||
|
+192.0.1.146 example.org
|
||
|
+192.0.1.147 example.org
|
||
|
+192.0.1.148 example.org
|
||
|
+192.0.1.149 example.org
|
||
|
+192.0.1.150 example.org
|
||
|
+192.0.1.151 example.org
|
||
|
+192.0.1.152 example.org
|
||
|
+192.0.1.153 example.org
|
||
|
+192.0.1.154 example.org
|
||
|
+192.0.1.155 example.org
|
||
|
+192.0.1.156 example.org
|
||
|
+192.0.1.157 example.org
|
||
|
+192.0.1.158 example.org
|
||
|
+192.0.1.159 example.org
|
||
|
+192.0.1.160 example.org
|
||
|
+192.0.1.161 example.org
|
||
|
+192.0.1.162 example.org
|
||
|
+192.0.1.163 example.org
|
||
|
+192.0.1.164 example.org
|
||
|
+192.0.1.165 example.org
|
||
|
+192.0.1.166 example.org
|
||
|
+192.0.1.167 example.org
|
||
|
+192.0.1.168 example.org
|
||
|
+192.0.1.169 example.org
|
||
|
+192.0.1.170 example.org
|
||
|
+192.0.1.171 example.org
|
||
|
+192.0.1.172 example.org
|
||
|
+192.0.1.173 example.org
|
||
|
+192.0.1.174 example.org
|
||
|
+192.0.1.175 example.org
|
||
|
+192.0.1.176 example.org
|
||
|
+192.0.1.177 example.org
|
||
|
+192.0.1.178 example.org
|
||
|
+192.0.1.179 example.org
|
||
|
+192.0.1.180 example.org
|
||
|
+192.0.1.181 example.org
|
||
|
+192.0.1.182 example.org
|
||
|
+192.0.1.183 example.org
|
||
|
+192.0.1.184 example.org
|
||
|
+192.0.1.185 example.org
|
||
|
+192.0.1.186 example.org
|
||
|
+192.0.1.187 example.org
|
||
|
+192.0.1.188 example.org
|
||
|
+192.0.1.189 example.org
|
||
|
+192.0.1.190 example.org
|
||
|
+192.0.1.191 example.org
|
||
|
+192.0.1.192 example.org
|
||
|
+192.0.1.193 example.org
|
||
|
+192.0.1.194 example.org
|
||
|
+192.0.1.195 example.org
|
||
|
+192.0.1.196 example.org
|
||
|
+192.0.1.197 example.org
|
||
|
+192.0.1.198 example.org
|
||
|
+192.0.1.199 example.org
|
||
|
+192.0.1.200 example.org
|
||
|
+192.0.1.201 example.org
|
||
|
+192.0.1.202 example.org
|
||
|
+192.0.1.203 example.org
|
||
|
+192.0.1.204 example.org
|
||
|
+192.0.1.205 example.org
|
||
|
+192.0.1.206 example.org
|
||
|
+192.0.1.207 example.org
|
||
|
+192.0.1.208 example.org
|
||
|
+192.0.1.209 example.org
|
||
|
+192.0.1.210 example.org
|
||
|
+192.0.1.211 example.org
|
||
|
+192.0.1.212 example.org
|
||
|
+192.0.1.213 example.org
|
||
|
+192.0.1.214 example.org
|
||
|
+192.0.1.215 example.org
|
||
|
+192.0.1.216 example.org
|
||
|
+192.0.1.217 example.org
|
||
|
+192.0.1.218 example.org
|
||
|
+192.0.1.219 example.org
|
||
|
+192.0.1.220 example.org
|
||
|
+192.0.1.221 example.org
|
||
|
+192.0.1.222 example.org
|
||
|
+192.0.1.223 example.org
|
||
|
+192.0.1.224 example.org
|
||
|
+192.0.1.225 example.org
|
||
|
+192.0.1.226 example.org
|
||
|
+192.0.1.227 example.org
|
||
|
+192.0.1.228 example.org
|
||
|
+192.0.1.229 example.org
|
||
|
+192.0.1.230 example.org
|
||
|
+192.0.1.231 example.org
|
||
|
+192.0.1.232 example.org
|
||
|
+192.0.1.233 example.org
|
||
|
+192.0.1.234 example.org
|
||
|
+192.0.1.235 example.org
|
||
|
+192.0.1.236 example.org
|
||
|
+192.0.1.237 example.org
|
||
|
+192.0.1.238 example.org
|
||
|
+192.0.1.239 example.org
|
||
|
+192.0.1.240 example.org
|
||
|
+192.0.1.241 example.org
|
||
|
+192.0.1.242 example.org
|
||
|
+192.0.1.243 example.org
|
||
|
+192.0.1.244 example.org
|
||
|
+192.0.1.245 example.org
|
||
|
+192.0.1.246 example.org
|
||
|
+192.0.1.247 example.org
|
||
|
+192.0.1.248 example.org
|
||
|
+192.0.1.249 example.org
|
||
|
+192.0.1.250 example.org
|
||
|
+192.0.1.251 example.org
|
||
|
+192.0.1.252 example.org
|
||
|
+192.0.1.253 example.org
|
||
|
+192.0.1.254 example.org
|
||
|
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||
|
index fae3dea81f19dba6..4fa963644af8b7d5 100644
|
||
|
--- a/sysdeps/posix/getaddrinfo.c
|
||
|
+++ b/sysdeps/posix/getaddrinfo.c
|
||
|
@@ -474,11 +474,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
|
||
|
if (name != NULL)
|
||
|
{
|
||
|
- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||
|
- at->family = AF_UNSPEC;
|
||
|
- at->scopeid = 0;
|
||
|
- at->next = NULL;
|
||
|
-
|
||
|
if (req->ai_flags & AI_IDN)
|
||
|
{
|
||
|
char *out;
|
||
|
@@ -489,13 +484,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
malloc_name = true;
|
||
|
}
|
||
|
|
||
|
- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
|
||
|
+ uint32_t addr[4];
|
||
|
+ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
|
||
|
{
|
||
|
+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||
|
+ at->scopeid = 0;
|
||
|
+ at->next = NULL;
|
||
|
+
|
||
|
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||
|
- at->family = AF_INET;
|
||
|
+ {
|
||
|
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||
|
+ at->family = AF_INET;
|
||
|
+ }
|
||
|
else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
|
||
|
{
|
||
|
- at->addr[3] = at->addr[0];
|
||
|
+ at->addr[3] = addr[0];
|
||
|
at->addr[2] = htonl (0xffff);
|
||
|
at->addr[1] = 0;
|
||
|
at->addr[0] = 0;
|
||
|
@@ -509,49 +512,62 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
|
||
|
if (req->ai_flags & AI_CANONNAME)
|
||
|
canon = name;
|
||
|
+
|
||
|
+ goto process_list;
|
||
|
}
|
||
|
- else if (at->family == AF_UNSPEC)
|
||
|
+
|
||
|
+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||
|
+ int e;
|
||
|
+
|
||
|
+ if (scope_delim == NULL)
|
||
|
+ e = inet_pton (AF_INET6, name, addr);
|
||
|
+ else
|
||
|
+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
|
||
|
+
|
||
|
+ if (e > 0)
|
||
|
{
|
||
|
- char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||
|
- int e;
|
||
|
- if (scope_delim == NULL)
|
||
|
- e = inet_pton (AF_INET6, name, at->addr);
|
||
|
+ at = alloca_account (sizeof (struct gaih_addrtuple),
|
||
|
+ alloca_used);
|
||
|
+ at->scopeid = 0;
|
||
|
+ at->next = NULL;
|
||
|
+
|
||
|
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||
|
+ {
|
||
|
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||
|
+ at->family = AF_INET6;
|
||
|
+ }
|
||
|
+ else if (req->ai_family == AF_INET
|
||
|
+ && IN6_IS_ADDR_V4MAPPED (addr))
|
||
|
+ {
|
||
|
+ at->addr[0] = addr[3];
|
||
|
+ at->addr[1] = addr[1];
|
||
|
+ at->addr[2] = addr[2];
|
||
|
+ at->addr[3] = addr[3];
|
||
|
+ at->family = AF_INET;
|
||
|
+ }
|
||
|
else
|
||
|
- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
|
||
|
- at->addr);
|
||
|
- if (e > 0)
|
||
|
{
|
||
|
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||
|
- at->family = AF_INET6;
|
||
|
- else if (req->ai_family == AF_INET
|
||
|
- && IN6_IS_ADDR_V4MAPPED (at->addr))
|
||
|
- {
|
||
|
- at->addr[0] = at->addr[3];
|
||
|
- at->family = AF_INET;
|
||
|
- }
|
||
|
- else
|
||
|
- {
|
||
|
- result = -EAI_ADDRFAMILY;
|
||
|
- goto free_and_return;
|
||
|
- }
|
||
|
-
|
||
|
- if (scope_delim != NULL
|
||
|
- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||
|
- scope_delim + 1,
|
||
|
- &at->scopeid) != 0)
|
||
|
- {
|
||
|
- result = -EAI_NONAME;
|
||
|
- goto free_and_return;
|
||
|
- }
|
||
|
+ result = -EAI_ADDRFAMILY;
|
||
|
+ goto free_and_return;
|
||
|
+ }
|
||
|
|
||
|
- if (req->ai_flags & AI_CANONNAME)
|
||
|
- canon = name;
|
||
|
+ if (scope_delim != NULL
|
||
|
+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||
|
+ scope_delim + 1,
|
||
|
+ &at->scopeid) != 0)
|
||
|
+ {
|
||
|
+ result = -EAI_NONAME;
|
||
|
+ goto free_and_return;
|
||
|
}
|
||
|
+
|
||
|
+ if (req->ai_flags & AI_CANONNAME)
|
||
|
+ canon = name;
|
||
|
+
|
||
|
+ goto process_list;
|
||
|
}
|
||
|
|
||
|
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
|
||
|
+ if ((req->ai_flags & AI_NUMERICHOST) == 0)
|
||
|
{
|
||
|
- struct gaih_addrtuple **pat = &at;
|
||
|
int no_data = 0;
|
||
|
int no_inet6_data = 0;
|
||
|
service_user *nip;
|
||
|
@@ -560,6 +576,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
int no_more;
|
||
|
struct resolv_context *res_ctx = NULL;
|
||
|
bool res_enable_inet6 = false;
|
||
|
+ bool do_merge = false;
|
||
|
|
||
|
/* If we do not have to look for IPv6 addresses or the canonical
|
||
|
name, use the simple, old functions, which do not support
|
||
|
@@ -596,7 +613,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
result = -EAI_MEMORY;
|
||
|
goto free_and_return;
|
||
|
}
|
||
|
- *pat = addrmem;
|
||
|
+ at = addrmem;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@@ -649,6 +666,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
}
|
||
|
|
||
|
struct gaih_addrtuple *addrfree = addrmem;
|
||
|
+ struct gaih_addrtuple **pat = &at;
|
||
|
+
|
||
|
for (int i = 0; i < air->naddrs; ++i)
|
||
|
{
|
||
|
socklen_t size = (air->family[i] == AF_INET
|
||
|
@@ -712,12 +731,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
|
||
|
free (air);
|
||
|
|
||
|
- if (at->family == AF_UNSPEC)
|
||
|
- {
|
||
|
- result = -EAI_NONAME;
|
||
|
- goto free_and_return;
|
||
|
- }
|
||
|
-
|
||
|
goto process_list;
|
||
|
}
|
||
|
else if (err == 0)
|
||
|
@@ -756,6 +769,22 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
|
||
|
while (!no_more)
|
||
|
{
|
||
|
+ /* Always start afresh; continue should discard previous results
|
||
|
+ and the hosts database does not support merge. */
|
||
|
+ at = NULL;
|
||
|
+ free (canonbuf);
|
||
|
+ free (addrmem);
|
||
|
+ canon = canonbuf = NULL;
|
||
|
+ addrmem = NULL;
|
||
|
+ got_ipv6 = false;
|
||
|
+
|
||
|
+ if (do_merge)
|
||
|
+ {
|
||
|
+ __set_h_errno (NETDB_INTERNAL);
|
||
|
+ __set_errno (EBUSY);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
no_data = 0;
|
||
|
nss_gethostbyname4_r fct4 = NULL;
|
||
|
|
||
|
@@ -768,12 +797,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
{
|
||
|
while (1)
|
||
|
{
|
||
|
- status = DL_CALL_FCT (fct4, (name, pat,
|
||
|
+ status = DL_CALL_FCT (fct4, (name, &at,
|
||
|
tmpbuf->data, tmpbuf->length,
|
||
|
&errno, &h_errno,
|
||
|
NULL));
|
||
|
if (status == NSS_STATUS_SUCCESS)
|
||
|
break;
|
||
|
+ /* gethostbyname4_r may write into AT, so reset it. */
|
||
|
+ at = NULL;
|
||
|
if (status != NSS_STATUS_TRYAGAIN
|
||
|
|| errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||
|
{
|
||
|
@@ -800,7 +831,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
no_data = 1;
|
||
|
|
||
|
if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
|
||
|
- canon = (*pat)->name;
|
||
|
+ canon = at->name;
|
||
|
+
|
||
|
+ struct gaih_addrtuple **pat = &at;
|
||
|
|
||
|
while (*pat != NULL)
|
||
|
{
|
||
|
@@ -852,6 +885,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
|
||
|
if (fct != NULL)
|
||
|
{
|
||
|
+ struct gaih_addrtuple **pat = &at;
|
||
|
+
|
||
|
if (req->ai_family == AF_INET6
|
||
|
|| req->ai_family == AF_UNSPEC)
|
||
|
{
|
||
|
@@ -927,6 +962,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||
|
break;
|
||
|
|
||
|
+ /* The hosts database does not support MERGE. */
|
||
|
+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||
|
+ do_merge = true;
|
||
|
+
|
||
|
if (nip->next == NULL)
|
||
|
no_more = -1;
|
||
|
else
|
||
|
@@ -960,7 +999,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||
|
}
|
||
|
|
||
|
process_list:
|
||
|
- if (at->family == AF_UNSPEC)
|
||
|
+ if (at == NULL)
|
||
|
{
|
||
|
result = -EAI_NONAME;
|
||
|
goto free_and_return;
|