1/* Test getaddrinfo and getnameinfo without usable libidn2.
2 Copyright (C) 2018-2022 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 <https://www.gnu.org/licenses/>. */
18
19#define TEST_USE_UTF8 1
20#include "tst-resolv-ai_idn-common.c"
21
22#include <locale.h>
23#include <support/xdlfcn.h>
24
25/* Tests for getaddrinfo. */
26static void
27gai_tests (void)
28{
29 /* No CNAME. */
30 check_ai (name: "non-idn.example", ai_flags: 0,
31 expected: "address: STREAM/TCP 192.0.2.110 80\n");
32 check_ai (name: "non-idn.example", AI_IDN,
33 expected: "flags: AI_IDN\n"
34 "address: STREAM/TCP 192.0.2.110 80\n");
35 check_ai (name: "non-idn.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
36 expected: "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
37 "canonname: non-idn.example\n"
38 "address: STREAM/TCP 192.0.2.110 80\n");
39
40 /* This gets passed over the network to the server, so it will
41 result in an NXDOMAIN error. */
42 check_ai (NAEMCHEN ".example", ai_flags: 0,
43 expected: "error: Name or service not known\n");
44 /* Due to missing libidn2, this fails inside getaddrinfo. */
45 check_ai (NAEMCHEN ".example", AI_IDN,
46 expected: "error: Parameter string not correctly encoded\n");
47 check_ai (NAEMCHEN ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
48 expected: "error: Parameter string not correctly encoded\n");
49
50 /* Non-IDN CNAME. */
51 check_ai (name: "with.cname.example", ai_flags: 0,
52 expected: "address: STREAM/TCP 192.0.2.119 80\n");
53 check_ai (name: "with.cname.example", AI_IDN,
54 expected: "flags: AI_IDN\n"
55 "address: STREAM/TCP 192.0.2.119 80\n");
56 check_ai (name: "with.cname.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
57 expected: "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
58 "canonname: non-idn-cname.example\n"
59 "address: STREAM/TCP 192.0.2.119 80\n");
60
61 /* IDN CNAME. */
62 check_ai (name: "With.idn-cname.example", ai_flags: 0,
63 expected: "address: STREAM/TCP 192.0.2.87 80\n");
64 check_ai (name: "With.idn-cname.example", AI_IDN,
65 expected: "flags: AI_IDN\n"
66 "address: STREAM/TCP 192.0.2.87 80\n");
67 check_ai (name: "With.idn-cname.example", AI_IDN | AI_CANONNAME,
68 expected: "flags: AI_CANONNAME AI_IDN\n"
69 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
70 "address: STREAM/TCP 192.0.2.87 80\n");
71 check_ai (name: "With.idn-cname.example",
72 AI_IDN | AI_CANONNAME | AI_CANONIDN,
73 expected: "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
74 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
75 "address: STREAM/TCP 192.0.2.87 80\n");
76
77 /* Non-IDN to IDN CNAME chain. */
78 check_ai (name: "both.cname.idn-cname.example", ai_flags: 0,
79 expected: "address: STREAM/TCP 192.0.2.98 80\n");
80 check_ai (name: "both.cname.idn-cname.example", AI_IDN,
81 expected: "flags: AI_IDN\n"
82 "address: STREAM/TCP 192.0.2.98 80\n");
83 check_ai (name: "both.cname.idn-cname.example", AI_IDN | AI_CANONNAME,
84 expected: "flags: AI_CANONNAME AI_IDN\n"
85 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
86 "address: STREAM/TCP 192.0.2.98 80\n");
87 check_ai (name: "both.cname.idn-cname.example",
88 AI_IDN | AI_CANONNAME | AI_CANONIDN,
89 expected: "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
90 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
91 "address: STREAM/TCP 192.0.2.98 80\n");
92}
93
94/* Tests for getnameinfo. */
95static void
96gni_tests (void)
97{
98 /* All non-IDN an IDN results are the same due to lack of libidn2
99 support. */
100 for (int do_ni_idn = 0; do_ni_idn < 2; ++do_ni_idn)
101 {
102 int flags = 0;
103 if (do_ni_idn)
104 flags |= NI_IDN;
105
106 gni_test (code: gni_non_idn_name, flags, expected: "non-idn.example");
107 gni_test (code: gni_non_idn_name, flags: flags | NI_NUMERICHOST, expected: "192.0.2.0");
108 gni_test (code: gni_non_idn_cname_to_non_idn_name, flags,
109 expected: "non-idn-name.example");
110 gni_test (code: gni_non_idn_cname_to_idn_name, flags,
111 NAEMCHEN_IDNA ".example");
112 gni_test (code: gni_idn_name, flags, NAEMCHEN_IDNA ".example");
113 gni_test (code: gni_idn_cname_to_non_idn_name, flags, expected: "non-idn-name.example");
114 gni_test (code: gni_idn_cname_to_idn_name, flags,
115 ANDERES_NAEMCHEN_IDNA ".example");
116
117 /* Test encoding errors. */
118 gni_test (code: gni_invalid_idn_1, flags, expected: "xn---.example");
119 gni_test (code: gni_invalid_idn_2, flags, expected: "xn--x.example");
120}
121}
122
123static int
124do_test (void)
125{
126 void *handle = xdlopen (filename: "tst-no-libidn2.so", RTLD_LAZY);
127 {
128 /* Verify that this replaced libidn2. */
129 void *handle2 = xdlopen (LIBIDN2_SONAME, RTLD_LAZY | RTLD_NOLOAD);
130 TEST_VERIFY (handle2 == handle);
131 xdlclose (handle: handle2);
132 }
133
134 if (setlocale (LC_CTYPE, locale: "en_US.UTF-8") == NULL)
135 FAIL_EXIT1 ("setlocale: %m");
136
137 struct resolv_test *aux = resolv_test_start
138 ((struct resolv_redirect_config)
139 {
140 .response_callback = response,
141 });
142
143 gai_tests ();
144 gni_tests ();
145
146 resolv_test_end (aux);
147 xdlclose (handle);
148 return 0;
149}
150
151#include <support/test-driver.c>
152

source code of glibc/resolv/tst-resolv-ai_idn-nolibidn2.c