Commit Graph
7881 Commits
Author SHA1 Message Date
Mark Andrews bde5c7632a Always check the return from isc_refcount_decrement.
Created isc_refcount_decrement_expect macro to test conditionally
the return value to ensure it is in expected range.  Converted
unchecked isc_refcount_decrement to use isc_refcount_decrement_expect.
Converted INSIST(isc_refcount_decrement()...) to isc_refcount_decrement_expect.
2020-07-31 10:15:44 +10:00
Michał Kępień 953d704bd2 Fix idle timeout for connected TCP sockets
When named acting as a resolver connects to an authoritative server over
TCP, it sets the idle timeout for that connection to 20 seconds.  This
fixed timeout was picked back when the default processing timeout for
each client query was hardcoded to 30 seconds.  Commit
000a8970f8 made this processing timeout
configurable through "resolver-query-timeout" and decreased its default
value to 10 seconds, but the idle TCP timeout was not adjusted to
reflect that change.  As a result, with the current defaults in effect,
a single hung TCP connection will consistently cause the resolution
process for a given query to time out.

Set the idle timeout for connected TCP sockets to half of the client
query processing timeout configured for a resolver.  This allows named
to handle hung TCP connections more robustly and prevents the timeout
mismatch issue from resurfacing in the future if the default is ever
changed again.
2020-07-30 10:58:39 +02:00
Diego FronzaandEvan Hunt c2928c2ed4 Fix rpz wildcard name matching
Whenever an exact match is found by dns_rbt_findnode(),
the highest level node in the chain will not be put into
chain->levels[] array, but instead the chain->end
pointer will be adjusted to point to that node.

Suppose we have the following entries in a rpz zone:
example.com     CNAME rpz-passthru.
*.example.com   CNAME rpz-passthru.

A query for www.example.com would result in the
following chain object returned by dns_rbt_findnode():

chain->level_count = 2
chain->level_matches = 2
chain->levels[0] = .
chain->levels[1] = example.com
chain->levels[2] = NULL
chain->end = www

Since exact matches only care for testing rpz set bits,
we need to test for rpz wild bits through iterating the nodechain, and
that includes testing the rpz wild bits in the highest level node found.

In the case of an exact match, chain->levels[chain->level_matches]
will be NULL, to address that we must use chain->end as the start point,
then iterate over the remaining levels in the chain.
2020-07-24 11:34:40 -07:00
Mark Andrews 78db46d746 Check walking the hip rendezvous servers.
Also fixes extraneous white space at end of record when
there are no rendezvous servers.
2020-07-24 04:15:56 +00:00
Ondřej Surý a9182c89a6 Change the dns_name hashing to use 32-bit values
Change the dns_hash_name() and dns_hash_fullname() functions to use
isc_hash32() as the maximum hashtable size in rbt is 0..UINT32_MAX
large.
2020-07-21 08:44:26 +02:00
Ondřej Surý e24bc324b4 Fix the rbt hashtable and grow it when setting max-cache-size
There were several problems with rbt hashtable implementation:

1. Our internal hashing function returns uint64_t value, but it was
   silently truncated to unsigned int in dns_name_hash() and
   dns_name_fullhash() functions.  As the SipHash 2-4 higher bits are
   more random, we need to use the upper half of the return value.

2. The hashtable implementation in rbt.c was using modulo to pick the
   slot number for the hash table.  This has several problems because
   modulo is: a) slow, b) oblivious to patterns in the input data.  This
   could lead to very uneven distribution of the hashed data in the
   hashtable.  Combined with the single-linked lists we use, it could
   really hog-down the lookup and removal of the nodes from the rbt
   tree[a].  The Fibonacci Hashing is much better fit for the hashtable
   function here.  For longer description, read "Fibonacci Hashing: The
   Optimization that the World Forgot"[b] or just look at the Linux
   kernel.  Also this will make Diego very happy :).

3. The hashtable would rehash every time the number of nodes in the rbt
   tree would exceed 3 * (hashtable size).  The overcommit will make the
   uneven distribution in the hashtable even worse, but the main problem
   lies in the rehashing - every time the database grows beyond the
   limit, each subsequent rehashing will be much slower.  The mitigation
   here is letting the rbt know how big the cache can grown and
   pre-allocate the hashtable to be big enough to actually never need to
   rehash.  This will consume more memory at the start, but since the
   size of the hashtable is capped to `1 << 32` (e.g. 4 mio entries), it
   will only consume maximum of 32GB of memory for hashtable in the
   worst case (and max-cache-size would need to be set to more than
   4TB).  Calling the dns_db_adjusthashsize() will also cap the maximum
   size of the hashtable to the pre-computed number of bits, so it won't
   try to consume more gigabytes of memory than available for the
   database.

   FIXME: What is the average size of the rbt node that gets hashed?  I
   chose the pagesize (4k) as initial value to precompute the size of
   the hashtable, but the value is based on feeling and not any real
   data.

For future work, there are more places where we use result of the hash
value modulo some small number and that would benefit from Fibonacci
Hashing to get better distribution.

Notes:
a. A doubly linked list should be used here to speedup the removal of
   the entries from the hashtable.
b. https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/
2020-07-21 08:44:26 +02:00
Michał Kępień 97a2733ef9 Update library API versions 2020-07-15 22:54:13 +02:00
Matthijs Mekking e645d2ef1e Check return value of dst_key_getbool()
Fix Coverity CHECKED_RETURN reports for dst_key_getbool().  In most
cases we do not really care about its return value, but it is prudent
to check it.

In one case, where a dst_key_getbool() error should be treated
identically as success, cast the return value to void and add a relevant
comment.
2020-07-14 12:53:54 +00:00
Mark Andrews 488eef63ca Only call gsskrb5_register_acceptor_identity if we have gssapi_krb5.h. 2020-07-14 08:55:13 +10:00
Mark Andrews 827746e89b Assert tsigout is non-NULL 2020-07-13 02:26:06 +00:00
Mark Andrews 9499adeb5e check returns from inet_pton() 2020-07-13 00:31:29 +00:00
Michał Kępień 53120279b5 Fix locking for LMDB 0.9.26
When "rndc reconfig" is run, named first configures a fresh set of views
and then tears down the old views.  Consider what happens for a single
view with LMDB enabled; "envA" is the pointer to the LMDB environment
used by the original/old version of the view, "envB" is the pointer to
the same LMDB environment used by the new version of that view:

 1. mdb_env_open(envA) is called when the view is first created.
 2. "rndc reconfig" is called.
 3. mdb_env_open(envB) is called for the new instance of the view.
 4. mdb_env_close(envA) is called for the old instance of the view.

This seems to have worked so far.  However, an upstream change [1] in
LMDB which will be part of its 0.9.26 release prevents the above
sequence of calls from working as intended because the locktable mutexes
will now get destroyed by the mdb_env_close() call in step 4 above,
causing any subsequent mdb_txn_begin() calls to fail (because all of the
above steps are happening within a single named process).

Preventing the above scenario from happening would require either
redesigning the way we use LMDB in BIND, which is not something we can
easily backport, or redesigning the way BIND carries out its
reconfiguration process, which would be an even more severe change.

To work around the problem, set MDB_NOLOCK when calling mdb_env_open()
to stop LMDB from controlling concurrent access to the database and do
the necessary locking in named instead.  Reuse the view->new_zone_lock
mutex for this purpose to prevent the need for modifying struct dns_view
(which would necessitate library API version bumps).  Drop use of
MDB_NOTLS as it is made redundant by MDB_NOLOCK: MDB_NOTLS only affects
where LMDB reader locktable slots are stored while MDB_NOLOCK prevents
the reader locktable from being used altogether.

[1] https://git.openldap.org/openldap/openldap/-/commit/2fd44e325195ae81664eb5dc36e7d265927c5ebc
2020-07-10 11:29:18 +02:00
Mark Andrews 092a159dcd Adjust range limit of unknown meta types 2020-07-08 02:04:16 +00:00
Ondřej SurýandMark Andrews 81d4230e60 Update STALE and ANCIENT header attributes atomically
The ThreadSanitizer found a data race when updating the stale header.
Instead of trying to acquire the write lock and failing occasionally
which would skew the statistics, the dns_rdatasetheader_t.attributes
field has been promoted to use stdatomics.  Updating the attributes in
the mark_header_ancient() and mark_header_stale() now uses the cmpxchg
to update the attributes forfeiting the need to hold the write lock on
the tree.  Please note that mark_header_ancient() still needs to hold
the lock because .dirty is being updated in the same go.
2020-07-08 10:50:52 +10:00
Mark Andrews 2fa2dbd5fb remove redundant rctx != NULL check 2020-07-05 23:52:19 +00:00
Evan Hunt 16e14353b1 add "primaries" as a synonym for "masters" in named.conf
as "type primary" is preferred over "type master" now, it makes
sense to make "primaries" available as a synonym too.

added a correctness check to ensure "primaries" and "masters"
cannot both be used in the same zone.
2020-07-01 11:11:34 -07:00
Witold KręcickiandOndřej Surý c8f2d55acf rbtdb: cleanup_dead_nodes should ignore alive nodes on the deadlist 2020-07-01 15:11:07 +02:00
Witold KręcickiandOndřej Surý b4f3fafcff Fix assertion failure during startup when the server is under load.
When we're coming back from recursion fetch_callback does not accept
DNS_R_NXDOMAIN as an rcode - query_gotanswer calls query_nxdomain in
which an assertion fails on qctx->is_zone. Yet, under some
circumstances, qname minimization will return an DNS_R_NXDOMAIN - when
root zone mirror is not yet loaded. The fix changes the DNS_R_NXDOMAIN
answer to DNS_R_SERVFAIL.
2020-07-01 12:25:36 +02:00
Matthijs Mekking 19ce9ec1d4 Output rndc dnssec -status
Implement the 'rndc dnssec -status' command that will output
some information about the key states, such as which policy is
used for the zone, what keys are in use, and when rollover is
scheduled.

Add loose testing in the kasp system test, the actual times are
already tested via key file inspection.
2020-06-30 09:51:04 +02:00
Matthijs Mekking 9e03f8e8fe Move dst key printtime in separate function
I'd like to use the same functionality (pretty print the datetime
of keytime metadata) in the 'rndc dnssec -status' command.  So it is
better that this logic is done in a separate function.

Since the stdtime.c code have differernt files for unix and win32,
I think the "#ifdef WIN32" define can be dropped.
2020-06-30 09:51:04 +02:00
Matthijs Mekking a47192ed5b kasp tests: fix wait for reconfig done
The wait until zones are signed after rndc reconfig is broken
because the zones are already signed before the reconfig.  Fix
by having a different way to ensure the signing of the zone is
complete.  This does require a call to the "wait_for_done_signing"
function after each "check_keys" call after the ns6 reconfig.

The "wait_for_done_signing" looks for a (newly added) debug log
message that named will output if it is done signing with a certain
key.
2020-06-26 08:43:45 +00:00
Evan Hunt a8baf79e33 append "0" to IPv6 addresses ending in "::" when printing YAML
such addresses broke some YAML parsers.
2020-06-25 16:42:13 -07:00
Mark AndrewsandMatthijs Mekking d475f3aeed The validator could fail when select_signing_key/get_dst_key failed
to select the signing key because the algorithm was not supported
and the loop was prematurely aborted.
2020-06-25 13:43:45 +02:00
Mark Andrews ee135d8946 Remove now redundant check for state != NULL 2020-06-25 12:04:36 +10:00
Tony FinchandMark Andrews 7c07129a51 Fix rndc dnstap -roll N
The `rndc` argument was always overridden by the static configuration,
because the logic for handling the number of dnstap files to retain
was both backwards and a bit redundant.
2020-06-23 20:20:39 +10:00
Mark AndrewsandOndřej Surý 67c8f7329d Address race between zone_maintenance and dns_zone_setview_helper
There was a possible NULL dereference due to data race between accessing
zone->view and zone->view->adb.
2020-06-22 12:20:51 +02:00
Michał Kępień a8bc003d1b Update library API versions 2020-06-18 10:03:05 +02:00
Mark AndrewsandMichał Kępień 0854f63114 Remove INSIST from from new_reference
RBTDB node can now appear on the deadnodes lists following the changes
to decrement_reference in 176b23b6cd to
defer checking of node->down when the tree write lock is not held.  The
node should be unlinked instead.
2020-06-18 09:59:20 +02:00
Mark Andrews ff4fc3f8dc val->keynode is no longer needed 2020-06-11 16:03:11 +10:00
Mark Andrews e5b2eca1d3 The dsset returned by dns_keynode_dsset needs to be thread safe.
- clone keynode->dsset rather than return a pointer so that thread
  use is independent of each other.
- hold a reference to the dsset (keynode) so it can't be deleted
  while in use.
- create a new keynode when removing DS records so that dangling
  pointers to the deleted records will not occur.
- use a rwlock when accessing the rdatalist to prevent instabilities
  when DS records are added.
2020-06-11 16:02:09 +10:00
Evan Hunt 364b349ad2 ensure clientstr is null-terminated 2020-06-05 18:56:40 -07:00
Witold KręcickiandOndřej Surý 175c4d9055 Fix a data access race in resolver
We were passing client address to dns_resolver_createfetch as a pointer
and it was saved as a pointer. The client (with its address) could be
gone before the fetch is finished, and in a very odd scenario
log_formerr would call isc_sockaddr_format() which first checks if the
address family is valid (and at this point it still is), then the
sockaddr is cleared, and then isc_netaddr_fromsockaddr is called which
fails an assertion as the address family is now invalid.
2020-06-05 16:06:42 +02:00
Michal NowakandMichał Kępień 5bbc6dd7f1 Fix "make dist"
Make various adjustments necessary to enable "make dist" to build a BIND
source tarball whose contents are complete enough to build binaries, run
unit & system tests, and generate documentation on Unix systems.

Known outstanding issues:

  - "make distcheck" does not work yet.
  - Tests do not work for out-of-tree source-tarball-based builds.
  - Source tarballs are not complete enough for building on Windows.

All of the above will be addressed in due course.
2020-06-05 13:19:49 +02:00
Mark Andrews 0ec77c2b92 Add +yaml support for EDE 2020-06-05 08:34:51 +10:00
Mark AndrewsandOndřej Surý fd96a41868 Verify the question section when transfering in.
There was a case where an primary server sent a response
on the wrong TCP connection and failure to check the question
section resulted in a truncated zone being served.
2020-06-04 16:10:41 +02:00
Mark AndrewsandOndřej Surý 35a58d30c9 Reject primary zones with an DS record at the zone apex.
DS records only belong at delegation points and if present
at the zone apex are invariably the result of administrative
errors.  Additionally they can't be queried for with modern
resolvers as the parent servers will be queried.
2020-06-04 16:00:33 +02:00
Michal Nowak eddece7841 Associate unit test data dir with a more specific variable
Having 'TESTS', the Automake variable and 'TESTS' the unit test data dir
seems confusing, lets rename the latter to to 'TESTS_DIR'.
2020-06-04 12:56:57 +02:00
Matthijs Mekking e71d60299f Retire predecessor when creating successor
When creating the successor, the current active key (predecessor)
should change its goal state to HIDDEN.

Also add two useful debug logs in the keymgr_key_rollover function.
2020-06-02 10:01:28 +02:00
Matthijs Mekking c08d0f7dd6 If prepub > retire, prepub now
Catch a case where if the prepublication time of the successor key
is later than the retire time of the predecessor. If that is the
case we should prepublish as soon as possible, a.k.a. now.
2020-06-02 10:00:53 +02:00
Matthijs Mekking bcf8192438 Put new key rollover logic in separate function
The `dns_keymgr_run()` function became quite long, put the logic
that looks if a new key needs to be created (start a key rollover)
in a separate function.
2020-06-02 10:00:53 +02:00
Matthijs Mekking 0d578097ef Fix bug in keymgr_key_has_successor
The logic in `keymgr_key_has_successor(key, keyring)` is flawed, it
returns true if there is any key in the keyring that has a successor,
while what we really want here is to make sure that the given key
has a successor in the given keyring.

Rather than relying on `keymgr_key_exists_with_state`, walk the
list of keys in the keyring and check if the key is a successor of
the given predecessor key.
2020-06-02 10:00:51 +02:00
Matthijs Mekking e233433772 Test keytimes on CSK rollover
This improves keytime testing on CSK rollover.  It now
tests for specific times, and also tests for SyncPublish and
Removed keytimes.

Since an "active key" for ZSK and KSK means something
different, this makes it tricky to decide when a CSK is
active. An "active key" intuitively means the key is signing
so we say a CSK is active when it is creating zone signatures.

This change means a lot of timings for the CSK rollover tests
need to be adjusted.

The keymgr code needs a slight change on calculating the
prepublication time: For a KSK we need to include the parent
registration delay, but for CSK we look at the zone signing
property and stick with the ZSK prepublication calculation.
2020-06-02 09:14:18 +02:00
Matthijs Mekking 50bbbb76a8 kasp: registration delay adjustments
Registration delay is not part of the Iret retire interval, thus
removed from the calculation when setting the Delete time metadata.

Include the registration delay in prepublication time, because
we need to prepublish the key sooner than just the Ipub
publication interval.
2020-06-02 09:14:15 +02:00
Matthijs Mekking 30cb5c97c2 Set SyncPublish on keys
Set the SyncPublish metadata on keys that don't have them yet.
2020-06-02 09:14:09 +02:00
Matthijs Mekking 18dc27afd3 Set keytimes appropriately when using kasp
While kasp relies on key states to determine when a key needs to
be published or be used for signing, the keytimes are used by
operators to get some expectation of key publication and usage.

Update the code such that these keytimes are set appropriately.
That means:
- Print "PublishCDS" and "DeleteCDS" times in the state files.
- The keymgr sets the "Removed" and "PublishCDS" times and derives
  those from the dnssec-policy.
- Tweak setting of the "Retired" time, when retiring keys, only
  update the time to now when the retire time is not yet set, or is
  in the future.

This also fixes a bug in "keymgr_transition_time" where we may wait
too long before zone signatrues become omnipresent or hidden. Not
only can we skip waiting the sign delay Dsgn if there is no
predecessor, we can also skip it if there is no successor.

Finally, this commit moves setting the lifetime, reducing two calls
to one.
2020-06-02 09:12:47 +02:00
Mark AndrewsandEvan Hunt eded3efb79 Ensure tree lock is always held when dns_rbt_fullnamefromnode is called 2020-05-29 14:17:39 -07:00
Evan Hunt db9d10e3c1 pass the nodename to add32() instead of calling dns_rbt_fullnamefromnode()
in addition to being more efficient, this prevents a possible crash by
looking up the node name before the tree sructure can be changed when
cleaning up dead nodes in addrdataset().
2020-05-29 14:17:36 -07:00
Ondřej Surý bf60e445ed Stop using AC_C_FLEXIBLE_ARRAY_MEMBER, support for it is part of C99 2020-05-28 11:28:44 +02:00
Ondřej Surý 4c23724c97 Move the dependencies from sln to vcxproj files 2020-05-28 08:08:30 +02:00
Ondřej Surý bfd87e453d Restore the GSSAPI compilation on Windows (but we should really switch to SSPI/Kerberos) 2020-05-28 08:07:57 +02:00