Commit Graph

60 Commits

Author SHA1 Message Date
Evan Hunt
9a372f2bce Use different allocators for UDP and TCP
Each worker has a receive buffer with space for 20 DNS messages of up
to 2^16 bytes each, and the allocator function passed to uv_read_start()
or uv_udp_recv_start() will reserve a portion of it for use by sockets.
UDP can use recvmmsg() and so it needs that entire space, but TCP reads
one message at a time.

This commit introduces separate allocator functions for TCP and UDP
setting different buffer size limits, so that libuv will provide the
correct buffer sizes to each of them.
2020-08-05 12:57:58 +02:00
Witold Kręcicki
a12076cc52 netmgr: retry binding with IP_FREEBIND when EADDRNOTAVAIL is returned.
When a new IPv6 interface/address appears it's first in a tentative
state - in which we cannot bind to it, yet it's already being reported
by the route socket. Because of that BIND9 is unable to listen on any
newly detected IPv6 addresses. Fix it by setting IP_FREEBIND option (or
equivalent option on other OSes) and then retrying bind() call.

(cherry picked from commit a0f7d28967)
2020-07-31 13:33:06 +02:00
Witold Kręcicki
4582ef3bb2 Fix a shutdown race in netmgr udp.
We need to mark the socket as inactive early (and synchronously)
in the stoplistening process - otherwise we might destroy the
callback argument before actually stopping listening, and call
the callback on a bad memory.
2020-06-26 01:44:03 -07:00
Witold Kręcicki
97e44fa3df Make netmgr tcpdns send calls asynchronous.
isc__nm_tcpdns_send() was not asynchronous and accessed socket
internal fields in an unsafe manner, which could lead to a race
condition and subsequent crash. Fix it by moving the whole tcpdns
processing to a proper netmgr thread.
2020-06-26 01:18:27 -07:00
Ondřej Surý
8b4fe6c6c5 Add missing acquire memory barrier in isc_nmhandle_unref
The ThreadSanitizer uses system synchronization primitives to check for
data race.  The netmgr handle->references was missing acquire memory
barrier before resetting and reusing the memory occupied by isc_nmhandle_t.

(cherry picked from commit 1013c0930e)
2020-06-16 08:58:33 +02:00
Witold Kręcicki
818afe613f Redesigned TCP accepting: one listen/accept loop, passing the connected socket.
Instead of using bind() and passing the listening socket to the children
threads using uv_export/uv_import use one thread that does the accepting,
and then passes the connected socket using uv_export/uv_import to a random
worker. The previous solution had thundering herd problems (all workers
waking up on one connection and trying to accept()), this one avoids this
and is simpler.
The tcp clients quota is simplified with isc_quota_attach_cb - a callback
is issued when the quota is available.

(cherry picked from commit 60629e5b0b)
2020-06-03 23:00:52 +02:00
Witold Kręcicki
3461aab083 Clear sock->magic to 0 when destroying a netmgr socket
(cherry picked from commit 7ef756f639)
2020-05-30 07:50:30 +02:00
Witold Kręcicki
4ceddeee78 Add missing isc_mutex_destroy and isc_conditional_destroy calls.
While harmless on Linux, missing isc_{mutex,conditional}_destroy
causes a memory leak on *BSD. Missing calls were added.

(cherry picked from commit a8807d9a7b)
2020-05-30 07:50:30 +02:00
Evan Hunt
00c816778d change 'expr == true' to 'expr' in conditionals
(cherry picked from commit 68a1c9d679)
2020-05-25 17:03:59 -07:00
Witold Kręcicki
786a289dfb Don't free udp recv buffer if UV_UDP_MMSG_CHUNK is set
(cherry picked from commit 83049ceabf)
2020-05-01 11:27:46 +02:00
Ondřej Surý
0e9b0d79fb Remove the extra decstats on STATID_ACTIVE for children sockets
(cherry picked from commit 26842ac25c)
2020-04-03 20:22:56 +02:00
Witold Kręcicki
365636dbc9 netmgr refactoring: use generic functions when operating on sockets.
tcpdns used transport-specific functions to operate on the outer socket.
Use generic ones instead, and select the proper call in netmgr.c.
Make the missing functions (e.g. isc_nm_read) generic and add type-specific
calls (isc__nm_tcp_read). This is the preparation for netmgr TLS layer.

(cherry picked from commit 5fedd21e16)
2020-04-03 13:44:28 +02:00
Witold Kręcicki
3274650123 Deactivate the handle before sending the async close callback.
We could have a race between handle closing and processing async
callback. Deactivate the handle before issuing the callback - we
have the socket referenced anyway so it's not a problem.
2020-03-30 10:54:12 +00:00
Witold Kręcicki
11b80da9ff Limit TCP connection quota logging to 1/s
(cherry picked from commit fc9792eae8)
2020-03-05 23:27:56 +00:00
Witold Kręcicki
b85de76816 Proper accounting of active TCP connections
(cherry picked from commit fc9e2276ca)
2020-03-05 23:27:56 +00:00
Witold Kręcicki
fbc81f4ed7 Increase inactivehandles and inactivereqs size for better reuse.
(cherry picked from commit 4791263def)
2020-02-28 10:05:25 +01:00
Witold Kręcicki
85c2f8dab5 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 14:21:16 +01:00
Ondřej Surý
829b461c54 Merge branch '46-enforce-clang-format-rules' into 'master'
Start enforcing the clang-format rules on changed files

Closes #46

See merge request isc-projects/bind9!3063

(cherry picked from commit a04cdde45d)

d2b5853b Start enforcing the clang-format rules on changed files
618947c6 Switch AlwaysBreakAfterReturnType from TopLevelDefinitions to All
654927c8 Add separate .clang-format files for headers
5777c44a Reformat using the new rules
60d29f69 Don't enforce copyrights on .clang-format
2020-02-14 08:45:59 +00:00
Ondřej Surý
cdef20bb66 Merge branch 'each-style-tweak' into 'master'
adjust clang-format options to get closer to ISC style

See merge request isc-projects/bind9!3061

(cherry picked from commit d3b49b6675)

0255a974 revise .clang-format and add a C formatting script in util
e851ed0b apply the modified style
2020-02-14 05:35:29 +00:00
Ondřej Surý
2e55baddd8 Merge branch '46-add-curly-braces' into 'master'
Add curly braces using uncrustify and then reformat with clang-format back

Closes #46

See merge request isc-projects/bind9!3057

(cherry picked from commit 67b68e06ad)

36c6105e Use coccinelle to add braces to nested single line statement
d14bb713 Add copy of run-clang-tidy that can fixup the filepaths
056e133c Use clang-tidy to add curly braces around one-line statements
2020-02-13 21:28:35 +00:00
Ondřej Surý
c931d8e417 Merge branch '46-just-use-clang-format-to-reformat-sources' into 'master'
Reformat source code with clang-format

Closes #46

See merge request isc-projects/bind9!2156

(cherry picked from commit 7099e79a9b)

4c3b063e Import Linux kernel .clang-format with small modifications
f50b1e06 Use clang-format to reformat the source files
11341c76 Update the definition files for Windows
df6c1f76 Remove tkey_test (which is no-op anyway)
2020-02-12 14:51:18 +00: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ý
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
Ondřej Surý
41fe9b7a14 Formatting issues found by local coccinelle run 2020-02-08 03:12:09 -08:00
Mark Andrews
0be2dc9f22 break was on wrong line.
959                break;

	CID 1457872 (#1 of 1): Structurally dead code (UNREACHABLE)
	unreachable: This code cannot be reached:
	isc__nm_incstats(sock->mgr,....

 960                isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
 961        default:
2020-02-05 18:37:17 +11:00
Witold Kręcicki
fd8788eb94 Fix possible race in socket destruction.
When two threads unreferenced handles coming from one socket while
the socket was being destructed we could get a use-after-free:
Having handle H1 coming from socket S1, H2 coming from socket S2,
S0 being a parent socket to S1 and S2:

Thread A                             Thread B
Unref handle H1                      Unref handle H2
Remove H1 from S1 active handles     Remove H2 from S2 active handles
nmsocket_maybe_destroy(S1)           nmsocket_maybe_destroy(S2)
nmsocket_maybe_destroy(S0)           nmsocket_maybe_destroy(S0)
LOCK(S0->lock)
Go through all children, figure
out that we have no more active
handles:
sum of S0->children[i]->ah == 0
UNLOCK(S0->lock)
destroy(S0)
                                     LOCK(S0->lock)
                                      - but S0 is already gone
2020-01-20 22:28:36 +01:00
Witold Kręcicki
16908ec3d9 netmgr: don't send to an inactive (closing) udp socket
We had a race in which n UDP socket could have been already closing
by libuv but we still sent data to it. Mark socket as not-active
when stopping listening and verify that socket is not active when
trying to send data to it.
2020-01-20 22:28:36 +01:00
Witold Kręcicki
0d637b5985 netmgr: we can't uv_close(sock->timer) when in sock->timer close callback 2020-01-15 14:56:40 +01:00
Ondřej Surý
3000f14eba Use isc_refcount_increment0() when reusing handle or socket; remove extra DbC checks 2020-01-14 13:12:13 +01:00
Evan Hunt
90a1dabe74 count statistics in netmgr UDP code
- also restored a test in the statistics test which was changed when
  the netmgr was introduced because active sockets were not being
  counted.
2020-01-13 14:09:37 -08:00
Evan Hunt
80a5c9f5c8 associate socket stats counters with netmgr socket objects
- the socket stat counters have been moved from socket.h to stats.h.
- isc_nm_t now attaches to the same stats counter group as
  isc_socketmgr_t, so that both managers can increment the same
  set of statistics
- isc__nmsocket_init() now takes an interface as a paramter so that
  the address family can be determined when initializing the socket.
- based on the address family and socket type, a group of statistics
  counters will be associated with the socket - for example, UDP4Active
  with IPv4 UDP sockets and TCP6Active with IPv6 TCP sockets.  note
  that no counters are currently associated with TCPDNS sockets; those
  stats will be handled by the underlying TCP socket.
- the counters are not actually used by netmgr sockets yet; counter
  increment and decrement calls will be added in a later commit.
2020-01-13 14:05:02 -08:00
Witold Kręcicki
67c1ca9a79 Use isc_uv_export() to pass bound TCP listening socket to child listeners.
For multithreaded TCP listening we need to pass a bound socket to all
listening threads. Instead of using uv_pipe handle passing method which
is quite complex (lots of callbacks, each of them with its own error
handling) we now use isc_uv_export() to export the socket, pass it as a
member of the isc__netievent_tcpchildlisten_t structure, and then
isc_uv_import() it in the child thread, simplifying the process
significantly.
2020-01-13 10:53:44 -08:00
Ondřej Surý
4f7d1298a8 Use isc_threadresult_t instead of pthread specific void * return type
The ISC thread API already defines isc_threadresult_t type,
but we are using a pthread specific return type (void *).
2020-01-13 09:08:48 +01:00
Mark Andrews
ad12c2f3b0 address lock order inversion 2019-12-12 17:43:03 +11:00
Ondřej Surý
1fa0deb4ea Add isc_refcount_destroy() call to nm_handle_free() 2019-12-10 13:43:18 +01:00
Ondřej Surý
71fe7d3c25 Add isc_refcount_destroy() call to nm_destroy() 2019-12-10 13:43:18 +01:00
Evan Hunt
31b3980ef0 shorten some names
reduce line breaks and general unwieldiness by changing some
function, type, and parameter names.
2019-12-09 21:44:04 +01:00
Evan Hunt
8c0792723d style nits 2019-12-09 21:44:04 +01:00
Witold Kręcicki
86a847314a Fix a race in socket destruction - we need to remove handle from socket in async close callback or we might race between destruction in the callback and in the original nmhandle_unref 2019-12-09 21:44:04 +01:00
Witold Kręcicki
ef2dff5c7a pause and unpause netmgr in isc_nm_destroy to flush all events from worker queues 2019-12-09 21:44:04 +01:00
Evan Hunt
c7b86d1cac Style fixes 2019-12-09 21:44:03 +01:00
Witold Kręcicki
3e66b7ba1c Fix a race in tcpdns close with uv_close on timer
stop timers before closing

netmgr: tcpdns_close needs to be asynchronous, it manipulates sock->timer
2019-12-09 21:43:45 +01:00
Witold Kręcicki
23ab349bbd netmgr: fix a race in socket destruction, happening if we close the socket
externally and, at the same time, a timeout timer callback was called.
2019-12-09 21:43:45 +01:00
Witold Kręcicki
0bf74ac792 netmgr:
- make tcp listening IPC pipe name saner
 - put the pipe in /tmp on unices
 - add pid to the pipe name to avoid conflicts between processes
 - fsync directory in which the pipe resides to make sure that the
   child threads will see it and be able to open it
2019-12-09 21:43:45 +01:00
Evan Hunt
b05194160b style, comments 2019-12-09 11:15:27 -08:00
Witold Kręcicki
8c5aaacbef - Add separate priority event queue for events that must be processed
even when worker is paused (e.g. interface reconfiguration). This is
  needed to prevent deadlocks when reconfiguring interfaces - as network
  manager is paused then, but we still need to stop/start listening.

- Proper handling of TCP listen errors in netmgr - bind to the socket first,
  then return the error code.
2019-12-09 11:15:27 -08:00
Witold Kręcicki
5a65ec0aff Add uv_handle_{get,set}_data functions that's absent in pre-1.19 libuv to make code clearer.
This might be removed when we stop supporting older libuv versions.
2019-12-09 11:15:27 -08:00
Witold Kręcicki
bc5aae1579 netmgr: make tcp listening multithreaded.
When listening for TCP connections we create a socket, bind it
and then pass it over IPC to all threads - which then listen on
in and accept connections. This sounds broken, but it's the
official way of dealing with multithreaded TCP listeners in libuv,
and works on all platforms supported by libuv.
2019-12-09 11:15:27 -08:00
Ondřej Surý
01731d4b1b Add and use ISC_THREAD_LOCAL macro
The new ISC_THREAD_LOCAL macro unifies usage of platform dependent
Thread Local Storage definition thread_local vs __thread vs
__declspec(thread) to a single macro.

The commit also unifies the required level of support for TLS as for
some parts of the code it was mandatory and for some parts of the code
it wasn't.
2019-12-03 16:27:24 +01:00
Witold Kręcicki
bf2cc19b04 - Access netmgr worker->finished under worker lock only
- Join network worker thread to silence tsan
2019-11-26 15:21:25 +01:00