Commit Graph

1357 Commits

Author SHA1 Message Date
Mark Andrews
8ce163bbc5 Properly initialise local_ndata in isdotlocal in dig
Remove the trailing '\0' so that the length field of the dns_name_t
structure is correct.  The old data just happens to work with
dns_name_issubdomain but would fail with dns_name_equal.
2022-12-13 23:05:30 +00:00
Mark Andrews
b5951f0411 Add reference to +tcp for +ignore 2022-12-07 21:38:18 +00:00
Mark Andrews
8caa94bdf1 Remember that the port was set in host and nslookup
Set 'port_set = true;' so that the TCP/DOT/DOH code doesn't reset
the port when making connections.
2022-12-06 08:58:58 +11:00
Michal Nowak
afdb41a5aa Update sources to Clang 15 formatting 2022-11-29 08:54:34 +01:00
Mark Andrews
3769266318 Fix typo in dig man page '+qr' should be '+noqr'
Reported by Fabian P. Schmidt
2022-11-29 08:47:18 +11:00
Tony Finch
45b2d8938b Simplify and speed up DNS name compression
All we need for compression is a very small hash set of compression
offsets, because most of the information we need (the previously added
names) can be found in the message using the compression offsets.

This change combines dns_compress_find() and dns_compress_add() into
one function dns_compress_name() that both finds any existing suffix,
and adds any new prefix to the table. The old split led to performance
problems caused by duplicate names in the compression context.

Compression contexts are now either small or large, which the caller
chooses depending on the expected size of the message. There is no
dynamic resizing.

There is a behaviour change: compression now acts on all the labels in
each name, instead of just the last few.

A small benchmark suggests this is about 2x faster.
2022-10-17 08:45:44 +02:00
Ondřej Surý
c0598d404c Use designated initializers instead of memset()/MEM_ZERO for structs
In several places, the structures were cleaned with memset(...)) and
thus the semantic patch converted the isc_mem_get(...) to
isc_mem_getx(..., ISC_MEM_ZERO).  Use the designated initializer to
initialized the structures instead of zeroing the memory with
ISC_MEM_ZERO flag as this better matches the intended purpose.
2022-10-05 16:44:05 +02:00
Ondřej Surý
c1d26b53eb Add and use semantic patch to replace isc_mem_get/allocate+memset
Add new semantic patch to replace the straightfoward uses of:

  ptr = isc_mem_{get,allocate}(..., size);
  memset(ptr, 0, size);

with the new API call:

  ptr = isc_mem_{get,allocate}x(..., size, ISC_MEM_ZERO);
2022-10-05 16:44:05 +02:00
Ondřej Surý
3b31f7f563 Add autoconf option to enable memory leak detection in libraries
There's a known memory leak in the engine_pkcs11 at the time of writing
this and it interferes with the named ability to check for memory leaks
in the OpenSSL memory context by default.

Add an autoconf option to explicitly enable the memory leak detection,
and use it in the CI except for pkcs11 enabled builds.  When this gets
fixed in the engine_pkc11, the option can be enabled by default.
2022-09-27 17:53:04 +02:00
Ondřej Surý
d1cc847ab0 Check the libuv, OpenSSL and libxml2 memory context on exit
As we can't check the deallocations done in the library memory contexts
by default because it would always fail on non-clean exit (that happens
on error or by calling exit() early), we just want to enable the checks
to be done on normal exit.
2022-09-27 17:10:42 +02:00
Mark Andrews
805e2ba31d Add the ability to dig to specify the signing time 2022-09-26 16:28:23 +02:00
Mark Andrews
4d248ee78e Allow dig to SIG(0) sign a message 2022-09-26 16:28:23 +02:00
Ondřej Surý
f6e4f620b3 Use the semantic patch to do the unsigned -> unsigned int change
Apply the semantic patch on the whole code base to get rid of 'unsigned'
usage in favor of explicit 'unsigned int'.
2022-09-19 15:56:02 +02:00
Tony Finch
f820ef49bf More lenient IDNA processing in dig
If there are any problems with IDN processing, DiG will now quietly
handle the name as if IDN were disabled. This means that international
query names are rendered verbatim on the wire, and ACE names are
printed raw without conversion to UTF8.

If you want to check the syntax of international domain names,
use the `idn2` utility.
2022-09-12 11:40:08 +01:00
Ondřej Surý
10923f9d87 Allow fallback to IDNA2003 processing
In several cases where IDNA2008 mappings do not exist whereas IDNA2003
mappings do, dig was failing to process the suplied domain name.  Take a
backwards compatible approach, and convert the domain to IDNA2008 form,
and if that fails try the IDNA2003 conversion.
2022-09-05 10:34:49 +02:00
Evan Hunt
66eaf6bb73 quote addresses in YAML output
YAML strings should be quoted if they contain colon characters.
Since IPv6 addresses do, we now quote the query_address and
response_address strings in all YAML output.
2022-08-31 15:32:24 -07:00
Ondřej Surý
b69e783164 Update netmgr, tasks, and applications to use isc_loopmgr
Previously:

* applications were using isc_app as the base unit for running the
  application and signal handling.

* networking was handled in the netmgr layer, which would start a
  number of threads, each with a uv_loop event loop.

* task/event handling was done in the isc_task unit, which used
  netmgr event loops to run the isc_event calls.

In this refactoring:

* the network manager now uses isc_loop instead of maintaining its
  own worker threads and event loops.

* the taskmgr that manages isc_task instances now also uses isc_loopmgr,
  and every isc_task runs on a specific isc_loop bound to the specific
  thread.

* applications have been updated as necessary to use the new API.

* new ISC_LOOP_TEST macros have been added to enable unit tests to
  run isc_loop event loops. unit tests have been updated to use this
  where needed.
2022-08-26 09:09:24 +02:00
Ondřej Surý
49b149f5fd Update isc_timer to use isc_loopmgr
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
  completely removed; isc_timer objects are now directly created on the
  isc_loop event loops.

* the isc_timer API has been simplified. the "inactive" timer type has
  been removed; timers are now stopped by calling isc_timer_stop()
  instead of resetting to inactive.

* isc_manager now creates a loop manager rather than a timer manager.

* modules and applications using isc_timer have been updated to use the
  new API.
2022-08-25 17:17:07 +02:00
Artem Boldariev
bd29705a9f DIG: mark HTTP GET method in output
This commit makes dig mark the usage of HTTP(S) GET protocol usage in
its output.
2022-08-18 13:34:22 +03:00
Artem Boldariev
b2f2fed65b DIG: fix handling of +http-plain-{get, post} options
Support for parsing +http-plain-get and +http-plain-post options was
broken. This commit fixes that.
2022-08-18 13:34:21 +03:00
Aram Sargsyan
c51b052827 dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset() can not fail
Clean up dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset()
functions by making them return void, because they cannot fail.

Clean up other functions that subsequently cannot fail.
2022-08-09 08:19:51 +00:00
Aram Sargsyan
d7e5c23a81 DiG: fix lookup reference counting bug
When DiG finishes its work with a lookup (due to success or error), it
calls the clear_current_lookup() function, which decreases the lookup's
reference count. That decrease action is the counterpart of the initial
creation of the reference counter, so this function was designed in such
a way that it should decrease the reference count only once, when there
are no more active queries in the lookup.

The way it checks whether there are any active queries is by looking
at the queries list of the lookup object - if it's NULL then there are
no active queries. But that is not always true - the cancel_lookup()
function, when canceling the queries one by one, also removes them
from the lookup's list, but in NSSEARCH mode, when the queries are
working in parallel, some of those queries can be still active. And
when their recv_done() callback gets called, it sees that the lookup
has been canceled, calls clear_current_lookup(), which decreases the
reference count every time for each query that was still active
(because ISC_LIST_HEAD(lookup->q) is NULL) and results in a reference
counting error.

Fix the issue by introducing a new "cleared" property for the lookup,
which will ensure that the clear_current_lookup() function does its
job only once per lookup.
2022-08-08 10:47:44 +00:00
Aram Sargsyan
244bf0b3e4 DiG: document +qid=<num> option in the usage summary
The +qid=<num> option, which sets the outgoing query ID, was missing
from the usage summary printed using `dig -h` command.
2022-07-28 09:08:13 +00:00
Aram Sargsyan
61def2f4e3 dig +nssearch: send more queries even if setting up one of them fails
In the NSSEARCH followup lookup, when one of the queries fails to be
set up (UDP) or connected (TCP), DiG doesn't start the next query.
This is a mistake, because in NSSEARCH mode the queries are independent
and DiG shouldn't stop the lookup process just because setting up (or
connecting to) one of the name servers returns an error code in the
`udp_ready()` or `tcp_connected()` callbacks.

Write a new `nssearch_next()` function which takes care of starting the
next query in NSSEARCH mode, so it can be used in several places without
code repetition.

Make sure that the `udp_ready()` and `tcp_connected()` functions call
`nssearch_next()` in case they won't be calling `send_udp()` and
`send_tcp()` respectively, because in that case the `send_done()`
callback, which usually does the job, won't be called.

Refactor `send_done()` to use the newly written `nssearch_next()`
function.
2022-07-22 09:37:05 +00:00
Aram Sargsyan
98da5129a5 dig +nssearch: send more queries even if sending the previous one fails
In the NSSEARCH followup lookup, when one of the queries fails to be
sent, DiG doesn't start the next query. This is a mistake, because in
NSSEARCH mode the queries are independent and DiG shouldn't stop the
lookup process just because sending a query to one of the name servers
returns an error code.

Restructure the `send_done()` function to unconditionally send the next
query in NSSEARCH mode, if it exists.
2022-07-22 09:26:25 +00:00
Aram Sargsyan
8611aa759f DiG: use the same retry and fail-over logic for different failure types
DiG implements different logic in the `recv_done()` callback function
when processing a failure:

1. For a timed-out query it applies the "retries" logic first, then,
   when it fails, fail-overs to the next server.

2. For an EOF (end-of-file, or unexpected disconnect) error it tries to
   make a single retry attempt (even if the user has requested more
   retries), then, when it fails, fail-overs to the next server.

3. For other types of failures, DiG does not apply the "retries" logic,
   and tries to fail-over to the next servers (again, even if the user
   has requested to make retries).

Simplify the logic and apply the same logic (1) of first retries, and
then fail-over, for different types of failures in `recv_done()`.
2022-07-22 08:35:35 +00:00
Aram Sargsyan
99085c587e Fix DiG query retry and fail-over bug
When the `send_done()` callback function gets called with a failure
result code, DiG erroneously cancels the lookup.

Stop canceling the lookup and give DiG a chance to retry the failed
query, or fail-over to another server, using the logic implemented in
the `recv_done()` callback function.
2022-07-22 08:35:35 +00:00
Aram Sargsyan
060feeb454 Fix DiG UDP query retry and fail-over bug
When the `udp_ready()` callback function gets called with a failure
result code, DiG erroneously cancels the lookup.

Copy the logic behind `tcp_connected()` callback function into
`udp_ready()` so that DiG will now retry the failed query (if retries
are enabled) and then, if it fails again, it will fail-over to the next
server in the list, which synchronizes the behavior between TCP and UDP
modes.

Also, `udp_ready()` was calling `lookup_detach()` without calling
`lookup_attach()` first, but the issue was masked behind the fact
that `clear_current_lookup()` wasn't being called when needed, and
`lookup_detach()` was compensating for that. This also has been fixed.
2022-07-22 08:34:32 +00:00
Ondřej Surý
deae974366 Directly cause assertion failure on pthreads primitives failure
Instead of returning error values from isc_rwlock_*(), isc_mutex_*(),
and isc_condition_*() macros/functions and subsequently carrying out
runtime assertion checks on the return values in the calling code,
trigger assertion failures directly in those macros/functions whenever
any pthread function returns an error, as there is no point in
continuing execution in such a case anyway.
2022-07-13 13:19:32 +02:00
Aram Sargsyan
1290863c22 Fix a crash in dig NS search mode
In special NS search mode, after the initial lookup, dig starts the
followup lookup with discovered NS servers in the queries list. If one
of those queries then fail, dig, as usual, tries to start the next query
in the list, which results in a crash, because the NS search mode is
special in a way that the queries are running in parallel, so the next
query is usually already started.

Apply some special logic in `recv_done()` function to deal with the
described situation when handling the query result for the NS search
mode. Particularly, print a warning message for the failed query,
and do not try to start the next query in the list. Also, set a non-zero
exit code if all the queries in the followup lookup fail.
2022-06-14 13:20:25 +00:00
Aram Sargsyan
b7cb73160b Remove unneded NULL-checking
Fix an issue reported by Coverity by removing the unneded check.

    *** CID 352554:  Null pointer dereferences  (REVERSE_INULL)
    /bin/dig/dighost.c: 3056 in start_tcp()
    3050
    3051     	if (ISC_LINK_LINKED(query, link)) {
    3052     		next = ISC_LIST_NEXT(query, link);
    3053     	} else {
    3054     		next = NULL;
    3055     	}
    >>>    CID 352554:  Null pointer dereferences  (REVERSE_INULL)
    >>>    Null-checking "connectquery" suggests that it may be null, but it
           has already been dereferenced on all paths leading to the check.
    3056     	if (connectquery != NULL) {
    3057     		query_detach(&connectquery);
    3058     	}
    3059     	query_detach(&query);
    3060     	if (next == NULL) {
    3061     		clear_current_lookup();
2022-06-07 09:51:47 +00:00
Tony Finch
e37b782c1a DNS name compression does not depend on the EDNS version
There was a proposal in the late 1990s that it might, but it turned
out to be unworkable. See RFC 6891, Extension Mechanisms for
DNS (EDNS(0)), section 5, Extended Label Types.

The remnants of the code that supported this in BIND are redundant.
2022-06-01 13:00:40 +01:00
Ondřej Surý
1fe391fd40 Make all tasks to be bound to a thread
Previously, tasks could be created either unbound or bound to a specific
thread (worker loop).  The unbound tasks would be assigned to a random
thread every time isc_task_send() was called.  Because there's no logic
that would assign the task to the least busy worker, this just creates
unpredictability.  Instead of random assignment, bind all the previously
unbound tasks to worker 0, which is guaranteed to exist.
2022-05-25 16:04:51 +02:00
Artem Boldariev
095b608412 CID 352849: refactor get_create_tls_context() within dighost.c
This commit removes dead code from cleanup handling part of the
get_create_tls_context().

In particular, currently:

* there is no way 'found_ctx' might equal 'ctx';
* there is no way 'session_cache' might equal a non-NULL value while
cleaning up after a TLS initialisation error.
2022-05-25 12:38:38 +03:00
Artem Boldariev
90c52ca12b Dig: Do not call isc_nm_cancelread() for HTTP sockets
This commit ensures that isc_nm_cancelread() is not called from within
dig code for HTTP sockets, as these lack its implementation.

It does not have much sense to have it due to transactional nature of
HTTP.

Every HTTP request-response pair is represented by a virtual socket,
where read callback is called only when full DNS message is received
or when an error code is being passed there. That is, there is nothing
to cancel at the time of the call.
2022-05-20 20:18:40 +03:00
Artem Boldariev
86465c1dac DoT: implement TLS client session resumption
This commit extends DoT code with TLS client session resumption
support implemented on top of the TLS client session cache.
2022-05-20 20:17:48 +03:00
Artem Boldariev
90bc13a5d5 TLS stream/DoH: implement TLS client session resumption
This commit extends TLS stream code and DoH code with TLS client
session resumption support implemented on top of the TLS client
session cache.
2022-05-20 20:17:45 +03:00
Artem Boldariev
987892d113 Extend TLS context cache with TLS client session cache
This commit extends TLS context cache with TLS client session cache so
that an associated session cache can be stored alongside the TLS
context within the context cache.
2022-05-20 20:13:20 +03:00
Ondřej Surý
33ba0057a7 Cleanup dns_message_gettemp*() functions - they cannot fail
The dns_message_gettempname(), dns_message_gettemprdata(),
dns_message_gettemprdataset(), and dns_message_gettemprdatalist() always
succeeds because the memory allocation cannot fail now.  Change the API
to return void and cleanup all the use of aforementioned functions.
2022-05-17 12:39:25 +02:00
Mark Andrews
30f3d51368 Remove unnecessary NULL pointer check
3034                next = ISC_LIST_NEXT(query, link);
    3035        } else {
    3036                next = NULL;
    3037        }

    CID 352554 (#1 of 1): Dereference before null check (REVERSE_INULL)
    check_after_deref: Null-checking connectquery suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
    3038        if (connectquery != NULL) {
    3039                query_detach(&connectquery);
    3040        }
2022-05-02 13:39:25 +00:00
Petr Menšík
59132bd3ec Initialize printed buffer
- var_decl: Declaring variable "tbuf" without initializer
- assign: Assigning: "target.base" = "tbuf", which points to
  uninitialized data
- assign: Assigning: "r.base" = "target.base", which points to
  uninitialized data

I expect it would correctly initialize length always. Add simple
initialization to silent coverity.
2022-04-29 11:22:40 +10:00
Artem Boldariev
5db2838abb Dig: do not hang on TLS context creation errors
There was a query_detach() call missing in dig, which could lead to
dig hanging on TLS context creation errors. This commit fixes.

The error was introduced because the Strict TLS implementation was
initially made over an older version of the code, where this extra
query_detach() call was not needed.
2022-04-27 16:28:23 +03:00
Petr Špaček
ac0c2378ca Add hyperlinks to dig/mdig/delv +options 2022-04-26 12:43:13 +02:00
Petr Špaček
0342dddce7 Split negative and positive dig/mdig/delv options to support Sphinx 1.4.9
Man pages for dig/mdig/delv used `.. option:: +[no]bla` to describe two
options at once, and very old Sphinx does not support that [] in option
names.

Solution is to split negative and positive options into `+bla, +nobla`
form. In the end it improves readability because it transforms hard to
read strings with double brackets from
`+[no]subnet=addr[/prefix-length]` to
`+subnet=addr[/prefix-length], +nosubnet`.

As a side-effect it also allows easier linking to dig/mdig/delv options
using their name directly instead of always overriding the link target
to `+[no]bla` form.

Transformation was done using regex:
    s/:: +\[no\]\(.*\)/:: +\1, +no\1
... and manual review around occurences matching regex
    +no.*=

Fixes: #3301
2022-04-26 12:43:09 +02:00
Evan Hunt
4eee6460ff ensure dig sets exitcode after local UDP connection failure
dig previously set an exit code of 9 when a TCP connection failed
or when a UDP connection timed out, but when the server address is
localhost it's possible for a UDP query to fail with ISC_R_CONNREFUSED.
that code path didn't update the exit code, causing dig to exit with
status 0. we now set the exit code to 9 in this failure case.
2022-04-15 10:32:31 -07:00
Evan Hunt
6bf8535542 detach unfinished query when canceling
when a query was canceled while still in the process of connecting,
tcp_connected() and udp_ready() didn't detach the query object.
2022-04-14 09:34:40 +00:00
Aram Sargsyan
b944bf4120 Unify dig +nssearch next query starting code for TCP and UDP protocols
In `+nssearch` mode `dig` starts the next query of the followup lookup
using `start_udp()` or `start_tcp()` calls without waiting for the
previous query to complete.

In UDP mode that happens in the `send_done()` callback of the previous
query, but in TCP mode that happens in the `start_tcp()` call of the
previous query (recursion) which doesn't work because `start_tcp()`
attaches the `lookup->current_query` to the query it is starting, so a
recursive call will result in an assertion failure.

Make the TCP mode to start the next query in `send_done()`, just like in
the UDP mode. During that time the `lookup->current_query` is already
detached by the `tcp_connected()`/`udp_ready()` callbacks.
2022-04-14 09:34:40 +00:00
Aram Sargsyan
5b2b3e589c Fix using unset pointer when printing a debug message in dighost.c
The used `query->handle` is always `NULL` at this point.

Change the code to use `handle` instead.
2022-04-05 11:20:42 +00:00
Aram Sargsyan
2771a5b64d Add a missing clear_current_lookup() call in recv_done()
The error code path handling the `ISC_R_CANCELED` code lacks a
`clear_current_lookup()` call, without which dig hangs indefinitely
when handling the error.

Add the missing call to account for all references of the lookup so
it can be destroyed.
2022-04-05 11:20:42 +00:00
Aram Sargsyan
f831e758d1 When using +qr in dig print the data of the current query
In `send_udp()` and `launch_next_query()` functions, when calling
`dighost_printmessage()` to print detailed information about the
sent query, dig always prints the data of the first query in the
lookup's queries list.

The first query in the list can be already finished, having its handles
freed, and accessing this information results in assertion failure.

Print the current query's information instead.
2022-04-05 11:20:41 +00:00