Commit Graph

3776 Commits

Author SHA1 Message Date
Ondřej Surý
70100c664a Stop leaking OpenSSL types and defines in the isc/hmac.h
The <isc/md.h> header directly included <openssl/hmac.h> header which
enforced all users of the libisc library to explicitly list the include
path to OpenSSL and link with -lcrypto.  By hiding the specific
implementation into the private namespace, we no longer enforce this.
In the long run, this might also allow us to switch cryptographic
library implementation without affecting the downstream users.
2020-03-12 22:22:03 +01:00
Ondřej Surý
ab827ab5bf Stop leaking OpenSSL types and defines in the isc/safe.h
The two "functions" that isc/safe.h declared before were actually simple
defines to matching OpenSSL functions.  The downside of the approach was
enforcing all users of the libisc library to explicitly list the include
path to OpenSSL and link with -lcrypto.  By hiding the specific
implementation into the private namespace changing the defines into
simple functions, we no longer enforce this.  In the long run, this
might also allow us to switch cryptographic library implementation
without affecting the downstream users.
2020-03-12 20:07:16 +01:00
Ondřej Surý
e67ce7e966 Use ISC_R_CRYPTOFAILURE instead DST_R_CRYPTOFAILURE in libisc
There was a circular libisc dependency on libdns headers for
DST_R_CRYPTOFAILURE return code.  Replace it with ISC_R_CRYPTOFAILURE to
break the loop.
2020-03-12 17:50:29 +01:00
Ondřej Surý
e847591867 Improve the backtrace to print symbols when backtrace_symbols() is available
The previous commit removed the code related to the internal symbol
table.  On platforms where available, we can now use backtrace_symbols()
to print more verbose symbols table to the output.

As there's now general availability of backtrace() and
backtrace_symbols() functions (see below), the commit also removes the
usage of glibc internals and the custom stack tracing.

* backtrace(), backtrace_symbols(), and backtrace_symbols_fd() are
  provided in glibc since version 2.1.
* backtrace(), backtrace_symbols(), and backtrace_symbols_fd() first
  appeared in Mac OS X 10.5.
* The backtrace() library of functions first appeared in NetBSD 7.0 and
  FreeBSD 10.0.
2020-03-11 20:32:21 +01:00
Evan Hunt
ad5250ff9c Remove support for internal symbol table
Since we can no longer generate an internal symbol table, there
doesn't seem to be much reason to retain the code that reads it.
2020-03-11 11:13:52 +01:00
Ondřej Surý
584fd98a0c Fixup the headers formatting 2020-03-11 10:19:32 +01:00
Ondřej Surý
1ca73f606e Fix the deeper symlinks to .clang-format.headers 2020-03-11 10:16:45 +01:00
Diego Fronza
a200852001 Fixed data race in log.c
A data race was happening while BIND was starting due to
isc_log_wouldlog function accessing lctx->logconfig without a lock.

To prevent that without incurring much costs, that variable was made
atomic.
2020-03-10 11:49:53 +01:00
Ondřej Surý
3178974f0c Use the new sorting rules to regroup #include headers 2020-03-09 16:19:22 +01:00
Diego Fronza
6e5b4f7ec8 Fixed missing list initialization
This commit fixes isc_glob function on windows environments.

The file_list_t * object pointed to by pglob->reserved was missing
ISC_LIST_INIT intialization macro.
2020-03-06 16:53:20 -03:00
Michał Kępień
b675d30f09 Fix lists of installed header files 2020-03-05 23:09:51 +00:00
Witold Kręcicki
4b9962d4a3 Only use tcpdns timer if it's initialized. 2020-03-05 23:13:39 +01:00
Witold Kręcicki
ae1499ca19 Fix TCPDNS socket closing issues 2020-03-05 18:02:27 +00:00
Witold Kręcicki
fc9792eae8 Limit TCP connection quota logging to 1/s 2020-03-05 18:02:27 +00:00
Witold Kręcicki
fc9e2276ca Proper accounting of active TCP connections 2020-03-05 18:02:27 +00:00
Witold Kręcicki
81ba0fe0e6 Fix a race in isc_socket destruction.
There was a very slim chance of a race between isc_socket_detach and
process_fd: isc_socket_detach decrements references to 0, and before it
calls destroy gets preempted. Second thread calls process_fd, increments
socket references temporarily to 1, and then gets preempted, first thread
then hits assertion in destroy() as the reference counter is now 1 and
not 0.
2020-03-03 08:34:19 +01:00
Michał Kępień
fc967ba092 Add ZLIB_LIBS to ISCLIBS
When --with-zlib is passed to ./configure (or when the latter
autodetects zlib's presence), libisc uses certain zlib functions and
thus libisc's users should be linked against zlib in that case.  Adjust
Makefile variables appropriately to prevent shared build failures caused
by underlinking.
2020-02-28 15:22:29 +01:00
Evan Hunt
0b76d8a490 comments 2020-02-28 08:46:16 +01:00
Witold Kręcicki
4791263def Increase inactivehandles and inactivereqs size for better reuse. 2020-02-28 08:46:16 +01:00
Witold Kręcicki
517e6eccdf use SO_INCOMING_CPU for UDP sockets 2020-02-28 08:46:16 +01:00
Witold Kręcicki
a658f7976c We don't need to fill udp local address every time since we are bound to it. 2020-02-28 08:46:16 +01:00
Witold Kręcicki
eb874608c1 Use the original threadid when sending a UDP packet to decrease probability of context switching 2020-02-28 08:46:16 +01:00
Mark Andrews
8c983a7ebd Simplify hash computation to prevent pointer being classed as tainted.
mem.c:add_trace_entry() -> isc_hash_function() -> isc_siphash24()

129        for (; in != end; in += 8) {

	6. byte_swapping: Performing a byte swapping operation on
	in implies that it came from an external source, and is
	therefore tainted.

130                uint64_t m = U8TO64_LE(in);
2020-02-27 19:41:36 +00:00
Witold Kręcicki
00f2146265 Use isc_rwlock for isc_result tables 2020-02-27 07:58:48 +00:00
Matthijs Mekking
5cc33084af Make clang-format happy 2020-02-25 09:07:45 +01:00
Diego Fronza
9b4e28e155 Added a isc_glob() function that wraps glob() calls for POSIX systems
and implement a custom glob() function on Windows systems.
2020-02-24 13:46:39 -03:00
Michał Kępień
9f34e0d5af Bump library API versions for BIND 9.17 2020-02-24 10:56:47 +01:00
Evan Hunt
ba0313e649 fix spelling errors reported by Fossies. 2020-02-21 15:05:08 +11:00
Witold Krecicki
0fe149b2fa Fix lib/isc/tests/socket_test hangs 2020-02-20 11:39:15 +01:00
Witold Kręcicki
093af1a609 Use libuv-provided uv_{export,import} if available.
We were using our own versions of isc_uv_{export,import} functions
for multithreaded TCP listeners. Upcoming libuv version will
contain proper uv_{export,import} functions - use them if they're
available.
2020-02-18 12:17:55 +01:00
Witold Kręcicki
a0d36d7601 Make nm->recvbuf larger and heap allocated, to allow uv_recvmmsg usage.
Upcoming version of libuv will suport uv_recvmmsg and uv_sendmmsg. To
use uv_recvmmsg we need to provide a larger buffer and be able to
properly free it.
2020-02-18 12:17:55 +01:00
Witold Kręcicki
23bd04d2f1 Make isc_task_pause/isc_task_unpause thread safe.
isc_task_pause/unpause were inherently thread-unsafe - a task
could be paused only once by one thread, if the task was running
while we paused it it led to races. Fix it by making sure that
the task will pause if requested to, and by using a 'pause reference
counter' to count task pause requests - a task will be unpaused
iff all threads unpause it.

Don't remove from queue when pausing task - we lock the queue lock
(expensive), while it's unlikely that the task will be running -
and we'll remove it anyway in dispatcher
2020-02-18 09:22:04 +00:00
Evan Hunt
0002377dca adjust the clang-format penalties to reduce string breaking
this corrects some style glitches such as:
```
        long_function_call(arg, arg2, arg3, arg4, arg5, "str"
                                                        "ing");
```
...by adjusting the penalties for breaking strings and call
parameter lists.
2020-02-17 14:23:58 -08:00
Ondřej Surý
4cf275ba8a Replace non-loop usage of atomic_compare_exchange_weak with strong variant
While testing BIND 9 on arm64 8+ core machine, it was discovered that
the weak variants in fact does spuriously fail, we haven't observed that
on other architectures.

This commit replaces all non-loop usage of atomic_compare_exchange_weak
with atomic_compare_exchange_strong.
2020-02-16 18:09:19 +01:00
Diego Fronza
fa68a0d869 Added atomic_compare_exchange_strong_acq_rel macro
It is much better to read than:
atomic_compare_exchange_strong_explicit() with 5 arguments.
2020-02-16 18:09:19 +01:00
Ondřej Surý
3832e3ecc9 Fixup the missing clang-format bits 2020-02-16 17:34:24 +01:00
Diego Fronza
e7b36924e2 Fixed potential-lock-inversion
This commit simplifies a bit the lock management within dns_resolver_prime()
and prime_done() functions by means of turning resolver's attribute
"priming" into an atomic_bool and by creating only one dependent object on the
lock "primelock", namely the "primefetch" attribute.

By having the attribute "priming" as an atomic type, it save us from having to
use a lock just to test if priming is on or off for the given resolver context
object, within "dns_resolver_prime" function.

The "primelock" lock is still necessary, since dns_resolver_prime() function
internally calls dns_resolver_createfetch(), and whenever this function
succeeds it registers an event in the task manager which could be called by
another thread, namely the "prime_done" function, and this function is
responsible for disposing the "primefetch" attribute in the resolver object,
also for resetting "priming" attribute to false.

It is important that the invariant "priming == false AND primefetch == NULL"
remains constant, so that any thread calling "dns_resolver_prime" knows for sure
that if the "priming" attribute is false, "primefetch" attribute should also be
NULL, so a new fetch context could be created to fulfill this purpose, and
assigned to "primefetch" attribute under the lock protection.

To honor the explanation above, dns_resolver_prime is implemented as follow:
	1. Atomically checks the attribute "priming" for the given resolver context.
	2. If "priming" is false, assumes that "primefetch" is NULL (this is
           ensured by the "prime_done" implementation), acquire "primelock"
	   lock and create a new fetch context, update "primefetch" pointer to
	   point to the newly allocated fetch context.
	3. If "priming" is true, assumes that the job is already in progress,
	   no locks are acquired, nothing else to do.

To keep the previous invariant consistent, "prime_done" is implemented as follow:
	1. Acquire "primefetch" lock.
	2. Keep a reference to the current "primefetch" object;
	3. Reset "primefetch" attribute to NULL.
	4. Release "primefetch" lock.
	5. Atomically update "priming" attribute to false.
	6. Destroy the "primefetch" object by using the temporary reference.

This ensures that if "priming" is false, "primefetch" was already reset to NULL.

It doesn't make any difference in having the "priming" attribute not protected
by a lock, since the visible state of this variable would depend on the calling
order of the functions "dns_resolver_prime" and "prime_done".

As an example, suppose that instead of using an atomic for the "priming" attribute
we employed a lock to protect it.
Now suppose that "prime_done" function is called by Thread A, it is then preempted
before acquiring the lock, thus not reseting "priming" to false.
In parallel to that suppose that a Thread B is scheduled and that it calls
"dns_resolver_prime()", it then acquires the lock and check that "priming" is true,
thus it will consider that this resolver object is already priming and it won't do
any more job.
Conversely if the lock order was acquired in the other direction, Thread B would check
that "priming" is false (since prime_done acquired the lock first and set "priming" to false)
and it would initiate a priming fetch for this resolver.

An atomic variable wouldn't change this behavior, since it would behave exactly the
same, depending on the function call order, with the exception that it would avoid
having to use a lock.

There should be no side effects resulting from this change, since the previous
implementation employed use of the more general resolver's "lock" mutex, which
is used in far more contexts, but in the specifics of the "dns_resolver_prime"
and "prime_done" it was only used to protect "primefetch" and "priming" attributes,
which are not used in any of the other critical sections protected by the same lock,
thus having zero dependency on those variables.
2020-02-14 14:28:31 -03:00
Diego Fronza
c210413a8a Added atomic_compare_exchange_strong_acq_rel macro
It is much better to read than:
atomic_compare_exchange_strong_explicit() with 5 arguments.
2020-02-14 11:41:36 -03:00
Ondřej Surý
5777c44ad0 Reformat using the new rules 2020-02-14 09:31:05 +01:00
Ondřej Surý
654927c871 Add separate .clang-format files for headers 2020-02-14 09:31:05 +01:00
Evan Hunt
e851ed0bb5 apply the modified style 2020-02-13 15:05:06 -08:00
Ondřej Surý
056e133c4c Use clang-tidy to add curly braces around one-line statements
The command used to reformat the files in this commit was:

./util/run-clang-tidy \
	-clang-tidy-binary clang-tidy-11
	-clang-apply-replacements-binary clang-apply-replacements-11 \
	-checks=-*,readability-braces-around-statements \
	-j 9 \
	-fix \
	-format \
	-style=file \
	-quiet
clang-format -i --style=format $(git ls-files '*.c' '*.h')
uncrustify -c .uncrustify.cfg --replace --no-backup $(git ls-files '*.c' '*.h')
clang-format -i --style=format $(git ls-files '*.c' '*.h')
2020-02-13 22:07:21 +01:00
Ondřej Surý
36c6105e4f Use coccinelle to add braces to nested single line statement
Both clang-tidy and uncrustify chokes on statement like this:

for (...)
	if (...)
		break;

This commit uses a very simple semantic patch (below) to add braces around such
statements.

Semantic patch used:

@@
statement S;
expression E;
@@

while (...)
- if (E) S
+ { if (E) { S } }

@@
statement S;
expression E;
@@

for (...;...;...)
- if (E) S
+ { if (E) { S } }

@@
statement S;
expression E;
@@

if (...)
- if (E) S
+ { if (E) { S } }
2020-02-13 21:58:55 +01:00
Ondřej Surý
11341c7688 Update the definition files for Windows 2020-02-12 15:04:17 +01:00
Ondřej Surý
f50b1e0685 Use clang-format to reformat the source files 2020-02-12 15:04:17 +01:00
Witold Kręcicki
a133239698 Don't limit the size of uvreq/nmhandle pool artificially.
There was a hard limit set on number of uvreq and nmhandles
that can be allocated by a pool, but we don't handle a situation
where we can't get an uvreq. Don't limit the number at all,
let the OS deal with it.
2020-02-11 12:10:57 +00:00
Ondřej Surý
b43f5e0238 Convert all atomic operations in isc_rwlock to release-acquire memory ordering
The memory ordering in the rwlock was all wrong, I am copying excerpts
from the https://en.cppreference.com/w/c/atomic/memory_order#Relaxed_ordering
for the convenience of the reader:

  Relaxed ordering

  Atomic operations tagged memory_order_relaxed are not synchronization
  operations; they do not impose an order among concurrent memory
  accesses. They only guarantee atomicity and modification order
  consistency.

  Release-Acquire ordering

  If an atomic store in thread A is tagged memory_order_release and an
  atomic load in thread B from the same variable is tagged
  memory_order_acquire, all memory writes (non-atomic and relaxed atomic)
  that happened-before the atomic store from the point of view of thread
  A, become visible side-effects in thread B. That is, once the atomic
  load is completed, thread B is guaranteed to see everything thread A
  wrote to memory.

  The synchronization is established only between the threads releasing
  and acquiring the same atomic variable. Other threads can see different
  order of memory accesses than either or both of the synchronized
  threads.

Which basically means that we had no or weak synchronization between
threads using the same variables in the rwlock structure.  There should
not be a significant performance drop because the critical sections were
already protected by:

  while(1) {
    if (relaxed_atomic_operation) {
      break;
    }
    LOCK(lock);
    if (!relaxed_atomic_operation) {
      WAIT(sem, lock);
    }
    UNLOCK(lock)l
  }

I would add one more thing to "Don't do your own crypto, folks.":

  - Also don't do your own locking, folks.
2020-02-11 11:10:55 +01:00
Ondřej Surý
bc1d4c9cb4 Clear the pointer to destroyed object early using the semantic patch
Also disable the semantic patch as the code needs tweaks here and there because
some destroy functions might not destroy the object and return early if the
object is still in use.
2020-02-09 18:00:17 -08:00
Witold Kręcicki
d708370db4 Fix atomics usage for mutexatomics 2020-02-08 12:34:19 -08:00
Ondřej Surý
41fe9b7a14 Formatting issues found by local coccinelle run 2020-02-08 03:12:09 -08:00