diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 692ea5ccac..708657d58f 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -287,6 +287,7 @@ help(void) { "(+[no]tcflag))\n" " +[no]tcp (TCP mode (+[no]vc))\n" " +timeout=### (Set query timeout) [5]\n" + " +[no]tls (DNS over TLS mode)\n" " +[no]trace (Trace delegation down " "from root " "[+dnssec])\n" @@ -1726,6 +1727,13 @@ plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) { timeout = 1; } break; + case 'l': + FULLCHECK("tls"); + lookup->tls_mode = state; + if (!lookup->tcp_mode_set) { + lookup->tcp_mode = state; + } + break; case 'o': FULLCHECK("topdown"); fprintf(stderr, ";; +topdown option is deprecated"); @@ -2027,6 +2035,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, fatal("Couldn't parse port number"); } port = num; + port_set = true; return (value_from_next); case 'q': if (!config_only) { diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst index 4b1dd7a9d4..891d54e7c9 100644 --- a/bin/dig/dig.rst +++ b/bin/dig/dig.rst @@ -506,14 +506,19 @@ abbreviation is unambiguous; for example, ``+cd`` is equivalent to ``+notcflag``. This bit is ignored by the server for QUERY. ``+[no]tcp`` - This option uses [or does not use] TCP when querying name servers. The default behavior - is to use UDP unless a type ``any`` or ``ixfr=N`` query is requested, - in which case the default is TCP. AXFR queries always use TCP. + This option indicates whether to use TCP when querying name servers. + The default behavior is to use UDP unless a type ``any`` or ``ixfr=N`` + query is requested, in which case the default is TCP. AXFR queries + always use TCP. ``+timeout=T`` This option sets the timeout for a query to ``T`` seconds. The default timeout is 5 seconds. An attempt to set ``T`` to less than 1 is silently set to 1. +``+[no]tls`` + This option indicates whether to use DNS over TLS (DoT) when querying + name servers. + ``+[no]topdown`` This feature is related to ``dig +sigchase``, which is obsolete and has been removed. Use ``delv`` instead. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index add0378cb2..f4a1b905c2 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -101,6 +101,7 @@ bool check_ra = false, have_ipv4 = false, have_ipv6 = false, showsearch = false, is_dst_up = false, keep_open = false, verbose = false, yaml = false; in_port_t port = 53; +bool port_set = false; unsigned int timeout = 0; unsigned int extrabytes; isc_mem_t *mctx = NULL; @@ -678,6 +679,7 @@ make_empty_lookup(void) { looknew->nsfound = 0; looknew->tcp_mode = false; looknew->tcp_mode_set = false; + looknew->tls_mode = false; looknew->comments = true; looknew->stats = true; looknew->section_question = true; @@ -823,6 +825,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) { looknew->ns_search_only = lookold->ns_search_only; looknew->tcp_mode = lookold->tcp_mode; looknew->tcp_mode_set = lookold->tcp_mode_set; + looknew->tls_mode = lookold->tls_mode; looknew->comments = lookold->comments; looknew->stats = lookold->stats; looknew->section_question = lookold->section_question; @@ -2756,6 +2759,13 @@ start_tcp(dig_query_t *query) { debug("start_tcp(%p)", query); query_attach(query, &query->lookup->current_query); + + /* + * For TLS connections, we want to override the default + * port number. + */ + port = port_set ? port : (query->lookup->tls_mode ? 853 : 53); + result = get_address(query->servname, port, &query->sockaddr); if (result != ISC_R_SUCCESS) { /* @@ -2821,11 +2831,20 @@ start_tcp(dig_query_t *query) { REQUIRE(query != NULL); - result = isc_nm_tcpdnsconnect( - netmgr, (isc_nmiface_t *)&localaddr, - (isc_nmiface_t *)&query->sockaddr, tcp_connected, query, - local_timeout, 0); - check_result(result, "isc_nm_tcpdnsconnect"); + if (query->lookup->tls_mode) { + result = isc_nm_tlsdnsconnect( + netmgr, (isc_nmiface_t *)&localaddr, + (isc_nmiface_t *)&query->sockaddr, + tcp_connected, query, local_timeout, 0); + check_result(result, "isc_nm_tcpdnsconnect"); + } else { + result = isc_nm_tcpdnsconnect( + netmgr, (isc_nmiface_t *)&localaddr, + (isc_nmiface_t *)&query->sockaddr, + tcp_connected, query, local_timeout, 0); + check_result(result, "isc_nm_tcpdnsconnect"); + } + /* XXX: set DSCP */ } @@ -2871,6 +2890,7 @@ send_udp(dig_query_t *query) { isc_nm_send(query->handle, &r, send_done, sendquery); isc_refcount_increment0(&sendcount); + debug("sendcount=%" PRIuFAST32, isc_refcount_current(&sendcount)); /* XXX qrflag, print_query, etc... */ if (!ISC_LIST_EMPTY(query->lookup->q) && query->lookup->qr) { @@ -3176,6 +3196,7 @@ launch_next_query(dig_query_t *query) { if (keep != NULL) { query->handle = keep; } + isc_nmhandle_attach(query->handle, &query->sendhandle); isc_nm_send(query->handle, &r, send_done, sendquery); isc_refcount_increment0(&sendcount); diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 81cc2750a1..08fdf12b17 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -120,7 +120,8 @@ struct dig_lookup { tcp_keepalive, header_only, ednsneg, mapped, print_unknown_format, multiline, nottl, noclass, onesoa, use_usec, nocrypto, ttlunits, idnin, idnout, expandaaaa, qr, - setqid; /*% use a specified query ID */ + setqid, /*% use a specified query ID */ + tls_mode; /*% connect using TLS */ char textname[MXNAME]; /*% Name we're going to be * looking up */ char cmdline[MXNAME]; @@ -228,6 +229,7 @@ extern unsigned int extrabytes; extern bool check_ra, have_ipv4, have_ipv6, specified_source, usesearch, showsearch, yaml; extern in_port_t port; +extern bool port_set; extern unsigned int timeout; extern isc_mem_t *mctx; extern isc_refcount_t sendcount;