]> git.ipfire.org Git - thirdparty/glibc.git/blob - resolv/tst-resolv-ai_idn-common.c
hurd: Fix build
[thirdparty/glibc.git] / resolv / tst-resolv-ai_idn-common.c
1 /* Common code for AI_IDN/NI_IDN tests.
2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 /* Before including this file, TEST_USE_UTF8 must be defined to 1 or
20 0, depending on whether a UTF-8 locale is used or a Latin-1
21 locale. */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <support/check.h>
27 #include <support/check_nss.h>
28 #include <support/resolv_test.h>
29 #include <support/support.h>
30
31 /* Name of the shared object for libidn2. */
32 #define LIBIDN2_SONAME "libidn2.so.0"
33
34 #if TEST_USE_UTF8
35 /* UTF-8 encoding of "nämchen" (German for “namelet”). */
36 # define NAEMCHEN "n\xC3\xA4mchen"
37
38 /* UTF-8 encoding of "שם" (Hebrew for “name”). */
39 # define SHEM "\xD7\xA9\xD7\x9D"
40
41 /* UTF-8 encoding of "buße" (German for “penance”). This used to be
42 encoded as "busse" (“busses”) in IDNA2003. */
43 # define BUSSE "bu\xC3\x9F""e"
44
45 #else
46 /* Latin-1 encodings, as far as they are available. */
47
48 # define NAEMCHEN "n\xE4mchen"
49 # define BUSSE "bu\xDF""e"
50
51 #endif
52
53 /* IDNA encoding of NAEMCHEN. */
54 #define NAEMCHEN_IDNA "xn--nmchen-bua"
55
56 /* IDNA encoding of NAEMCHEN "_zwo". */
57 #define NAEMCHEN_ZWO_IDNA "xn--nmchen_zwo-q5a"
58
59 /* IDNA encoding of SHEM. */
60 #define SHEM_IDNA "xn--iebx"
61
62 /* IDNA encoding of BUSSE. */
63 #define BUSSE_IDNA "xn--bue-6ka"
64
65 /* IDNA encoding of "שם1". */
66 #define SHEM1_IDNA "xn--1-qic9a"
67
68 /* Another IDNA name. */
69 #define ANDERES_NAEMCHEN "anderes-" NAEMCHEN
70 #define ANDERES_NAEMCHEN_IDNA "xn--anderes-nmchen-eib"
71
72 /* Controls the kind of test data in a PTR lookup response. */
73 enum gni_test
74 {
75 gni_non_idn_name,
76 gni_non_idn_cname_to_non_idn_name,
77 gni_non_idn_cname_to_idn_name,
78 gni_idn_name,
79 gni_idn_shem,
80 gni_idn_shem1,
81 gni_idn_cname_to_non_idn_name,
82 gni_idn_cname_to_idn_name,
83 gni_invalid_idn_1,
84 gni_invalid_idn_2,
85 };
86
87 /* Called from response below. The LSB (first byte) controls what
88 goes into the response, see enum gni_test. */
89 static void
90 response_ptr (const struct resolv_response_context *ctx,
91 struct resolv_response_builder *b, const char *qname)
92 {
93 int comp[4] = { 0 };
94 TEST_COMPARE (sscanf (qname, "%d.%d.%d.%d.in-addr.arpa",
95 &comp[0], &comp[1], &comp[2], &comp[3]), 4);
96 const char *next_name;
97 switch ((enum gni_test) comp[0])
98 {
99 /* First name in response is non-IDN name. */
100 case gni_non_idn_name:
101 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
102 resolv_response_add_name (b, "non-idn.example");
103 resolv_response_close_record (b);
104 return;
105 case gni_non_idn_cname_to_non_idn_name:
106 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
107 next_name = "non-idn-cname.example";
108 resolv_response_add_name (b, next_name);
109 resolv_response_close_record (b);
110 resolv_response_open_record (b, next_name, C_IN, T_PTR, 0);
111 resolv_response_add_name (b, "non-idn-name.example");
112 resolv_response_close_record (b);
113 return;
114 case gni_non_idn_cname_to_idn_name:
115 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
116 next_name = "non-idn-cname.example";
117 resolv_response_add_name (b, next_name);
118 resolv_response_close_record (b);
119 resolv_response_open_record (b, next_name, C_IN, T_PTR, 0);
120 resolv_response_add_name (b, NAEMCHEN_IDNA ".example");
121 resolv_response_close_record (b);
122 return;
123
124 /* First name in response is IDN name. */
125 case gni_idn_name:
126 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
127 resolv_response_add_name (b, "xn--nmchen-bua.example");
128 resolv_response_close_record (b);
129 return;
130 case gni_idn_shem:
131 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
132 resolv_response_add_name (b, SHEM_IDNA ".example");
133 resolv_response_close_record (b);
134 return;
135 case gni_idn_shem1:
136 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
137 resolv_response_add_name (b, SHEM1_IDNA ".example");
138 resolv_response_close_record (b);
139 return;
140 case gni_idn_cname_to_non_idn_name:
141 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
142 next_name = NAEMCHEN_IDNA ".example";
143 resolv_response_add_name (b, next_name);
144 resolv_response_close_record (b);
145 resolv_response_open_record (b, next_name, C_IN, T_PTR, 0);
146 resolv_response_add_name (b, "non-idn-name.example");
147 resolv_response_close_record (b);
148 return;
149 case gni_idn_cname_to_idn_name:
150 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
151 next_name = NAEMCHEN_IDNA ".example";
152 resolv_response_add_name (b, next_name);
153 resolv_response_close_record (b);
154 resolv_response_open_record (b, next_name, C_IN, T_PTR, 0);
155 resolv_response_add_name (b, ANDERES_NAEMCHEN_IDNA ".example");
156 resolv_response_close_record (b);
157 return;
158
159 /* Invalid IDN encodings. */
160 case gni_invalid_idn_1:
161 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
162 resolv_response_add_name (b, "xn---.example");
163 resolv_response_close_record (b);
164 return;
165 case gni_invalid_idn_2:
166 resolv_response_open_record (b, qname, C_IN, T_PTR, 0);
167 resolv_response_add_name (b, "xn--x.example");
168 resolv_response_close_record (b);
169 return;
170 }
171 FAIL_EXIT1 ("invalid PTR query: %s", qname);
172 }
173
174 /* For PTR responses, see above. A/AAAA queries can request
175 additional CNAMEs in the response by include ".cname." and
176 ".idn-cname." in the query. The LSB in the address contains the
177 first byte of the QNAME. */
178 static void
179 response (const struct resolv_response_context *ctx,
180 struct resolv_response_builder *b,
181 const char *qname, uint16_t qclass, uint16_t qtype)
182 {
183 TEST_VERIFY_EXIT (qclass == C_IN);
184
185 for (const char *p = qname; *p != '\0'; ++p)
186 if (!(('0' <= *p && *p <= '9')
187 || ('a' <= *p && *p <= 'z')
188 || ('A' <= *p && *p <= 'Z')
189 || *p == '.' || *p == '-' || *p == '_'))
190 {
191 /* Non-ASCII query. Reply with NXDOMAIN. */
192 struct resolv_response_flags flags = { .rcode = 3 };
193 resolv_response_init (b, flags);
194 resolv_response_add_question (b, qname, qclass, qtype);
195 return;
196 }
197
198 struct resolv_response_flags flags = { 0 };
199 resolv_response_init (b, flags);
200 resolv_response_add_question (b, qname, qclass, qtype);
201 resolv_response_section (b, ns_s_an);
202
203 if (qtype == T_PTR)
204 {
205 response_ptr (ctx, b, qname);
206 return;
207 }
208
209 bool with_cname = strstr (qname, ".cname.") != NULL;
210 bool with_idn_cname = strstr (qname, ".idn-cname.") != NULL;
211
212 const char *next_name = qname;
213 if (with_cname)
214 {
215 next_name = "non-idn-cname.example";
216 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
217 resolv_response_add_name (b, next_name);
218 resolv_response_close_record (b);
219 }
220 if (with_idn_cname)
221 {
222 next_name = ANDERES_NAEMCHEN_IDNA ".example";
223 resolv_response_open_record (b, qname, C_IN, T_CNAME, 0);
224 resolv_response_add_name (b, next_name);
225 resolv_response_close_record (b);
226 }
227
228 resolv_response_open_record (b, next_name, C_IN, qtype, 0);
229 switch (qtype)
230 {
231 case T_A:
232 {
233 char addr[4] = { 192, 0, 2, qname[0] };
234 resolv_response_add_data (b, &addr, sizeof (addr));
235 }
236 break;
237 case T_AAAA:
238 {
239 char addr[16]
240 = { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 qname[0] };
242 resolv_response_add_data (b, &addr, sizeof (addr));
243 }
244 break;
245 default:
246 FAIL_EXIT1 ("invalid qtype: %d", qtype);
247 }
248 resolv_response_close_record (b);
249 }
250
251 /* Check the result of a getaddrinfo call. */
252 static void
253 check_ai (const char *name, int ai_flags, const char *expected)
254 {
255 struct addrinfo hints =
256 {
257 .ai_flags = ai_flags,
258 .ai_family = AF_INET,
259 .ai_socktype = SOCK_STREAM,
260 };
261 struct addrinfo *ai;
262 char *query = xasprintf ("%s:80 AF_INET/0x%x", name, ai_flags);
263 int ret = getaddrinfo (name, "80", &hints, &ai);
264 check_addrinfo (query, ai, ret, expected);
265 if (ret == 0)
266 freeaddrinfo (ai);
267 free (query);
268 }
269
270 /* Run one getnameinfo test. FLAGS is automatically augmented with
271 NI_NUMERICSERV. */
272 static void
273 gni_test (enum gni_test code, unsigned int flags, const char *expected)
274 {
275 struct sockaddr_in sin =
276 {
277 .sin_family = AF_INET,
278 .sin_port = htons (80),
279 .sin_addr = { htonl (0xc0000200 | code) }, /* 192.0.2.0/24 network. */
280 };
281 char host[1024];
282 char service[1024];
283 int ret = getnameinfo ((const struct sockaddr *) &sin, sizeof (sin),
284 host, sizeof (host), service, sizeof (service),
285 flags| NI_NUMERICSERV);
286 if (ret != 0)
287 {
288 if (expected == NULL)
289 TEST_COMPARE (ret, EAI_IDN_ENCODE);
290 else
291 {
292 support_record_failure ();
293 printf ("error: getnameinfo failed (code %d, flags 0x%x): %s (%d)\n",
294 (int) code, flags, gai_strerror (ret), ret);
295 }
296 }
297 else if (ret == 0 && expected == NULL)
298 {
299 support_record_failure ();
300 printf ("error: getnameinfo unexpected success (code %d, flags 0x%x)\n",
301 (int) code, flags);
302 }
303 else if (strcmp (host, expected) != 0 || strcmp (service, "80") != 0)
304 {
305 support_record_failure ();
306 printf ("error: getnameinfo test failure (code %d, flags 0x%x)\n"
307 " expected host: \"%s\"\n"
308 " expected service: \"80\"\n"
309 " actual host: \"%s\"\n"
310 " actual service: \"%s\"\n",
311 (int) code, flags, expected, host, service);
312 }
313 }
314
315 /* Tests for getaddrinfo which assume a working libidn2 library. */
316 __attribute__ ((unused))
317 static void
318 gai_tests_with_libidn2 (void)
319 {
320 /* No CNAME. */
321 check_ai ("non-idn.example", 0,
322 "address: STREAM/TCP 192.0.2.110 80\n");
323 check_ai ("non-idn.example", AI_IDN,
324 "flags: AI_IDN\n"
325 "address: STREAM/TCP 192.0.2.110 80\n");
326 check_ai ("non-idn.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
327 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
328 "canonname: non-idn.example\n"
329 "address: STREAM/TCP 192.0.2.110 80\n");
330
331 check_ai (NAEMCHEN ".example", 0,
332 "error: Name or service not known\n");
333 check_ai (NAEMCHEN ".example", AI_IDN,
334 "flags: AI_IDN\n"
335 "address: STREAM/TCP 192.0.2.120 80\n");
336 check_ai (NAEMCHEN ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
337 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
338 "canonname: " NAEMCHEN ".example\n"
339 "address: STREAM/TCP 192.0.2.120 80\n");
340
341 #if TEST_USE_UTF8
342 check_ai (SHEM ".example", 0,
343 "error: Name or service not known\n");
344 check_ai (SHEM ".example", AI_IDN,
345 "flags: AI_IDN\n"
346 "address: STREAM/TCP 192.0.2.120 80\n");
347 check_ai (SHEM ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
348 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
349 "canonname: " SHEM ".example\n"
350 "address: STREAM/TCP 192.0.2.120 80\n");
351 check_ai (SHEM ".example", AI_IDN | AI_CANONNAME,
352 "flags: AI_CANONNAME AI_IDN\n"
353 "canonname: " SHEM_IDNA ".example\n"
354 "address: STREAM/TCP 192.0.2.120 80\n");
355 check_ai (SHEM "1.example", AI_IDN,
356 "flags: AI_IDN\n"
357 "address: STREAM/TCP 192.0.2.120 80\n");
358 check_ai (SHEM "1.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
359 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
360 "canonname: " SHEM "1.example\n"
361 "address: STREAM/TCP 192.0.2.120 80\n");
362 check_ai (SHEM "1.example", AI_IDN | AI_CANONNAME,
363 "flags: AI_CANONNAME AI_IDN\n"
364 "canonname: " SHEM1_IDNA ".example\n"
365 "address: STREAM/TCP 192.0.2.120 80\n");
366 #endif
367
368 /* Check that non-transitional mode is active. German sharp S
369 should not turn into SS. */
370 check_ai (BUSSE ".example", 0,
371 "error: Name or service not known\n");
372 check_ai (BUSSE ".example", AI_IDN,
373 "flags: AI_IDN\n"
374 "address: STREAM/TCP 192.0.2.120 80\n");
375 check_ai (BUSSE ".example", AI_IDN | AI_CANONNAME,
376 "flags: AI_CANONNAME AI_IDN\n"
377 "canonname: " BUSSE_IDNA ".example\n"
378 "address: STREAM/TCP 192.0.2.120 80\n");
379 check_ai (BUSSE ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
380 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
381 "canonname: " BUSSE ".example\n"
382 "address: STREAM/TCP 192.0.2.120 80\n");
383
384 /* Check that Unicode TR 46 mode is active. Underscores should be
385 permitted in IDNA components. */
386 check_ai (NAEMCHEN "_zwo.example", 0,
387 "error: Name or service not known\n");
388 check_ai (NAEMCHEN "_zwo.example", AI_IDN,
389 "flags: AI_IDN\n"
390 "address: STREAM/TCP 192.0.2.120 80\n");
391 check_ai (NAEMCHEN "_zwo.example", AI_IDN | AI_CANONNAME,
392 "flags: AI_CANONNAME AI_IDN\n"
393 "canonname: " NAEMCHEN_ZWO_IDNA ".example\n"
394 "address: STREAM/TCP 192.0.2.120 80\n");
395 check_ai (NAEMCHEN "_zwo.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
396 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
397 "canonname: " NAEMCHEN "_zwo.example\n"
398 "address: STREAM/TCP 192.0.2.120 80\n");
399
400 /* No CNAME, but already IDN-encoded. */
401 check_ai (NAEMCHEN_IDNA ".example", 0,
402 "address: STREAM/TCP 192.0.2.120 80\n");
403 check_ai (NAEMCHEN_IDNA ".example", AI_IDN,
404 "flags: AI_IDN\n"
405 "address: STREAM/TCP 192.0.2.120 80\n");
406 check_ai (NAEMCHEN_IDNA ".example", AI_IDN | AI_CANONNAME,
407 "flags: AI_CANONNAME AI_IDN\n"
408 "canonname: " NAEMCHEN_IDNA ".example\n"
409 "address: STREAM/TCP 192.0.2.120 80\n");
410 check_ai (NAEMCHEN_IDNA ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
411 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
412 "canonname: " NAEMCHEN ".example\n"
413 "address: STREAM/TCP 192.0.2.120 80\n");
414 check_ai (SHEM_IDNA ".example", 0,
415 "address: STREAM/TCP 192.0.2.120 80\n");
416 check_ai (SHEM_IDNA ".example", AI_IDN,
417 "flags: AI_IDN\n"
418 "address: STREAM/TCP 192.0.2.120 80\n");
419 check_ai (SHEM_IDNA ".example", AI_IDN | AI_CANONNAME,
420 "flags: AI_CANONNAME AI_IDN\n"
421 "canonname: " SHEM_IDNA ".example\n"
422 "address: STREAM/TCP 192.0.2.120 80\n");
423 #if TEST_USE_UTF8
424 check_ai (SHEM_IDNA ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
425 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
426 "canonname: " SHEM ".example\n"
427 "address: STREAM/TCP 192.0.2.120 80\n");
428 #else
429 check_ai (SHEM_IDNA ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
430 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
431 "canonname: " SHEM_IDNA ".example\n"
432 "address: STREAM/TCP 192.0.2.120 80\n");
433 #endif
434
435 /* Invalid IDNA canonical name is returned as-is. */
436 check_ai ("xn---.example", AI_CANONNAME | AI_CANONIDN,
437 "flags: AI_CANONNAME AI_CANONIDN\n"
438 "canonname: xn---.example\n"
439 "address: STREAM/TCP 192.0.2.120 80\n");
440
441 /* Non-IDN CNAME. */
442 check_ai ("with.cname.example", 0,
443 "address: STREAM/TCP 192.0.2.119 80\n");
444 check_ai ("with.cname.example", AI_IDN,
445 "flags: AI_IDN\n"
446 "address: STREAM/TCP 192.0.2.119 80\n");
447 check_ai ("with.cname.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
448 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
449 "canonname: non-idn-cname.example\n"
450 "address: STREAM/TCP 192.0.2.119 80\n");
451
452 check_ai ("with.cname." NAEMCHEN ".example", 0,
453 "error: Name or service not known\n");
454 check_ai ("with.cname." NAEMCHEN ".example", AI_IDN,
455 "flags: AI_IDN\n"
456 "address: STREAM/TCP 192.0.2.119 80\n");
457 check_ai ("with.cname." NAEMCHEN ".example", AI_IDN | AI_CANONNAME,
458 "flags: AI_CANONNAME AI_IDN\n"
459 "canonname: non-idn-cname.example\n"
460 "address: STREAM/TCP 192.0.2.119 80\n");
461 check_ai ("with.cname." NAEMCHEN ".example",
462 AI_IDN | AI_CANONNAME | AI_CANONIDN,
463 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
464 "canonname: non-idn-cname.example\n"
465 "address: STREAM/TCP 192.0.2.119 80\n");
466
467 /* IDN CNAME. */
468 check_ai ("With.idn-cname.example", 0,
469 "address: STREAM/TCP 192.0.2.87 80\n");
470 check_ai ("With.idn-cname.example", AI_IDN,
471 "flags: AI_IDN\n"
472 "address: STREAM/TCP 192.0.2.87 80\n");
473 check_ai ("With.idn-cname.example", AI_IDN | AI_CANONNAME,
474 "flags: AI_CANONNAME AI_IDN\n"
475 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
476 "address: STREAM/TCP 192.0.2.87 80\n");
477 check_ai ("With.idn-cname.example",
478 AI_IDN | AI_CANONNAME | AI_CANONIDN,
479 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
480 "canonname: " ANDERES_NAEMCHEN ".example\n"
481 "address: STREAM/TCP 192.0.2.87 80\n");
482
483 check_ai ("With.idn-cname." NAEMCHEN ".example", 0,
484 "error: Name or service not known\n");
485 check_ai ("With.idn-cname." NAEMCHEN ".example", AI_IDN,
486 "flags: AI_IDN\n"
487 "address: STREAM/TCP 192.0.2.119 80\n");
488 check_ai ("With.idn-cname." NAEMCHEN ".example", AI_IDN | AI_CANONNAME,
489 "flags: AI_CANONNAME AI_IDN\n"
490 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
491 "address: STREAM/TCP 192.0.2.119 80\n");
492 check_ai ("With.idn-cname." NAEMCHEN ".example",
493 AI_IDN | AI_CANONNAME | AI_CANONIDN,
494 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
495 "canonname: " ANDERES_NAEMCHEN ".example\n"
496 "address: STREAM/TCP 192.0.2.119 80\n");
497
498 /* Non-IDN to IDN CNAME chain. */
499 check_ai ("both.cname.idn-cname.example", 0,
500 "address: STREAM/TCP 192.0.2.98 80\n");
501 check_ai ("both.cname.idn-cname.example", AI_IDN,
502 "flags: AI_IDN\n"
503 "address: STREAM/TCP 192.0.2.98 80\n");
504 check_ai ("both.cname.idn-cname.example", AI_IDN | AI_CANONNAME,
505 "flags: AI_CANONNAME AI_IDN\n"
506 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
507 "address: STREAM/TCP 192.0.2.98 80\n");
508 check_ai ("both.cname.idn-cname.example",
509 AI_IDN | AI_CANONNAME | AI_CANONIDN,
510 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
511 "canonname: " ANDERES_NAEMCHEN ".example\n"
512 "address: STREAM/TCP 192.0.2.98 80\n");
513
514 check_ai ("both.cname.idn-cname." NAEMCHEN ".example", 0,
515 "error: Name or service not known\n");
516 check_ai ("both.cname.idn-cname." NAEMCHEN ".example", AI_IDN,
517 "flags: AI_IDN\n"
518 "address: STREAM/TCP 192.0.2.98 80\n");
519 check_ai ("both.cname.idn-cname." NAEMCHEN ".example",
520 AI_IDN | AI_CANONNAME,
521 "flags: AI_CANONNAME AI_IDN\n"
522 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
523 "address: STREAM/TCP 192.0.2.98 80\n");
524 check_ai ("both.cname.idn-cname." NAEMCHEN ".example",
525 AI_IDN | AI_CANONNAME | AI_CANONIDN,
526 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
527 "canonname: " ANDERES_NAEMCHEN ".example\n"
528 "address: STREAM/TCP 192.0.2.98 80\n");
529 }
530
531 /* Tests for getnameinfo which assume a working libidn2 library. */
532 __attribute__ ((unused))
533 static void
534 gni_tests_with_libidn2 (void)
535 {
536 gni_test (gni_non_idn_name, 0, "non-idn.example");
537 gni_test (gni_non_idn_name, NI_IDN, "non-idn.example");
538 gni_test (gni_non_idn_name, NI_NUMERICHOST, "192.0.2.0");
539 gni_test (gni_non_idn_name, NI_NUMERICHOST | NI_IDN, "192.0.2.0");
540
541 gni_test (gni_non_idn_cname_to_non_idn_name, 0, "non-idn-name.example");
542 gni_test (gni_non_idn_cname_to_non_idn_name, NI_IDN, "non-idn-name.example");
543
544 gni_test (gni_non_idn_cname_to_idn_name, 0, NAEMCHEN_IDNA ".example");
545 gni_test (gni_non_idn_cname_to_idn_name, NI_IDN, NAEMCHEN ".example");
546
547 gni_test (gni_idn_name, 0, NAEMCHEN_IDNA ".example");
548 gni_test (gni_idn_name, NI_IDN, NAEMCHEN ".example");
549 gni_test (gni_idn_shem, 0, SHEM_IDNA ".example");
550 gni_test (gni_idn_shem1, 0, SHEM1_IDNA ".example");
551 #if TEST_USE_UTF8
552 gni_test (gni_idn_shem, NI_IDN, SHEM ".example");
553 gni_test (gni_idn_shem1, NI_IDN, SHEM "1.example");
554 #else
555 gni_test (gni_idn_shem, NI_IDN, SHEM_IDNA ".example");
556 gni_test (gni_idn_shem1, NI_IDN, SHEM1_IDNA ".example");
557 #endif
558
559 gni_test (gni_idn_cname_to_non_idn_name, 0, "non-idn-name.example");
560 gni_test (gni_idn_cname_to_non_idn_name, NI_IDN, "non-idn-name.example");
561
562 gni_test (gni_idn_cname_to_idn_name, 0, ANDERES_NAEMCHEN_IDNA ".example");
563 gni_test (gni_idn_cname_to_idn_name, NI_IDN, ANDERES_NAEMCHEN ".example");
564
565 /* Test encoding errors. */
566 gni_test (gni_invalid_idn_1, 0, "xn---.example");
567 gni_test (gni_invalid_idn_1, NI_IDN, "xn---.example");
568 gni_test (gni_invalid_idn_2, 0, "xn--x.example");
569 gni_test (gni_invalid_idn_2, NI_IDN, "xn--x.example");
570 }