From: Jan Hák Date: Tue, 9 Dec 2025 14:06:33 +0000 (+0100) Subject: kdig: replace +noidn with +[no]idnin and +[no]idnout as in dig X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62a64aa104e6494f554b00ffa5da3692ccb3299b;p=thirdparty%2Fknot-dns.git kdig: replace +noidn with +[no]idnin and +[no]idnout as in dig --- diff --git a/doc/man_kdig.rst b/doc/man_kdig.rst index d19ea9e426..198bbe43bb 100644 --- a/doc/man_kdig.rst +++ b/doc/man_kdig.rst @@ -345,12 +345,18 @@ Options **+**\ [\ **no**\ ]\ **json** Use JSON for output encoding (RFC 8427). -**+noidn** - Disable the IDN transformation to ASCII and vice versa. IDN support depends - on libidn2 availability during project building! If used in *common-settings*, - all IDN transformations are disabled. If used in the individual query *settings*, - transformation from ASCII is disabled on output for the particular query. Note - that IDN transformation does not preserve domain name letter case. +**+**\ [\ **no**\ ]\ **idnin** + Use IDN transformation (Unicode to ASCII punycode) on input query. (*) + + Note that IDN transformation does not preserve domain name letter case. + IDN support depends on libidn2 availability during project building! + +**+**\ [\ **no**\ ]\ **idnout** + Use IDN transformation (ASCII punycode to Unicode) on printed domain names. (*) + This mode is disabled by default for non-tty outputs (e.g. file, pipe). + + Note that IDN transformation does not preserve domain name letter case. + IDN support depends on libidn2 availability during project building! Notes ----- diff --git a/src/utils/kdig/kdig_params.c b/src/utils/kdig/kdig_params.c index 02eda194a1..f67aaade19 100644 --- a/src/utils/kdig/kdig_params.c +++ b/src/utils/kdig/kdig_params.c @@ -1408,11 +1408,37 @@ static int opt_noednsopt(const char *arg, void *query) return KNOT_EOK; } -static int opt_noidn(const char *arg, void *query) +static int opt_idnin(const char *arg, void *query) +{ + query_t *q = query; + + q->idn = true; + + return KNOT_EOK; +} + +static int opt_noidnin(const char *arg, void *query) { query_t *q = query; q->idn = false; + + return KNOT_EOK; +} + +static int opt_idnout(const char *arg, void *query) +{ + query_t *q = query; + + q->style.style.ascii_to_idn = name_to_idn; + + return KNOT_EOK; +} + +static int opt_noidnout(const char *arg, void *query) +{ + query_t *q = query; + q->style.style.ascii_to_idn = NULL; return KNOT_EOK; @@ -1687,8 +1713,11 @@ static const param_t kdig_opts2[] = { { "json", ARG_NONE, opt_json }, { "nojson", ARG_NONE, opt_nojson }, - /* "idn" doesn't work since it must be called before query creation. */ - { "noidn", ARG_NONE, opt_noidn }, + { "idnin", ARG_NONE, opt_idnin }, + { "noidnin", ARG_NONE, opt_noidnin }, + + { "idnout", ARG_NONE, opt_idnout }, + { "noidnout", ARG_NONE, opt_noidnout }, { NULL } }; @@ -1723,6 +1752,7 @@ query_t *query_create(const char *owner, const query_t *conf) query->flags = DEFAULT_FLAGS_DIG; query->style = DEFAULT_STYLE_DIG; query->style.style.now = knot_time(); + query->style.style.ascii_to_idn = isatty(STDOUT_FILENO) ? name_to_idn : NULL, query->idn = true; query->nsid = false; query->zoneversion = false; @@ -2014,36 +2044,11 @@ static int parse_local(const char *value, query_t *query) static int parse_name(const char *value, list_t *queries, const query_t *conf) { - query_t *query = NULL; - char *ascii_name = (char *)value; - char *fqd_name = NULL; - - if (value != NULL && value[0] != '\0') { - if (conf->idn) { - ascii_name = name_from_idn(value); - if (ascii_name == NULL) { - return KNOT_EINVAL; - } - } - - // If name is not FQDN, append trailing dot. - fqd_name = get_fqd_name(ascii_name); - - if (conf->idn) { - free(ascii_name); - } - } - - // Create new query. - query = query_create(fqd_name, conf); - - free(fqd_name); - + query_t *query = query_create(value, conf); if (query == NULL) { return KNOT_ENOMEM; } - // Add new query to the queries. add_tail(queries, (node_t *)query); return KNOT_EOK; @@ -2306,6 +2311,23 @@ void complete_queries(list_t *queries, const query_t *conf) query_t *q = (query_t *)n; query_t *q_prev = (HEAD(*queries) != n) ? (query_t *)n->prev : NULL; + // Normalize to FQDN and optionally apply IDN conversion. + if (q->owner != NULL && q->owner[0] != '\0') { + char *ascii_name = q->owner; + if (q->idn) { + ascii_name = name_from_idn(q->owner); + if (ascii_name == NULL) { + ascii_name = q->owner; + } else { + free(q->owner); + } + } + + // If name is not FQDN, append trailing dot. + q->owner = get_fqd_name(ascii_name); + free(ascii_name); + } + // Fill class number if missing. if (q->class_num < 0) { if (conf->class_num >= 0) { @@ -2430,7 +2452,8 @@ static void print_help(void) " +[no]ednsopt=CODE[:HEX] Set custom EDNS option.\n" " +[no]proxy=SADDR-DADDR Add PROXYv2 header with src and dest addresses.\n" " +[no]json Use JSON for output encoding (RFC 8427).\n" - " +noidn Disable IDN transformation.\n" + " +[no]idnin * Use IDN transformation on input.\n" + " +[no]idnout * Use IDN transformation on output.\n" "\n" " -h, --help Print the program help.\n" " -V, --version Print the program version.\n", diff --git a/src/utils/kdig/kdig_params.h b/src/utils/kdig/kdig_params.h index 24c8bc27b4..32d6a86cd0 100644 --- a/src/utils/kdig/kdig_params.h +++ b/src/utils/kdig/kdig_params.h @@ -97,7 +97,7 @@ struct query { flags_t flags; /*!< Output settings. */ style_t style; - /*!< IDN conversion. */ + /*!< Unicode to IDN input conversion. */ bool idn; /*!< Query for NSID. */ bool nsid;