PageRenderTime 62ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/resolv/tst-resolv-ai_idn-common.c

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