1 From 85cfe508568530eed2d9cfd34110c21721d1f99e Mon Sep 17 00:00:00 2001
2 From: Florian Weimer <fweimer@redhat.com>
3 Date: Wed, 6 Sep 2017 13:43:01 +0200
4 Subject: [PATCH 28] tst-res_use_inet6: Enhance test to cover IPv4-to-IPv6
7 This requires more control over the response data, so it is now
8 determined by flags embedded in the query name.
10 (cherry picked from commit 5e9c4d17feb9910f489ad2915d0b6e00597a0f11)
13 resolv/tst-res_use_inet6.c | 231 ++++++++++++++++++++++++++++++++++++---------
14 2 files changed, 198 insertions(+), 45 deletions(-)
16 diff --git a/ChangeLog b/ChangeLog
17 index 3e32d14dbf..dd71f6c427 100644
21 +2017-09-06 Florian Weimer <fweimer@redhat.com>
23 + Enhance tst-res_use_inet6 to test IPv4-to-IPv6 address mapping.
24 + * resolv/tst-res_use_inet6.c (response): Process flags embedded in
26 + (test_gai): Adjust query names. Add additional tests.
27 + (test_get2_any, test_get2_no_inet6, test_get2_inet6): Split from
28 + test_get2. Adjust query names. Add additional tests.
29 + (test_no_inet6): New function, extracted from threadfunc.
30 + (threadfunc): Call test_get2_any, test_get2_inet6, test_no_inet6.
31 + Add additional tests.
33 2017-09-01 Florian Weimer <fweimer@redhat.com>
36 diff --git a/resolv/tst-res_use_inet6.c b/resolv/tst-res_use_inet6.c
37 index 6f3db08892..1522d5c5f5 100644
38 --- a/resolv/tst-res_use_inet6.c
39 +++ b/resolv/tst-res_use_inet6.c
44 +#include <support/check.h>
45 #include <support/check_nss.h>
46 #include <support/resolv_test.h>
47 #include <support/xthread.h>
49 +/* Produce a response based on QNAME: Certain characters in the first
50 + label of QNAME trigger the inclusion of resource records:
52 + 'a' A record (IPv4 address)
53 + 'q' AAAA record (quad A record, IPv6 address)
54 + 'm' record type must match QTYPE (no additional records)
56 + QTYPE is ignored for record type selection if 'm' is not
59 response (const struct resolv_response_context *ctx,
60 struct resolv_response_builder *b,
61 const char *qname, uint16_t qclass, uint16_t qtype)
63 - bool include_both = strcmp (qname, "both.example") == 0;
64 - bool include_a = qtype == T_A || include_both;
65 - bool include_aaaa = qtype == T_AAAA || include_both;
66 + bool include_a = false;
67 + bool include_aaaa = false;
68 + bool include_match = false;
69 + for (const char *p = qname; *p != '.' && *p != '\0'; ++p)
74 + include_aaaa = true;
76 + include_match = true;
81 + include_aaaa = false;
82 + else if (qtype == T_AAAA)
86 resolv_response_init (b, (struct resolv_response_flags) {});
87 resolv_response_add_question (b, qname, qclass, qtype);
88 @@ -64,16 +90,21 @@ test_gai (void)
89 .ai_protocol = IPPROTO_TCP,
92 - int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
93 - check_addrinfo ("getaddrinfo AF_UNSPEC www1.example", ai, ret,
94 + int ret = getaddrinfo ("qam.example", "80", &hints, &ai);
95 + check_addrinfo ("getaddrinfo AF_UNSPEC qam.example", ai, ret,
96 "address: STREAM/TCP 192.0.2.17 80\n"
97 "address: STREAM/TCP 2001:db8::1 80\n");
100 - ret = getaddrinfo ("both.example", "80", &hints, &ai);
101 + ret = getaddrinfo ("am.example", "80", &hints, &ai);
102 + check_addrinfo ("getaddrinfo AF_UNSPEC am.example", ai, ret,
103 + "address: STREAM/TCP 192.0.2.17 80\n");
106 + ret = getaddrinfo ("qa.example", "80", &hints, &ai);
107 /* Combined A/AAAA responses currently result in address
109 - check_addrinfo ("getaddrinfo AF_UNSPEC both.example", ai, ret,
110 + check_addrinfo ("getaddrinfo AF_UNSPEC qa.example", ai, ret,
111 "address: STREAM/TCP 192.0.2.17 80\n"
112 "address: STREAM/TCP 192.0.2.17 80\n"
113 "address: STREAM/TCP 2001:db8::1 80\n"
114 @@ -89,13 +120,18 @@ test_gai (void)
115 .ai_protocol = IPPROTO_TCP,
118 - int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
119 - check_addrinfo ("getaddrinfo AF_INET www1.example", ai, ret,
120 + int ret = getaddrinfo ("qam.example", "80", &hints, &ai);
121 + check_addrinfo ("getaddrinfo AF_INET qam.example", ai, ret,
122 + "address: STREAM/TCP 192.0.2.17 80\n");
125 + ret = getaddrinfo ("am.example", "80", &hints, &ai);
126 + check_addrinfo ("getaddrinfo AF_INET am.example", ai, ret,
127 "address: STREAM/TCP 192.0.2.17 80\n");
130 - ret = getaddrinfo ("both.example", "80", &hints, &ai);
131 - check_addrinfo ("getaddrinfo AF_INET both.example", ai, ret,
132 + ret = getaddrinfo ("qa.example", "80", &hints, &ai);
133 + check_addrinfo ("getaddrinfo AF_INET qa.example", ai, ret,
134 "address: STREAM/TCP 192.0.2.17 80\n");
137 @@ -108,40 +144,131 @@ test_gai (void)
138 .ai_protocol = IPPROTO_TCP,
141 - int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
142 + int ret = getaddrinfo ("qa.example", "80", &hints, &ai);
143 check_addrinfo ("getaddrinfo (AF_INET6)", ai, ret,
144 "address: STREAM/TCP 2001:db8::1 80\n");
147 - ret = getaddrinfo ("both.example", "80", &hints, &ai);
148 - check_addrinfo ("getaddrinfo AF_INET6 both.example", ai, ret,
149 + ret = getaddrinfo ("am.example", "80", &hints, &ai);
150 + check_addrinfo ("getaddrinfo AF_INET6 am.example", ai, ret,
151 + "error: No address associated with hostname\n");
154 + ret = getaddrinfo ("qam.example", "80", &hints, &ai);
155 + check_addrinfo ("getaddrinfo AF_INET6 qam.example", ai, ret,
156 "address: STREAM/TCP 2001:db8::1 80\n");
162 -/* Test that gethostbyname2 is not influenced by RES_USE_INET6. */
163 +/* Test that gethostbyname2 is mostly not influenced by
167 +test_get2_any (void)
169 - check_hostent ("gethostbyname2 AF_INET www1.example",
170 - gethostbyname2 ("www1.example", AF_INET),
171 - "name: www1.example\n"
172 + check_hostent ("gethostbyname2 AF_INET am.example",
173 + gethostbyname2 ("am.example", AF_INET),
174 + "name: am.example\n"
175 "address: 192.0.2.17\n");
176 - check_hostent ("gethostbyname2 AF_INET both.example",
177 - gethostbyname2 ("both.example", AF_INET),
178 - "name: both.example\n"
179 + check_hostent ("gethostbyname2 AF_INET a.example",
180 + gethostbyname2 ("a.example", AF_INET),
181 + "name: a.example\n"
182 + "address: 192.0.2.17\n");
183 + check_hostent ("gethostbyname2 AF_INET qm.example",
184 + gethostbyname2 ("qm.example", AF_INET),
185 + "error: NO_ADDRESS\n");
186 + check_hostent ("gethostbyname2 AF_INET q.example",
187 + gethostbyname2 ("q.example", AF_INET),
188 + "error: NO_RECOVERY\n");
189 + check_hostent ("gethostbyname2 AF_INET qam.example",
190 + gethostbyname2 ("qam.example", AF_INET),
191 + "name: qam.example\n"
192 + "address: 192.0.2.17\n");
193 + check_hostent ("gethostbyname2 AF_INET qa.example",
194 + gethostbyname2 ("qa.example", AF_INET),
195 + "name: qa.example\n"
196 "address: 192.0.2.17\n");
198 - check_hostent ("gethostbyname2 AF_INET6 www1.example",
199 - gethostbyname2 ("www1.example", AF_INET6),
200 - "name: www1.example\n"
201 + check_hostent ("gethostbyname2 AF_INET6 qm.example",
202 + gethostbyname2 ("qm.example", AF_INET6),
203 + "name: qm.example\n"
204 + "address: 2001:db8::1\n");
205 + check_hostent ("gethostbyname2 AF_INET6 q.example",
206 + gethostbyname2 ("q.example", AF_INET6),
207 + "name: q.example\n"
208 "address: 2001:db8::1\n");
209 - check_hostent ("gethostbyname2 AF_INET6 both.example",
210 - gethostbyname2 ("both.example", AF_INET6),
211 - "name: both.example\n"
212 + check_hostent ("gethostbyname2 AF_INET6 qam.example",
213 + gethostbyname2 ("qam.example", AF_INET6),
214 + "name: qam.example\n"
215 "address: 2001:db8::1\n");
216 + check_hostent ("gethostbyname2 AF_INET6 qa.example",
217 + gethostbyname2 ("qa.example", AF_INET6),
218 + "name: qa.example\n"
219 + "address: 2001:db8::1\n");
220 + /* Additional AF_INET6 tests depend on RES_USE_INET6; see below. */
223 +/* gethostbyname2 tests with RES_USE_INET6 disabled. */
225 +test_get2_no_inet6 (void)
229 + check_hostent ("gethostbyname2 AF_INET6 am.example",
230 + gethostbyname2 ("am.example", AF_INET6),
231 + "error: NO_ADDRESS\n");
232 + check_hostent ("gethostbyname2 AF_INET6 a.example",
233 + gethostbyname2 ("a.example", AF_INET6),
234 + "error: NO_RECOVERY\n");
237 +/* gethostbyname2 tests with RES_USE_INET6 enabled. */
239 +test_get2_inet6 (void)
243 + check_hostent ("gethostbyname2 AF_INET6 am.example",
244 + gethostbyname2 ("am.example", AF_INET6),
245 + "name: am.example\n"
246 + "address: ::ffff:192.0.2.17\n");
247 + check_hostent ("gethostbyname2 AF_INET6 a.example",
248 + gethostbyname2 ("a.example", AF_INET6),
249 + "error: NO_RECOVERY\n");
252 +/* Collection of tests which assume no RES_USE_INET6 flag. */
254 +test_no_inet6 (void)
256 + check_hostent ("gethostbyname (\"a.example\")",
257 + gethostbyname ("a.example"),
258 + "name: a.example\n"
259 + "address: 192.0.2.17\n");
260 + check_hostent ("gethostbyname (\"qa.example\")",
261 + gethostbyname ("qa.example"),
262 + "name: qa.example\n"
263 + "address: 192.0.2.17\n");
264 + check_hostent ("gethostbyname (\"am.example\")",
265 + gethostbyname ("am.example"),
266 + "name: am.example\n"
267 + "address: 192.0.2.17\n");
268 + check_hostent ("gethostbyname (\"qam.example\")",
269 + gethostbyname ("qam.example"),
270 + "name: qam.example\n"
271 + "address: 192.0.2.17\n");
272 + check_hostent ("gethostbyname (\"q.example\")",
273 + gethostbyname ("q.example"),
274 + "error: NO_RECOVERY\n");
275 + check_hostent ("gethostbyname (\"qm.example\")",
276 + gethostbyname ("qm.example"),
277 + "error: NO_ADDRESS\n");
278 + test_get2_no_inet6 ();
279 + test_get2_no_inet6 ();
281 + test_get2_no_inet6 ();
282 + test_get2_no_inet6 ();
286 @@ -153,28 +280,42 @@ threadfunc (void *ignored)
287 .response_callback = response
290 - check_hostent ("gethostbyname (\"www1.example\")",
291 - gethostbyname ("www1.example"),
292 - "name: www1.example\n"
293 - "address: 192.0.2.17\n");
294 - check_hostent ("gethostbyname (\"both.example\")",
295 - gethostbyname ("both.example"),
296 - "name: both.example\n"
297 - "address: 192.0.2.17\n");
300 + TEST_VERIFY ((_res.options & RES_USE_INET6) == 0);
303 _res.options |= RES_USE_INET6;
304 - check_hostent ("gethostbyname (\"www1.example\")",
305 - gethostbyname ("www1.example"),
306 - "name: www1.example\n"
307 + check_hostent ("gethostbyname (\"a.inet6.example\")",
308 + gethostbyname ("a.inet6.example"),
309 + "error: NO_RECOVERY\n");
310 + check_hostent ("gethostbyname (\"am.inet6.example\")",
311 + gethostbyname ("am.inet6.example"),
312 + "name: am.inet6.example\n"
313 + "address: ::ffff:192.0.2.17\n");
314 + check_hostent ("gethostbyname (\"qa.inet6.example\")",
315 + gethostbyname ("qa.inet6.example"),
316 + "name: qa.inet6.example\n"
317 + "address: 2001:db8::1\n");
318 + check_hostent ("gethostbyname (\"qam.inet6.example\")",
319 + gethostbyname ("qam.inet6.example"),
320 + "name: qam.inet6.example\n"
321 "address: 2001:db8::1\n");
322 - check_hostent ("gethostbyname (\"both.example\")",
323 - gethostbyname ("both.example"),
324 - "name: both.example\n"
325 + check_hostent ("gethostbyname (\"q.inet6.example\")",
326 + gethostbyname ("q.inet6.example"),
327 + "name: q.inet6.example\n"
328 "address: 2001:db8::1\n");
330 + check_hostent ("gethostbyname (\"qm.inet6.example\")",
331 + gethostbyname ("qm.inet6.example"),
332 + "name: qm.inet6.example\n"
333 + "address: 2001:db8::1\n");
334 + test_get2_inet6 ();
335 + test_get2_inet6 ();
337 + test_get2_inet6 ();
338 + test_get2_inet6 ();
340 + TEST_VERIFY (_res.options & RES_USE_INET6);
341 + _res.options &= ~RES_USE_INET6;
344 resolv_test_end (obj);