Commit Graph

13721 Commits

Author SHA1 Message Date
Ondřej Surý
4716c56ebb Reset the TCP connection when garbage is received
When invalid DNS message is received, there was a handling mechanism for
DoH that would be called to return proper HTTP response.

Reuse this mechanism and reset the TCP connection when the client is
blackholed, DNS message is completely bogus or the ns_client receives
response instead of query.
2022-02-17 20:39:55 +01:00
Evan Hunt
b6d40b3c4e correct TCP error handling in dispatch and resolver
- certain TCP result codes, including ISC_R_EOF and
  ISC_R_CONNECTIONRESET, were being mapped to ISC_R_SHUTTINGDOWN
  before calling the response handler in tcp_recv_cancelall().
  the result codes should be passed through to the response handler
  without being changed.

- the response handlers, resquery_response() and req_response(), had
  code to return immediately if encountering ISC_R_EOF, but this is
  not the correct behavior; that should only happen in the case of
  ISC_R_CANCELED when it was the caller that canceled the operation

- ISC_R_CONNECTIONRESET was not being caught in rctx_dispfail().

- removed code in rctx_dispfail() to retry queries without EDNS
  when receiving ISC_R_EOF; this is now treated the same as any
  other connection failure.
2022-02-17 09:59:12 +01:00
Ondřej Surý
ee359d6ffa Update writetimeout to be T_IDLE in netmgr_test.c
Use the isc_nmhandle_setwritetimeout() function in the netmgr unit test
to allow more time for writing and reading the responses because some of
the intervals that are used in the unit tests are really small leaving a
little room for any delays.
2022-02-17 09:06:58 +01:00
Ondřej Surý
a89d9e0fa6 Add isc_nmhandle_setwritetimeout() function
In some situations (unit test and forthcoming XFR timeouts MR), we need
to modify the write timeout independently of the read timeout.  Add a
isc_nmhandle_setwritetimeout() function that could be called before
isc_nm_send() to specify a custom write timeout interval.
2022-02-17 09:06:58 +01:00
Ondřej Surý
408b362169 Add TCP, TCPDNS and TLSDNS write timer
When the outgoing TCP write buffers are full because the other party is
not reading the data, the uv_write() could wait indefinitely on the
uv_loop and never calling the callback.  Add a new write timer that uses
the `tcp-idle-timeout` value to interrupt the TCP connection when we are
not able to send data for defined period of time.
2022-02-17 09:06:58 +01:00
Ondřej Surý
cd3b58622c Add uv_tcp_close_reset compat
The uv_tcp_close_reset() function was added in libuv 1.32.0 and since we
support older libuv releases, we have to add a shim uv_tcp_close_reset()
implementation loosely based on libuv.
2022-02-17 09:06:58 +01:00
Ondřej Surý
45a73c113f Rename sock->timer to sock->read_timer
Before adding the write timer, we have to remove the generic sock->timer
to sock->read_timer.  We don't touch the function names to limit the
impact of the refactoring.
2022-02-17 09:06:58 +01:00
Evan Hunt
4444b168db negative 'blackhole' ACL match could be treated as positive
There was a bug in the checking of the "blackhole" ACL in
dns_request_create*(), causing an address to be treated as included
in the ACL if it was explicitly *excluded*. Thus, leaving "blackhole"
unset had no effect, but setting it to "none" would cause any
destination addresses to be rejected for dns_request purposes. This
would cause zone transfer requests and SOA queries to fail, among
other things.

The bug has been fixed, and "blackhole { none; };" was added to the
xfer system test as a regression test.
2022-02-16 19:05:06 -08:00
Michał Kępień
f286c845b0 Log the result of each resolver priming attempt
When a resolver priming attempt completes, the following message is
currently logged:

    resolver priming query complete

This message is identical for both successful and failed priming
attempts.  Consider the following log excerpts:

  - successful priming attempt:

        10-Feb-2022 11:33:11.272 all zones loaded
        10-Feb-2022 11:33:11.272 running
        10-Feb-2022 11:33:19.722 resolver priming query complete

  - failed priming attempt:

        10-Feb-2022 11:33:29.978 all zones loaded
        10-Feb-2022 11:33:29.978 running
        10-Feb-2022 11:33:38.432 timed out resolving '_.org/A/IN': 2001:500:9f::42#53
        10-Feb-2022 11:33:38.522 timed out resolving './NS/IN': 2001:500:9f::42#53
        10-Feb-2022 11:33:42.132 timed out resolving '_.org/A/IN': 2001:500:12::d0d#53
        10-Feb-2022 11:33:42.285 timed out resolving './NS/IN': 2001:500:12::d0d#53
        10-Feb-2022 11:33:44.685 resolver priming query complete

Include the result of each priming attempt in the relevant log message
to give the administrator better insight into named's resolver priming
process.
2022-02-16 13:26:12 +01:00
Ondřej Surý
8715be1e4b Use UV_RUNTIME_CHECK() as appropriate
Replace the RUNTIME_CHECK() calls for libuv API calls with
UV_RUNTIME_CHECK() to get more detailed error message when
something fails and should not.
2022-02-16 11:16:57 +01:00
Ondřej Surý
62e15bb06d Add UV_RUNTIME_CHECK() macro to print uv_strerror()
When libuv functions fail, they return correct return value that could
be useful for more detailed debugging.  Currently, we usually just check
whether the return value is 0 and invoke assertion error if it doesn't
throwing away the details why the call has failed.  Unfortunately, this
often happen on more exotic platforms.

Add a UV_RUNTIME_CHECK() macro that can be used to print more detailed
error message (via uv_strerror() before ending the execution of the
program abruptly with the assertion.
2022-02-16 11:16:57 +01:00
Ondřej Surý
cdce681cf7 Remove unused dns_timer API
The dns_timer API was unused, and this commit just removes it.
2022-02-16 10:49:48 +01:00
Ondřej Surý
b9cb29076f Log when starting and ending task exclusive mode
The task exclusive mode stops all processing (tasks and networking IO)
except the designated exclusive task events.  This has impact on the
operation of the server.  Add log messages indicating when we start the
exclusive mode, and when we end exclusive task mode.
2022-02-10 21:09:06 +01:00
Ondřej Surý
0893b5fb79 Assert if statistics counter underflows in the developer mode
There are reported occurences where the statitic counters underflows and
starts reporting non-sense.

Add a check for the underflow, when ``named`` is compiled in the
developer mode.
2022-02-10 17:18:09 +01:00
Ondřej Surý
0500345513 Remove unused functions from isc_thread API
The isc_thread_setaffinity call was removed in !5265 and we are not
going to restore it because it was proven that the performance is better
without it.  Additionally, remove the already disabled cpu system test.

The isc_thread_setconcurrency function is unused and also calling
pthread_setconcurrency() on Linux has no meaning, formerly it was
added because of Solaris in 2001 and it was removed when taskmgr was
refactored to run on top of netmgr in !4918.
2022-02-09 17:22:06 +01:00
Ondřej Surý
2ae84702ad Add log message when hard quota is reached in TCP accept
When isc_quota_attach_cb() API returns ISC_R_QUOTA (meaning hard quota
was reached) the accept_connection() would return without logging a
message about quota reached.

Change the connection callback to log the quota reached message.
2022-02-01 21:00:05 +01:00
Evan Hunt
e8ac7cf6ec remove error handling code around dns_dnsseckey_create()
this function can no longer fail, so error checking is not necessary.
2022-01-31 10:39:04 -08:00
Evan Hunt
d3fed6f400 update dlz_minimal.h
the addition of support for ECS client information in DLZ
modules omitted some necessary changes to build modules
in contrib.
2022-01-27 15:48:50 -08:00
Evan Hunt
737e658602 allow dns_clientinfo to store client ECS data
this brings DNS_CLIENTINFO_VERSION into line with the subscription
branch so that fixes applied to clientinfo processing can also be
applied to the main branch without diverging.
2022-01-27 13:53:59 -08:00
Petr Menšík
f00f521e9c Use detected cache line size
IBM power architecture has L1 cache line size equal to 128.  Take
advantage of that on that architecture, do not force more common value
of 64.  When it is possible to detect higher value, use that value
instead.  Keep the default to be 64.
2022-01-27 13:02:23 +01:00
Aram Sargsyan
81d3584116 Set the ephemeral certificate's "not before" a short time in the past
TLS clients can have their clock a short time in the past which will
result in not being able to validate the certificate.

Setting the "not before" property 5 minutes in the past will
accommodate with some possible clock skew across systems.
2022-01-25 09:09:35 +00:00
Aram Sargsyan
4a6c66288f Fix a memory leak in dns_dlzcreate()
dns_dlzcreate() fails to free the memory allocated for dlzname
when an error occurs.

Free dlzname's memory (acquired earlier with isc_mem_strdup())
by calling isc_mem_free() before returning an error code.
2022-01-25 08:21:50 +00:00
Aram Sargsyan
2fd967136a Improve the zones' view reverting logic when a zone is a catalog zone
When a zone is being configured with a new view, the catalog zones
structure will also be linked to that view. Later on, in case of some
error, should the zone be reverted to the previous view, the link
between the catalog zones structure and the view won't be reverted.

Change the dns_zone_setviewrevert() function so it calls
dns_zone_catz_enable() during a zone revert, which will reset the
link between `catzs` and view.
2022-01-25 08:20:52 +00:00
Aram Sargsyan
6b937ed5f6 Separate the locked parts of dns_zone_catz_enable/disable functions
Separate the locked parts of dns_zone_catz_enable() and
dns_zone_catz_disable() functions into static functions.  This will
let us perform those tasks from the other parts of the module while
the zone is locked, avoiding one pair of additional unlocking and
locking operations.
2022-01-25 08:20:52 +00:00
Ondřej Surý
b28327354d Ignore the invalid L1 cache line size returned by sysconf()
On some systems, the glibc can return 0 instead of cache-line size to
indicate the cache line sizes cannot be determined.  This is comment
from glibc source code:

    /* In general we cannot determine these values.  Therefore we
       return zero which indicates that no information is
       available.  */

As the goal of the check is to determine whether the L1 cache line size
is still 64 and we would use this value in case the sysconf() call is
not available, we can also ignore the invalid values returned by the
sysconf() call.
2022-01-22 16:59:50 +01:00
Ondřej Surý
b5e086257d Explicitly enable IPV6_V6ONLY on the netmgr sockets
Some operating systems (OpenBSD and DragonFly BSD) don't restrict the
IPv6 sockets to sending and receiving IPv6 packets only.  Explicitly
enable the IPV6_V6ONLY socket option on the IPv6 sockets to prevent
failures from using the IPv4-mapped IPv6 address.
2022-01-17 22:16:27 +01:00
Evan Hunt
be0bc24c7f add UV_ENOTSUP to isc___nm_uverr2result()
This error code is now mapped to ISC_R_FAMILYNOSUPPORT.
2022-01-17 11:45:10 +01:00
Artem Boldariev
ca9fe3559a DoH: ensure that server_send_error_response() is used properly
The server_send_error_response() function is supposed to be used only
in case of failures and never in case of legitimate requests. Ensure
that ISC_HTTP_ERROR_SUCCESS is never passed there by mistake.
2022-01-14 16:00:42 +02:00
Artem Boldariev
a38b4945c1 DoH: add bad HTTP/2 requests logging
Add some error logging when facing bad requests over HTTP/2. Log the
address and the error description.
2022-01-14 16:00:42 +02:00
Ondřej Surý
0a4e91ee47 Revert "Always enqueue isc__nm_tcp_resumeread()"
The commit itself is harmless, but at the same time it is also useless,
so we are reverting it.

This reverts commit 11c869a3d5.
2022-01-13 19:06:39 +01:00
Ondřej Surý
7370725008 Fix the UDP recvmmsg support
Previously, the netmgr/udp.c tried to detect the recvmmsg detection in
libuv with #ifdef UV_UDP_<foo> preprocessor macros.  However, because
the UV_UDP_<foo> are not preprocessor macros, but enum members, the
detection didn't work.  Because the detection didn't work, the code
didn't have access to the information when we received the final chunk
of the recvmmsg and tried to free the uvbuf every time.  Fortunately,
the isc__nm_free_uvbuf() had a kludge that detected attempt to free in
the middle of the receive buffer, so the code worked.

However, libuv 1.37.0 changed the way the recvmmsg was enabled from
implicit to explicit, and we checked for yet another enum member
presence with preprocessor macro, so in fact libuv recvmmsg support was
never enabled with libuv >= 1.37.0.

This commit changes to the preprocessor macros to autoconf checks for
declaration, so the detection now works again.  On top of that, it's now
possible to cleanup the alloc_cb and free_uvbuf functions because now,
the information whether we can or cannot free the buffer is available to
us.
2022-01-13 19:06:39 +01:00
Ondřej Surý
c960236adb Don't schedule next zone events when shutting down
When the named is shutting down, the zone event callbacks could
re-schedule the stub and refresh events leading to assertion failure.

Handle the ISC_R_SHUTTINGDOWN event state gracefully by bailing out.
2022-01-13 17:58:33 +01:00
Ondřej Surý
efca93942c Refactor zone stub, refresh and notify event callbacks
This commit cleanups the way how we handle the revent->result in the
stub_callback(), refresh_callback() and notify_done() zone callbacks.
2022-01-13 17:58:33 +01:00
Ondřej Surý
8a0c4355d2 Remove the workaround for broken handling of NOTIFY with SOA
In 2000, old BIND instances (BIND 8?) would return FORMERR if the SOA is
included in the NOTIFY.

Remove the workaround that detected the state and resent the NOTIFY
without SOA record.
2022-01-13 17:09:43 +01:00
Aram Sargsyan
6f457c5121 Generate a random serial number for 'tls ephemeral' certificates
Clients can cache the TLS certificates and refuse to accept
another one with the same serial number from the same issuer.

Generate a random serial number for the self-signed certificates
instead of using a fixed value.
2022-01-13 11:03:07 +00:00
Aram Sargsyan
0a19b5cd62 Use uncompressed point conversion form for 'tls ephemeral' ECC keys
GnuTLS, NSS, and possibly other TLS libraries currently fail to work
with compressed point conversion form supported by OpenSSL.

Use uncompressed point conversion form for better compatibility.
2022-01-13 11:03:06 +00:00
Ondřej Surý
dbd9c31354 Use ISC_R_SHUTTINGDOWN to detect netmgr shutting down
When the dispatch code was refactored in libdns, the netmgr was changed
to return ISC_R_SHUTTINGDOWN when the netmgr is shutting down, and the
ISC_R_CANCELED is now reserved only for situation where the callback was
canceled by the caller.

This change wasn't reflected in the controlconf.c channel which was
still looking for ISC_R_CANCELED as the shutdown event.
2022-01-13 09:14:12 +01:00
Ondřej Surý
58bd26b6cf Update the copyright information in all files in the repository
This commit converts the license handling to adhere to the REUSE
specification.  It specifically:

1. Adds used licnses to LICENSES/ directory

2. Add "isc" template for adding the copyright boilerplate

3. Changes all source files to include copyright and SPDX license
   header, this includes all the C sources, documentation, zone files,
   configuration files.  There are notes in the doc/dev/copyrights file
   on how to add correct headers to the new files.

4. Handle the rest that can't be modified via .reuse/dep5 file.  The
   binary (or otherwise unmodifiable) files could have license places
   next to them in <foo>.license file, but this would lead to cluttered
   repository and most of the files handled in the .reuse/dep5 file are
   system test files.
2022-01-11 09:05:02 +01:00
Ondřej Surý
11c869a3d5 Always enqueue isc__nm_tcp_resumeread()
The isc__nm_tcp_resumeread() was using maybe_enqueue function to enqueue
netmgr event which could case the read callback to be executed
immediately if there was enough data waiting in the TCP queue.

If such thing would happen, the read callback would be called before the
previous read callback was finished and the worker receive buffer would
be still marked "in use" causing a assertion failure.

This would affect only raw TCP channels, e.g. rndc and http statistics.
2022-01-06 10:34:04 -08:00
Matthijs Mekking
beeefe35c4 Fix bug introduced by #763 related to offline keys
In some cases we want to keep expired signatures. For example, if the
KSK is offline, we don't want to fall back to signing with the ZSK.
We could remove the signatures, but in any case we end up with a broken
zone.

The change made for GL #763 prevented the behavior to sign the DNSKEY
RRset with the ZSK if the KSK was offline (and signatures were expired).

The change causes the definition of "having both keys": if one key is
offline, we still consider having both keys, so we don't fallback
signing with the ZSK if KSK is offline.

That change also works the other way, if the ZSK is offline, we don't
fallback signing with the KSK.

This commit fixes that, so we only fallback signing zone RRsets with
the KSK, not signing key RRsets with the ZSK.
2022-01-06 09:32:32 +01:00
Matthijs Mekking
2d2858841a Only warn if we could not delete signature
BIND can log this warning:

    zone example.ch/IN (signed): Key example.ch/ECDSAP256SHA256/56340
      missing or inactive and has no replacement: retaining signatures.

This log can happen when BIND tries to remove signatures because the
are about to expire or to be resigned. These RRsets may be signed with
the KSK if the ZSK files has been removed from disk. When we have
created a new ZSK we can replace the signatures creeated by the KSK
with signatures from the new ZSK.

It complains about the KSK being missing or inactive, but actually it
takes the key id from the RRSIG.

The warning is logged if BIND detects the private ZSK file is missing.

The warning is logged even if we were able to delete the signature.

With the change from this commit it only logs this warning if it is not
okay to delete the signature.
2022-01-06 09:32:32 +01:00
Michał Kępień
ef625f5f06 Do not detach raw zone until dumping is complete
When the signed version of an inline-signed zone is dumped to disk, the
serial number of the unsigned version of the zone is stored in the
raw-format header so that the contents of the signed zone can be
resynchronized after named restart if the unsigned zone file is modified
while named is not running.

In order for the serial number of the unsigned zone to be determined
during the dump, zone->raw must be set to a non-NULL value.  This should
always be the case as long as the signed version of the zone is used for
anything by named.

However, a scenario exists in which the signed version of the zone has
zone->raw set to NULL while it is being dumped:

 1. Zone dump is requested; zone_dump() is invoked.

 2. Another zone dump is already in progress, so the dump gets deferred
    until I/O is available (see zonemgr_getio()).

 3. The last external reference to the zone is released.
    zone_shutdown() gets queued to the zone's task.

 4. I/O becomes available for zone dumping.  zone_gotwritehandle() gets
    queued to the zone's task.

 5. The zone's task runs zone_shutdown().  zone->raw gets set to NULL.

 6. The zone's task runs zone_gotwritehandle().  zone->raw is determined
    to be NULL, causing the serial number of the unsigned version of the
    zone to be omitted from the raw-format dump of the signed zone file.

Note that the naïve solution - deferring the dns_zone_detach() call for
zone->raw until zone_free() gets called for the secure version of the
zone - does not work because it leads to a chicken-and-egg problem when
the inline-signed zone is about to get freed: the raw zone holds a weak
reference to the secure zone and that reference does not get released
until the reference count for the raw zone reaches zero, which in turn
would not happen until all weak references to the secure zone were
released.

Defer detaching from zone->raw in zone_shutdown() if the zone is in the
process of being dumped to disk.  Ensure zone->raw gets detached from
after the dump is finished if detaching gets deferred.  Prevent zone
dumping from being requeued upon failure if the zone is in the process
of being cleaned up as it opens up possibilities for the zone->raw
reference to leak, triggering a shutdown hang.
2022-01-05 17:53:49 +01:00
Ondřej Surý
1064b2fc47 Revert "Ensure the correct ordering zone_shutdown() vs zone_gotwritehandle()"
This reverts commit cc1d4e1aa6.
2022-01-05 17:53:49 +01:00
Ondřej Surý
d026ddde82 Add unit test of aligned isc_mem functions
Add unit test that checks whether all the aligned functions work and
that allocators return memory aligned at the specified boundary.
2022-01-05 17:17:39 +01:00
Ondřej Surý
6269fce0fe Use isc_mem_get_aligned() for isc_queue and cleanup max_threads
The isc_queue_new() was using dirty tricks to allocate the head and tail
members of the struct aligned to the cacheline.  We can now use
isc_mem_get_aligned() to allocate the structure to the cacheline
directly.

Use ISC_OS_CACHELINE_SIZE (64) instead of arbitrary ALIGNMENT (128), one
cacheline size is enough to prevent false sharing.

Cleanup the unused max_threads variable - there was actually no limit on
the maximum number of threads.  This was changed a while ago.
2022-01-05 17:10:58 +01:00
Ondřej Surý
c84eb55049 Reduce the memory used by hazard pointers
The hazard pointers implementation was bit of frivolous with memory
usage allocating memory based on maximum constants rather than on the
usage.

Make the retired list bit use exactly the memory needed for specified
number of hazard pointers.  This reduced the memory used by hazard
pointers to one quarter in our specific case because we only use single
HP in the queue implementation (as opposed to allocating memory for
HP_MAX_HPS = 4).

Previously, the alignment to prevent false sharing was double the
cacheline size.  This was copied from the ConcurrencyFreaks
implementation, but one cacheline size is enough to prevent false
sharing, so we are using this now to save few bits of memory.

The top level hazard pointers and retired list arrays are now not
aligned to the cacheline size - they are read-only for the whole
life-time of the isc_hp object.  Only hp (hazard pointer) and
rl (retired list) array members are allocated aligned to the cacheline
size to avoid false sharing between threads.

Cleanup HP_MAX_HPS and HP_THRESHOLD_R constants from the paper, because
we don't use them in the code.  HP_THRESHOLD_R was 0, so the check
whether the retired list size was smaller than the value was basically a
dead code.
2022-01-05 17:10:58 +01:00
Ondřej Surý
c917a2ca88 Add isc_mem_*_aligned() function that works with aligned memory
There are some situations where having aligned allocations would be
useful, so we don't have to play tricks with padding the data to the
cacheline sizes.

Add isc_mem_{get,put,reget,putanddetach}_aligned() functions that has
alignment and size as last argument mimicking the POSIX posix_memalign()
functions on systems with jemalloc (see the documentation on
MALLOX_ALIGN() for more details).  On systems without jemalloc, those
functions are same as non-aligned variants.
2022-01-05 17:10:56 +01:00
Ondřej Surý
4f78f9d72a Add #define ISC_OS_CACHELINE_SIZE 64
Add library ctor and dtor for isc_os compilation unit which initializes
the numbers of the CPUs and also checks whether L1 cacheline size is
really 64 if the sysconf() call is available.
2022-01-05 17:07:35 +01:00
Ondřej Surý
ab5b2ef43c Add isc_refcount_destroy() for dns_zt reference counters
The zt_destroy() function was missing isc_refcount_destroy() on the two
reference counters.  The isc_refcount_destroy() adds proper memory
ordering on destroy and also ensures that the reference counters have
been zeroed before destroying the object.
2022-01-05 16:56:16 +01:00
Ondřej Surý
f326d45135 Lock view while accessing its zone table
Commit 308bc46a59 introduced a change to
the view_flushanddetach() function which makes the latter access
view->zonetable without holding view->lock.  As confirmed by TSAN, this
enables races between threads for view->zonetable accesses.

Swap the view->zonetable pointer under view lock and then detach the
local swapped dns_zt_t later when the view lock is already unlocked.

This commit also changes the dns_zt interfaces, so the setting the
zonetable "flush" flag is separate operation to dns_zt_detach,
e.g. instead of doing:

    if (view->flush) {
        dns_zt_flushanddetach(&zt);
    } else {
        dns_zt_detach(&zt);
    }

the code is now:

    if (view->flush) {
        dns_zt_flush(zt);
    }
    dns_zt_detach(&zt);

making the code more consistent with how we handle flushing and
detaching dns_zone_t pointers from the view.
2022-01-05 16:56:16 +01:00