" +[no]identify (ID responders in short "
"answers)\n"
#ifdef HAVE_LIBIDN2
- " +[no]idnin (Parse IDN names "
- "[default=on on tty])\n"
- " +[no]idnout (Convert IDN response "
- "[default=on on tty])\n"
+ " +[no]idn (convert international "
+ "domain names)\n"
#endif /* ifdef HAVE_LIBIDN2 */
" +[no]ignore (Don't revert to TCP for "
"TC responses.)\n"
break;
case 'i':
switch (cmd[1]) {
- case 'd': /* identify */
+ case 'd':
switch (cmd[2]) {
case 'e':
FULLCHECK("identify");
break;
case 'n':
switch (cmd[3]) {
- case 'i':
+ case '\0':
+ FULLCHECK("idn");
+ lookup->idnin = state;
+ lookup->idnout = state;
+ break;
+ case 'i': /* (compat) */
FULLCHECK("idnin");
-#ifndef HAVE_LIBIDN2
- if (state) {
- fprintf(stderr,
- ";; IDN input support"
- " not enabled\n");
- }
-#else /* ifndef HAVE_LIBIDN2 */
lookup->idnin = state;
-#endif /* ifndef HAVE_LIBIDN2 */
break;
- case 'o':
+ case 'o': /* (compat) */
FULLCHECK("idnout");
-#ifndef HAVE_LIBIDN2
- if (state) {
- fprintf(stderr,
- ";; IDN output support"
- " not enabled\n");
- }
-#else /* ifndef HAVE_LIBIDN2 */
lookup->idnout = state;
-#endif /* ifndef HAVE_LIBIDN2 */
break;
default:
goto invalid_option;
}
+#ifndef HAVE_LIBIDN2
+ if (state) {
+ printf(";; IDN support "
+ "is not available\n");
+ }
+#endif /* ifndef HAVE_LIBIDN2 */
break;
default:
goto invalid_option;
form answers are requested, the default is not to show the source
address and port number of the server that provided the answer.
-.. option:: +idnin, +noidnin
+.. option:: +idn, +noidn
- This option processes [or does not process] IDN domain names on input. This requires
- ``IDN SUPPORT`` to have been enabled at compile time.
+ Enable or disable IDN processing. By default IDN is enabled for
+ input query names, and for display when the output is a terminal.
- The default is to process IDN input when standard output is a tty.
- The IDN processing on input is disabled when :program:`dig` output is redirected
- to files, pipes, and other non-tty file descriptors.
-
-.. option:: +idnout, +noidnout
-
- This option converts [or does not convert] puny code on output. This requires
- ``IDN SUPPORT`` to have been enabled at compile time.
-
- The default is to process puny code on output when standard output is
- a tty. The puny code processing on output is disabled when :program:`dig` output
- is redirected to files, pipes, and other non-tty file descriptors.
+ You can also turn off :program:`dig`'s IDN processing by setting
+ the ``IDN_DISABLE`` environment variable.
.. option:: +ignore, +noignore
- This option ignores [or does not ignore] truncation in UDP responses instead of retrying with TCP. By
- default, TCP retries are performed.
+ This option ignores [or does not ignore] truncation in UDP
+ responses instead of retrying with TCP. By default, TCP retries are
+ performed.
.. option:: +keepalive, +nokeepalive
means that :program:`dig` does not print the initial query when it looks up the
NS records for ``isc.org``.
-IDN Support
-~~~~~~~~~~~
-
-If :program:`dig` has been built with IDN (internationalized domain name)
-support, it can accept and display non-ASCII domain names. :program:`dig`
-appropriately converts character encoding of a domain name before sending
-a request to a DNS server or displaying a reply from the server.
-To turn off IDN support, use the parameters
-:option:`+idnin` and :option:`+idnout`, or define the ``IDN_DISABLE`` environment
-variable.
-
Return Codes
~~~~~~~~~~~~
#ifdef HAVE_LIBIDN2
static void
-idn_locale_to_ace(const char *src, char *dst, size_t dstlen);
-static void
-idn_ace_to_locale(const char *src, char **dst);
-static isc_result_t
-idn_output_filter(isc_buffer_t *buffer, unsigned int used_org);
+idn_input(const char *src, char *dst, size_t dstlen);
#endif /* HAVE_LIBIDN2 */
isc_nmhandle_t *keep = NULL;
dig_lookup_t *
make_empty_lookup(void) {
dig_lookup_t *looknew;
+ int idnin = false, idnout = false;
+
#ifdef HAVE_LIBIDN2
- bool idn_allowed = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
+ if (getenv("IDN_DISABLE") == NULL) {
+ idnin = true;
+ idnout = isatty(1);
+ }
#endif /* HAVE_LIBIDN2 */
debug("make_empty_lookup()");
.besteffort = true,
.opcode = dns_opcode_query,
.badcookie = true,
-#ifdef HAVE_LIBIDN2
- .idnin = idn_allowed,
- .idnout = idn_allowed,
-#endif /* HAVE_LIBIDN2 */
+ .idnin = idnin,
+ .idnout = idnout,
.udpsize = -1,
.edns = -1,
.recurse = true,
textname = lookup->textname;
#ifdef HAVE_LIBIDN2
if (lookup->idnin) {
- idn_locale_to_ace(textname, idn_textname, sizeof(idn_textname));
+ idn_input(textname, idn_textname, sizeof(idn_textname));
debug("idn_textname: %s", idn_textname);
textname = idn_textname;
}
origin = lookup->origin->origin;
#ifdef HAVE_LIBIDN2
if (lookup->idnin) {
- idn_locale_to_ace(origin, idn_origin,
- sizeof(idn_origin));
+ idn_input(origin, idn_origin, sizeof(idn_origin));
debug("trying idn origin %s", idn_origin);
origin = idn_origin;
}
}
#ifdef HAVE_LIBIDN2
+
static isc_result_t
-idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) {
- char src[MXNAME], *dst = NULL;
+idn_filter(isc_buffer_t *buffer, unsigned start) {
+ char src[MXNAME];
+ char *dst = NULL;
size_t srclen, dstlen;
- isc_result_t result = ISC_R_SUCCESS;
+ int res;
/*
* Copy name from 'buffer' to 'src' and terminate it with NULL.
*/
- srclen = isc_buffer_usedlength(buffer) - used_org;
- if (srclen >= sizeof(src)) {
- warn("Input name too long to perform IDN conversion");
- goto cleanup;
- }
- memmove(src, (char *)isc_buffer_base(buffer) + used_org, srclen);
+ srclen = isc_buffer_usedlength(buffer) - start;
+ INSIST(srclen < sizeof(src));
+ memmove(src, (char *)isc_buffer_base(buffer) + start, srclen);
src[srclen] = '\0';
- systemlocale(LC_ALL);
-
/*
- * Convert 'src' to the current locale's character encoding.
+ * Try to convert the name; leave it unchanged if conversion fails.
*/
- idn_ace_to_locale(src, &dst);
-
+ systemlocale(LC_ALL);
+ res = idn2_to_unicode_8zlz(src, &dst, IDN2_NONTRANSITIONAL);
+ if (res == IDN2_DISALLOWED) {
+ res = idn2_to_unicode_8zlz(src, &dst, IDN2_TRANSITIONAL);
+ }
resetlocale(LC_ALL);
+ if (res != IDN2_OK) {
+ return (ISC_R_SUCCESS);
+ }
/*
- * Check whether the converted name will fit back into 'buffer'.
+ * Copy the converted back into 'buffer' if it fits.
*/
dstlen = strlen(dst);
- if (isc_buffer_length(buffer) < used_org + dstlen) {
- result = ISC_R_NOSPACE;
- goto cleanup;
+ if (isc_buffer_length(buffer) < start + dstlen) {
+ return (ISC_R_NOSPACE);
}
-
- /*
- * Put the converted name back into 'buffer'.
- */
isc_buffer_subtract(buffer, srclen);
memmove(isc_buffer_used(buffer), dst, dstlen);
isc_buffer_add(buffer, dstlen);
- /*
- * Clean up.
- */
-cleanup:
- if (dst != NULL) {
- idn2_free(dst);
- }
-
- return (result);
+ idn2_free(dst);
+ return (ISC_R_SUCCESS);
}
/*%
* 'dst' MUST be large enough to hold any valid domain name.
*/
static void
-idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
- const char *final_src;
- char *ascii_src;
+idn_input(const char *src, char *dst, size_t dstlen) {
+ char *ascii = NULL;
+ size_t len;
int res;
- systemlocale(LC_ALL);
-
/*
* We trust libidn2 to return an error if 'src' is too large to be a
* valid domain name.
- */
- res = idn2_to_ascii_lz(src, &ascii_src, IDN2_NONTRANSITIONAL);
- if (res == IDN2_DISALLOWED) {
- res = idn2_to_ascii_lz(src, &ascii_src, IDN2_TRANSITIONAL);
- }
- if (res != IDN2_OK) {
- fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin",
- src, idn2_strerror(res));
- }
-
- /*
- * idn2_to_ascii_lz() normalizes all strings to lower case, but we
- * generally don't want to lowercase all input strings; make sure to
- * return the original case if the two strings differ only in case.
- */
- final_src = (strcasecmp(src, ascii_src) == 0 ? src : ascii_src);
-
- (void)strlcpy(dst, final_src, dstlen);
-
- idn2_free(ascii_src);
-
- resetlocale(LC_ALL);
-}
-
-/*%
- * Convert 'src', which is an ACE string suitable for use in the DNS, into a
- * string using the current locale's character encoding, storing the conversion
- * result in 'dst'.
- *
- * The caller MUST subsequently release 'dst' using idn2_free().
- */
-static void
-idn_ace_to_locale(const char *src, char **dst) {
- char *local_src, *utf8_src;
- int res;
-
- systemlocale(LC_ALL);
-
- /*
- * We need to:
- *
- * 1) check whether 'src' is a valid IDNA2008 name,
- * 2) if it is, output it in the current locale's character encoding.
- *
- * Unlike idn2_to_ascii_*(), idn2_to_unicode_*() functions are unable
- * to perform IDNA2008 validity checks. Thus, we need to decode any
- * Punycode in 'src', check if the resulting name is a valid IDNA2008
- * name, and only once we ensure it is, output that name in the current
- * locale's character encoding.
- *
- * We could just use idn2_to_unicode_8zlz() + idn2_to_ascii_lz(), but
- * then we would not be able to universally tell invalid names and
- * character encoding errors apart (if the current locale uses ASCII
- * for character encoding, the former function would fail even for a
- * valid IDNA2008 name, as long as it contained any non-ASCII
- * character). Thus, we need to take a longer route.
*
- * First, convert 'src' to UTF-8, ignoring the current locale.
+ * If conversion fails under IDNA2008 rules, retry with transitional
+ * rules. The aim is that characters whose interpretation changed will
+ * be handled under the new rules, but we will accept characters (such
+ * as emoji) that were OK but are now forbidden.
*/
- res = idn2_to_unicode_8z8z(src, &utf8_src, 0);
- if (res != IDN2_OK) {
- fatal("Bad ACE string '%s' (%s), use +noidnout", src,
- idn2_strerror(res));
- }
-
- /*
- * Then, check whether decoded 'src' is a valid IDNA2008 name
- * and if disallowed character is found, fallback to IDNA2003.
- */
- res = idn2_to_ascii_8z(utf8_src, NULL, IDN2_NONTRANSITIONAL);
+ systemlocale(LC_ALL);
+ res = idn2_to_ascii_lz(src, &ascii, IDN2_NONTRANSITIONAL);
if (res == IDN2_DISALLOWED) {
- res = idn2_to_ascii_8z(utf8_src, NULL, IDN2_TRANSITIONAL);
- }
- if (res != IDN2_OK) {
- fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnout",
- src, idn2_strerror(res));
+ res = idn2_to_ascii_lz(src, &ascii, IDN2_TRANSITIONAL);
}
+ resetlocale(LC_ALL);
/*
- * Finally, try converting the decoded 'src' into the current locale's
- * character encoding.
+ * idn2_to_ascii_lz() normalizes all strings to lower case, but
+ * we generally don't want to lowercase all input strings; make
+ * sure to return the original case if the two strings differ
+ * only in case.
*/
- res = idn2_to_unicode_8zlz(utf8_src, &local_src, 0);
- if (res != IDN2_OK) {
- static bool warned = false;
-
- res = idn2_to_ascii_8z(utf8_src, &local_src, 0);
- if (res != IDN2_OK) {
- fatal("Cannot represent '%s' "
- "in the current locale nor ascii (%s), "
- "use +noidnout or a different locale",
- src, idn2_strerror(res));
- } else if (!warned) {
- fprintf(stderr,
- ";; Warning: cannot represent '%s' "
- "in the current locale",
- local_src);
- warned = true;
- }
+ if (res == IDN2_OK && strcasecmp(src, ascii) != 0) {
+ len = strlcpy(dst, ascii, dstlen);
+ } else {
+ len = strlcpy(dst, src, dstlen);
}
-
- /*
- * Free the interim conversion result.
- */
- idn2_free(utf8_src);
-
- *dst = local_src;
-
- resetlocale(LC_ALL);
+ INSIST(len < dstlen);
+ idn2_free(ascii);
}
+
#endif /* HAVE_LIBIDN2 */
void
#ifdef HAVE_LIBIDN2
isc_result_t result;
result = dns_name_settotextfilter(
- (active && lookup->idnout) ? idn_output_filter : NULL);
+ (active && lookup->idnout) ? idn_filter : NULL);
check_result(result, "dns_name_settotextfilter");
#else
UNUSED(lookup);
# This set of tests check the behavior of the IDNA options in "dig".
#
-# "dig" supports two IDNA-related options:
-#
-# +[no]idnin - Translates a domain name into punycode format before sending
-# the query to the server.
-#
-# Should the input name be a punycode name, "dig +idnin" will also
-# validate the punycode, rejecting it if it is invalid.
-#
-# +[no]idnout - Translates the received punycode domain names into appropriate
-# unicode characters before displaying.
-#
# The tests run "dig" against an authoritative server configured with a minimal
# root zone and nothing else. As a result, all queries will result in an
# NXDOMAIN. The server will return the qname sent, which "dig" will display
ascii_case_preservation_test() {
text="Checking valid ASCII label"
- idna_test "$text" "" LocalhosT LocalhosT.
+ idna_test "$text" "+noidn" LocalhosT LocalhosT.
idna_test "$text" "+noidnin +noidnout" LocalhosT LocalhosT.
idna_test "$text" "+noidnin +idnout" LocalhosT LocalhosT.
idna_test "$text" "+idnin +noidnout" LocalhosT LocalhosT.
idna_test "$text" "+idnin +idnout" LocalhosT LocalhosT.
+ idna_test "$text" "+idn" LocalhosT LocalhosT.
}
# Function to perform the tests if IDNA is enabled.
# Note that ASCII characters are converted to lower-case.
text="Checking valid non-ASCII label"
- idna_test "$text" "" "München" "M\195\188nchen."
+ idna_test "$text" "+noidn" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
idna_test "$text" "+idnin +idnout" "München" "münchen."
-
+ idna_test "$text" "+idn" "München" "münchen."
# Tests of transitional processing of a valid U-label
#
# under IDNA2003, go to www.fass.example but under IDNA2008 would end up at
# www.fa\195\159.example - a different web site).
#
- # BIND has adopted a hard transition, so this test checks that these
- # transitional mapping is not used. The tests are essentially the same as
- # for the valid U-label.
+ # BIND has adopted a (mostly) hard transition, so this test checks that
+ # the transitional mapping is not used for characters that are valid in
+ # IDNA2008. The tests are essentially the same as for the valid U-label.
text="Checking that non-transitional IDNA processing is used"
- idna_test "$text" "" "faß.de" "fa\195\159.de."
+ idna_test "$text" "+noidn" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
idna_test "$text" "+idnin +idnout" "faß.de" "faß.de."
+ idna_test "$text" "+idn" "faß.de" "faß.de."
# Another problem character. The final character in the first label mapped
# onto the Greek sigma character ("σ") in IDNA2003.
text="Second check that non-transitional IDNA processing is used"
- idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
+ idna_test "$text" "+noidn" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
idna_test "$text" "+idnin +idnout" "βόλος.com" "βόλος.com."
-
-
+ idna_test "$text" "+idn" "βόλος.com" "βόλος.com."
# Tests of a valid A-label (i.e. starting xn--)
#
# The "+[no]idnin" flag has no effect in these cases.
text="Checking valid A-label"
- idna_test "$text" "" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
+ idna_test "$text" "+noidn" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
+ idna_test "$text" "+idn" "xn--nxasmq6b.com" "βόλοσ.com."
# Test of valid A-label in locale that cannot display it
#
text="Checking valid A-label in C locale"
label="xn--nxasmq6b.com"
if command -v idn2 >/dev/null && ! idn2 -d "$label" >/dev/null 2>/dev/null; then
- idna_test "$text" "" "$label" "$label."
+ idna_test "$text" "+noidn" "$label" "$label."
idna_test "$text" "+noidnin +noidnout" "$label" "$label."
idna_test "$text" "+noidnin +idnout" "$label" "$label."
idna_test "$text" "+idnin +noidnout" "$label" "$label."
idna_test "$text" "+idnin +idnout" "$label" "$label."
idna_test "$text" "+noidnin +idnout" "$label" "$label."
+ idna_test "$text" "+idn" "$label" "$label."
fi
LC_ALL="${saved_LC_ALL}"
-
-
# Tests of invalid A-labels
#
# +noidnin: The label is sent as-is to the server and dig will display the
#
# +[no]idnout: If the label makes it to the server (via +noidnin), "dig"
# should report an error if +idnout is specified.
+ #
+ # +idn=lax: The label is sent and printed as-is.
# The minimum length of a punycode A-label is 7 characters. Check that
# a shorter label is detected and rejected.
text="Checking punycode label shorter than minimum valid length"
- idna_test "$text" "" "xn--xx" "xn--xx."
+ idna_test "$text" "+noidn" "xn--xx" "xn--xx."
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
- idna_fail "$text" "+noidnin +idnout" "xn--xx"
- idna_fail "$text" "+idnin +noidnout" "xn--xx"
- idna_fail "$text" "+idnin +idnout" "xn--xx"
+ idna_test "$text" "+noidnin +idnout" "xn--xx" "xn--xx."
+ idna_test "$text" "+idnin +noidnout" "xn--xx" "xn--xx."
+ idna_test "$text" "+idnin +idnout" "xn--xx" "xn--xx."
+ idna_test "$text" "+idn" "xn--xx" "xn--xx."
# Fake A-label - the string does not translate to anything.
+ # This name is a syntax error: IDNA expects be punycode-encoded
+ # non-ascii characters after the last hyphen, but they are missing
+ # in this test.
text="Checking fake A-label"
- idna_test "$text" "" "xn--ahahah" "xn--ahahah."
- idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
- idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
- idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
- idna_fail "$text" "+idnin +idnout" "xn--ahahah"
+ idna_test "$text" "+noidn" "xn--ah-" "xn--ah-."
+ idna_test "$text" "+noidnin +noidnout" "xn--ah-" "xn--ah-."
+ idna_test "$text" "+noidnin +idnout" "xn--ah-" "xn--ah-."
+ idna_test "$text" "+idnin +noidnout" "xn--ah-" "xn--ah-."
+ idna_test "$text" "+idnin +idnout" "xn--ah-" "xn--ah-."
+ idna_test "$text" "+idn" "xn--ah-" "xn--ah-."
# Too long a label. The punycode string is too long (at 64 characters).
# BIND rejects such labels: with +idnin
label="xn--xflod18hstflod18hstflod18hstflod18hstflod18hstflod18-1iejjjj"
text="Checking punycode label longer than maximum valid length"
- idna_fail "$text" "" "$label"
+ idna_fail "$text" "+noidn" "$label"
idna_fail "$text" "+noidnin +noidnout" "$label"
idna_fail "$text" "+noidnin +idnout" "$label"
idna_fail "$text" "+idnin +noidnout" "$label"
idna_fail "$text" "+idnin +idnout" "$label"
+ idna_fail "$text" "+idn" "$label"
# Tests of a valid unicode string but an invalid U-label (input)
#
- # Symbols are not valid IDNA2008 names. Check whether dig rejects them
- # when they are supplied on the command line to ensure no IDNA2003
- # fallbacks are in place.
+ # Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
#
# +noidnin: "dig" should send unicode octets to the server and display the
# returned qname in the same form.
# The +[no]idnout options should not have any effect on the test.
text="Checking invalid input U-label"
- idna_test "$text" "" "√.com" "\226\136\154.com."
+ idna_test "$text" "+noidn" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
idna_test "$text" "+idnin +noidnout" "√.com" "xn--19g.com."
idna_test "$text" "+idnin +idnout" "√.com" "√.com."
+ idna_test "$text" "+idn" "√.com" "√.com."
# Tests of a valid unicode string but an invalid U-label (output)
#
- # Symbols are not valid IDNA2008 names. Check whether dig rejects them
- # when they are received in DNS responses to ensure no IDNA2003 fallbacks
- # are in place.
- #
- # Note that "+idnin +noidnout" is not tested because libidn2 2.2.0+ parses
- # Punycode more strictly than older versions and thus dig fails with that
- # combination of options with libidn2 2.2.0+ but succeeds with older
- # versions.
+ # Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
#
# +noidnout: "dig" should send the ACE string to the server and display the
# returned qname.
# The +[no]idnin options should not have any effect on the test.
text="Checking invalid output U-label"
- idna_test "$text" "" "xn--19g" "xn--19g."
+ idna_test "$text" "+noidn" "xn--19g" "xn--19g."
idna_test "$text" "+noidnin +noidnout" "xn--19g" "xn--19g."
idna_test "$text" "+noidnin +idnout" "xn--19g" "√."
+ idna_test "$text" "+idnin +noidnout" "xn--19g" "xn--19g."
idna_test "$text" "+idnin +idnout" "xn--19g" "√."
-
+ idna_test "$text" "+idn" "xn--19g" "√."
# Test that non-letter characters are preserved in the output. When
# UseSTD3ASCIIRules are enabled, it would mangle non-letter characters like
# `_` (underscore) and `*` (wildcard.
text="Checking valid non-letter characters"
- idna_test "$text" "" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
+ idna_test "$text" "+noidn" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
+ idna_test "$text" "+idn" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
- idna_test "$text" "" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
+ idna_test "$text" "+noidn" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
+ idna_test "$text" "+idn=strict" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
+ idna_test "$text" "+idn=lax" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
}
.UNINDENT
.INDENT 0.0
.TP
-.B +idnin, +noidnin
-This option processes [or does not process] IDN domain names on input. This requires
-\fBIDN SUPPORT\fP to have been enabled at compile time.
+.B +idn, +noidn
+Enable or disable IDN processing. By default IDN is enabled for
+input query names, and for display when the output is a terminal.
.sp
-The default is to process IDN input when standard output is a tty.
-The IDN processing on input is disabled when \fBdig\fP output is redirected
-to files, pipes, and other non\-tty file descriptors.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B +idnout, +noidnout
-This option converts [or does not convert] puny code on output. This requires
-\fBIDN SUPPORT\fP to have been enabled at compile time.
-.sp
-The default is to process puny code on output when standard output is
-a tty. The puny code processing on output is disabled when \fBdig\fP output
-is redirected to files, pipes, and other non\-tty file descriptors.
+You can also turn off \fBdig\fP\(aqs IDN processing by setting
+the \fBIDN_DISABLE\fP environment variable.
.UNINDENT
.INDENT 0.0
.TP
.B +ignore, +noignore
-This option ignores [or does not ignore] truncation in UDP responses instead of retrying with TCP. By
-default, TCP retries are performed.
+This option ignores [or does not ignore] truncation in UDP
+responses instead of retrying with TCP. By default, TCP retries are
+performed.
.UNINDENT
.INDENT 0.0
.TP
each lookup. The final query has a local query option of \fI\%+qr\fP which
means that \fBdig\fP does not print the initial query when it looks up the
NS records for \fBisc.org\fP\&.
-.SH IDN SUPPORT
-.sp
-If \fBdig\fP has been built with IDN (internationalized domain name)
-support, it can accept and display non\-ASCII domain names. \fBdig\fP
-appropriately converts character encoding of a domain name before sending
-a request to a DNS server or displaying a reply from the server.
-To turn off IDN support, use the parameters
-\fI\%+idnin\fP and \fI\%+idnout\fP, or define the \fBIDN_DISABLE\fP environment
-variable.
.SH RETURN CODES
.sp
\fBdig\fP return codes are: