"SERVFAIL)\n"
" +[no]header-only (Send query without a "
"question section)\n"
+ " +[no]https[=###] (DNS over HTTPS mode) "
+ "[/]\n"
+ " +[no]https-get (Use GET instead of "
+ "default POST method\n"
" +[no]identify (ID responders in short "
"answers)\n"
#ifdef HAVE_LIBIDN2
}
if (query->lookup->tls_mode) {
proto = "TLS";
+ } else if (query->lookup->https_mode) {
+ if (query->lookup->http_plain) {
+ proto = "HTTP";
+ } else {
+ proto = "HTTPS";
+ }
} else if (query->lookup->tcp_mode) {
proto = "TCP";
} else {
proto = "UDP";
}
- printf(";; SERVER: %s(%s) (%s)\n", fromtext, query->servname,
+ printf(";; SERVER: %s(%s) (%s)\n", fromtext, query->userarg,
proto);
time(&tnow);
(void)localtime_r(&tnow, &tmnow);
(_l >= sizeof(B) || strncasecmp(cmd, B, _l) != 0)) \
goto invalid_option; \
} while (0)
+#define FULLCHECK6(A, B, C, D, E, F) \
+ do { \
+ size_t _l = strlen(cmd); \
+ if ((_l >= sizeof(A) || strncasecmp(cmd, A, _l) != 0) && \
+ (_l >= sizeof(B) || strncasecmp(cmd, B, _l) != 0) && \
+ (_l >= sizeof(C) || strncasecmp(cmd, C, _l) != 0) && \
+ (_l >= sizeof(D) || strncasecmp(cmd, D, _l) != 0) && \
+ (_l >= sizeof(E) || strncasecmp(cmd, E, _l) != 0) && \
+ (_l >= sizeof(F) || strncasecmp(cmd, F, _l) != 0)) \
+ goto invalid_option; \
+ } while (0)
switch (cmd[0]) {
case 'a':
lookup->servfail_stops = state;
break;
case 'h':
- FULLCHECK("header-only");
- lookup->header_only = state;
+ switch (cmd[1]) {
+ case 'e': /* header-only */
+ FULLCHECK("header-only");
+ lookup->header_only = state;
+ break;
+ case 't':
+ FULLCHECK6("https", "https-get", "https-post",
+ "http-plain", "http-plain-get",
+ "http-plain-post");
+ if (lookup->https_path != NULL) {
+ isc_mem_free(mctx, lookup->https_path);
+ lookup->https_path = NULL;
+ }
+ if (!state) {
+ lookup->https_mode = false;
+ break;
+ }
+ lookup->https_mode = true;
+ if (cmd[4] == '-') {
+ lookup->http_plain = true;
+ switch (cmd[10]) {
+ case '\0':
+ FULLCHECK("http-plain");
+ break;
+ case '-':
+ switch (cmd[6]) {
+ case 'p':
+ FULLCHECK("https-plain-post");
+ break;
+ case 'g':
+ FULLCHECK("https-plain-get");
+ lookup->https_get = true;
+ break;
+ }
+ break;
+ default:
+ goto invalid_option;
+ }
+ } else {
+ switch (cmd[5]) {
+ case '\0':
+ FULLCHECK("https");
+ break;
+ case '-':
+ switch (cmd[6]) {
+ case 'p':
+ FULLCHECK("https-post");
+ break;
+ case 'g':
+ FULLCHECK("https-get");
+ lookup->https_get = true;
+ break;
+ }
+ break;
+ default:
+ goto invalid_option;
+ }
+ }
+ if (!lookup->tcp_mode_set) {
+ lookup->tcp_mode = state;
+ }
+ if (value == NULL) {
+ lookup->https_path = isc_mem_strdup(
+ mctx, DEFAULT_HTTPS_PATH);
+ } else {
+ lookup->https_path = isc_mem_strdup(mctx,
+ value);
+ }
+ break;
+ default:
+ goto invalid_option;
+ }
break;
case 'i':
switch (cmd[1]) {
default is to add a question section. The query type and query name
are ignored when this is set.
+``+[no]https[=value]``
+ This option indicates whether to use DNS-over-HTTPS (DoH) when querying
+ name servers. When this option is in use, the port number defaults to 443.
+ The HTTP POST request mode is used when sending the query.
+
+ If ``value`` is specified, it will be used as the HTTP endpoint in the
+ query URI; the default is ``/dns-query``. So, for example, ``dig
+ @example.com +https`` will use the URI ``https://example.com/dns-query``.
+
+``+[no]https-get[=value]``
+ Similar to ``+https``, except that the HTTP GET request mode is used
+ when sending the query.
+
+``+[no]https-post[=value]``
+ Same as ``+https``.
+
+``+[no]http-plain[=value]``
+ Similar to ``+https``, except that HTTP queries will be sent over a
+ non-encrypted channel. When this option is in use, the port number
+ defaults to 80 and the HTTP request mode is POST.
+
+``+[no]http-plain-get[=value]``
+ Similar to ``+http-plain``, except that the HTTP request mode is GET.
+
+``+[no]http-plain-post[=value]``
+ Same as ``+http-plain``.
+
``+[no]identify``
- This option shows [or does not show] the IP address and port number that supplied
- the answer, when the ``+short`` option is enabled. If short form
- answers are requested, the default is not to show the source address
- and port number of the server that provided the answer.
+ This option shows [or does not show] the IP address and port number that
+ supplied the answer, when the ``+short`` option is enabled. If short
+ form answers are requested, the default is not to show the source
+ address and port number of the server that provided the answer.
``+[no]idnin``
This option processes [or does not process] IDN domain names on input. This requires
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.
+ This option indicates whether to use DNS-over-TLS (DoT) when querying
+ name servers. When this option is in use, the port number defaults
+ to 853.
``+[no]topdown``
This feature is related to ``dig +sigchase``, which is obsolete and
dig_lookup_t *
make_empty_lookup(void) {
dig_lookup_t *looknew;
+#ifdef HAVE_LIBIDN2
+ bool idn_allowed = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
+#endif /* HAVE_LIBIDN2 */
debug("make_empty_lookup()");
INSIST(!free_now);
- looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
- looknew->pending = true;
- looknew->textname[0] = 0;
- looknew->cmdline[0] = 0;
- looknew->rdtype = dns_rdatatype_a;
- looknew->qrdtype = dns_rdatatype_a;
- looknew->rdclass = dns_rdataclass_in;
- looknew->rdtypeset = false;
- looknew->rdclassset = false;
- looknew->sendspace = NULL;
- looknew->sendmsg = NULL;
- looknew->name = NULL;
- looknew->oname = NULL;
- looknew->xfr_q = NULL;
- looknew->current_query = NULL;
- looknew->doing_xfr = false;
- looknew->ixfr_serial = 0;
- looknew->trace = false;
- looknew->trace_root = false;
- looknew->identify = false;
- looknew->identify_previous_line = false;
- looknew->ignore = false;
- looknew->servfail_stops = true;
- looknew->besteffort = true;
- looknew->dns64prefix = false;
- looknew->dnssec = false;
- looknew->ednsflags = 0;
- looknew->opcode = dns_opcode_query;
- looknew->expire = false;
- looknew->nsid = false;
- looknew->tcp_keepalive = false;
- looknew->padding = 0;
- looknew->header_only = false;
- looknew->sendcookie = false;
- looknew->seenbadcookie = false;
- looknew->badcookie = true;
- looknew->multiline = false;
- looknew->nottl = false;
- looknew->noclass = false;
- looknew->onesoa = false;
- looknew->use_usec = false;
- looknew->nocrypto = false;
- looknew->ttlunits = false;
- looknew->expandaaaa = false;
- looknew->qr = false;
+ looknew = isc_mem_allocate(mctx, sizeof(*looknew));
+ *looknew = (dig_lookup_t){
+ .pending = true,
+ .rdtype = dns_rdatatype_a,
+ .qrdtype = dns_rdatatype_a,
+ .rdclass = dns_rdataclass_in,
+ .servfail_stops = true,
+ .besteffort = true,
+ .opcode = dns_opcode_query,
+ .badcookie = true,
#ifdef HAVE_LIBIDN2
- looknew->idnin = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
- looknew->idnout = looknew->idnin;
-#else /* ifdef HAVE_LIBIDN2 */
- looknew->idnin = false;
- looknew->idnout = false;
+ .idnin = idn_allowed,
+ .idnout = idn_allowed,
#endif /* HAVE_LIBIDN2 */
- looknew->udpsize = -1;
- looknew->edns = -1;
- looknew->recurse = true;
- looknew->aaonly = false;
- looknew->adflag = false;
- looknew->cdflag = false;
- looknew->raflag = false;
- looknew->tcflag = false;
- looknew->print_unknown_format = false;
- looknew->zflag = false;
- looknew->setqid = false;
- looknew->qid = 0;
- looknew->ns_search_only = false;
- looknew->origin = NULL;
- looknew->tsigctx = NULL;
- looknew->querysig = NULL;
- looknew->retries = tries;
- 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;
- looknew->section_answer = true;
- looknew->section_authority = true;
- looknew->section_additional = true;
- looknew->new_search = false;
- looknew->done_as_is = false;
- looknew->need_search = false;
- looknew->ecs_addr = NULL;
- looknew->cookie = NULL;
- looknew->ednsopts = NULL;
- looknew->ednsoptscnt = 0;
- looknew->ednsneg = true;
- looknew->mapped = true;
- looknew->dscp = -1;
- looknew->rrcomments = 0;
- looknew->eoferr = 0;
+ .udpsize = -1,
+ .edns = -1,
+ .recurse = true,
+ .retries = tries,
+ .comments = true,
+ .stats = true,
+ .section_question = true,
+ .section_answer = true,
+ .section_authority = true,
+ .section_additional = true,
+ .ednsneg = true,
+ .mapped = true,
+ .dscp = -1,
+ };
+
dns_fixedname_init(&looknew->fdomain);
ISC_LINK_INIT(looknew, link);
ISC_LIST_INIT(looknew->q);
looknew->nsid = lookold->nsid;
looknew->tcp_keepalive = lookold->tcp_keepalive;
looknew->header_only = lookold->header_only;
+ looknew->https_mode = lookold->https_mode;
+ if (lookold->https_path != NULL) {
+ looknew->https_path = isc_mem_strdup(mctx, lookold->https_path);
+ }
+ looknew->https_get = lookold->https_get;
+ looknew->http_plain = lookold->http_plain;
looknew->sendcookie = lookold->sendcookie;
looknew->seenbadcookie = lookold->seenbadcookie;
looknew->badcookie = lookold->badcookie;
isc_mem_free(mctx, lookup->ednsopts);
}
+ if (lookup->https_path) {
+ isc_mem_free(mctx, lookup->https_path);
+ }
+
isc_mem_free(mctx, lookup);
}
* For TLS connections, we want to override the default
* port number.
*/
- port = port_set ? port : (query->lookup->tls_mode ? 853 : 53);
+ if (!port_set) {
+ if (query->lookup->tls_mode) {
+ port = 853;
+ } else if (query->lookup->https_mode &&
+ !query->lookup->http_plain) {
+ port = 443;
+ } else if (query->lookup->https_mode) {
+ port = 80;
+ } else {
+ port = 53;
+ }
+ }
+
+ debug("query->servname = %s\n", query->servname);
result = get_address(query->servname, port, &query->sockaddr);
if (result != ISC_R_SUCCESS) {
(isc_nmiface_t *)&query->sockaddr,
tcp_connected, query, local_timeout, 0,
query->tlsctx);
- check_result(result, "isc_nm_tcpdnsconnect");
+ check_result(result, "isc_nm_tlsdnsconnect");
+ } else if (query->lookup->https_mode) {
+ char uri[4096] = { 0 };
+ snprintf(uri, sizeof(uri), "https://%s:%u%s",
+ query->userarg, (uint16_t)port,
+ query->lookup->https_path);
+
+ if (!query->lookup->http_plain) {
+ result =
+ isc_tlsctx_createclient(&query->tlsctx);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ isc_tlsctx_enable_http2client_alpn(
+ query->tlsctx);
+ }
+
+ result = isc_nm_httpconnect(
+ netmgr, (isc_nmiface_t *)&localaddr,
+ (isc_nmiface_t *)&query->sockaddr, uri,
+ !query->lookup->https_get, tcp_connected, query,
+ query->tlsctx, local_timeout, 0);
+ check_result(result, "isc_nm_httpconnect");
} else {
result = isc_nm_tcpdnsconnect(
netmgr, (isc_nmiface_t *)&localaddr,
}
}
}
+
lookup_detach(&l);
return;
}
isc_sockaddr_t peer;
REQUIRE(DIG_VALID_QUERY(query));
- INSIST(query->readhandle != NULL);
- INSIST(handle == query->readhandle);
+ REQUIRE(query->readhandle != NULL);
INSIST(!free_now);
debug("recv_done(%p, %s, %p, %p)", handle, isc_result_totext(eresult),
default is to add a question section. The query type and query name
are ignored when this is set.
.TP
+.B \fB+[no]https[=value]\fP
+This option indicates whether to use DNS\-over\-HTTPS (DoH) when querying
+name servers. When this option is in use, the port number defaults to 443.
+The HTTP POST request mode is used when sending the query.
+.sp
+If \fBvalue\fP is specified, it will be used as the HTTP endpoint in the
+query URI; the default is \fB/dns\-query\fP\&. So, for example, \fBdig
+@example.com +https\fP will use the URI \fBhttps://example.com/dns\-query\fP\&.
+.TP
+.B \fB+[no]https\-get[=value]\fP
+Similar to \fB+https\fP, except that the HTTP GET request mode is used
+when sending the query.
+.TP
+.B \fB+[no]https\-post[=value]\fP
+Same as \fB+https\fP\&.
+.TP
+.B \fB+[no]http\-plain[=value]\fP
+Similar to \fB+https\fP, except that HTTP queries will be sent over a
+non\-encrypted channel. When this option is in use, the port number
+defaults to 80 and the HTTP request mode is POST.
+.TP
+.B \fB+[no]http\-plain\-get[=value]\fP
+Similar to \fB+http\-plain\fP, except that the HTTP request mode is GET.
+.TP
+.B \fB+[no]http\-plain\-post[=value]\fP
+Same as \fB+http\-plain\fP\&.
+.TP
.B \fB+[no]identify\fP
-This option shows [or does not show] the IP address and port number that supplied
-the answer, when the \fB+short\fP option is enabled. If short form
-answers are requested, the default is not to show the source address
-and port number of the server that provided the answer.
+This option shows [or does not show] the IP address and port number that
+supplied the answer, when the \fB+short\fP option is enabled. If short
+form answers are requested, the default is not to show the source
+address and port number of the server that provided the answer.
.TP
.B \fB+[no]idnin\fP
This option processes [or does not process] IDN domain names on input. This requires
5 seconds. An attempt to set \fBT\fP to less than 1 is silently set to 1.
.TP
.B \fB+[no]tls\fP
-This option indicates whether to use DNS over TLS (DoT) when querying
-name servers.
+This option indicates whether to use DNS\-over\-TLS (DoT) when querying
+name servers. When this option is in use, the port number defaults
+to 853.
.TP
.B \fB+[no]topdown\fP
This feature is related to \fBdig +sigchase\fP, which is obsolete and