2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Refactor TLSDNS module to work with libuv/ssl directly

* Following the example set in 634bdfb16d, the tlsdns netmgr
  module now uses libuv and SSL primitives directly, rather than
  opening a TLS socket which opens a TCP socket, as the previous
  model was difficult to debug.  Closes #2335.

* Remove the netmgr tls layer (we will have to re-add it for DoH)

* Add isc_tls API to wrap the OpenSSL SSL_CTX object into libisc
  library; move the OpenSSL initialization/deinitialization from dstapi
  needed for OpenSSL 1.0.x to the isc_tls_{initialize,destroy}()

* Add couple of new shims needed for OpenSSL 1.0.x

* When LibreSSL is used, require at least version 2.7.0 that
  has the best OpenSSL 1.1.x compatibility and auto init/deinit

* Enforce OpenSSL 1.1.x usage on Windows

* Added a TLSDNS unit test and implemented a simple TLSDNS echo
  server and client.
This commit is contained in:
Ondřej Surý
2020-12-17 11:40:29 +01:00
parent 8f73c70d23
commit e493e04c0f
32 changed files with 4376 additions and 1983 deletions

View File

@@ -113,16 +113,6 @@ stop_reading(isc_nmsocket_t *sock);
static isc__nm_uvreq_t *
get_read_req(isc_nmsocket_t *sock);
/*
* Regular TCP buffer, should suffice in most cases.
*/
#define NM_REG_BUF 4096
/*
* Two full DNS packets with lengths.
* netmgr receives 64k at most so there's no risk
* of overrun.
*/
#define NM_BIG_BUF (65535 + 2) * 2
static inline void
alloc_dnsbuf(isc_nmsocket_t *sock, size_t len) {
REQUIRE(len <= NM_BIG_BUF);
@@ -790,7 +780,7 @@ get_read_req(isc_nmsocket_t *sock) {
req->handle = isc__nmhandle_get(sock, NULL, NULL);
}
return req;
return (req);
}
static void
@@ -813,25 +803,26 @@ start_sock_timer(isc_nmsocket_t *sock) {
if (sock->read_timeout > 0) {
int r = uv_timer_start(&sock->timer, readtimeout_cb,
sock->read_timeout, 0);
REQUIRE(r == 0);
RUNTIME_CHECK(r == 0);
}
}
static void
stop_sock_timer(isc_nmsocket_t *sock) {
int r = uv_timer_stop(&sock->timer);
REQUIRE(r == 0);
RUNTIME_CHECK(r == 0);
}
static void
start_reading(isc_nmsocket_t *sock) {
int r;
if (sock->reading) {
return;
}
int r = uv_read_start(&sock->uv_handle.stream, tcpdns_alloc_cb,
read_cb);
REQUIRE(r == 0);
r = uv_read_start(&sock->uv_handle.stream, tcpdns_alloc_cb, read_cb);
RUNTIME_CHECK(r == 0);
sock->reading = true;
start_sock_timer(sock);
@@ -839,12 +830,14 @@ start_reading(isc_nmsocket_t *sock) {
static void
stop_reading(isc_nmsocket_t *sock) {
int r;
if (!sock->reading) {
return;
}
int r = uv_read_stop(&sock->uv_handle.stream);
REQUIRE(r == 0);
r = uv_read_stop(&sock->uv_handle.stream);
RUNTIME_CHECK(r == 0);
sock->reading = false;
stop_sock_timer(sock);
@@ -898,10 +891,11 @@ tcpdns_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);
isc__networker_t *worker = NULL;
UNUSED(size);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->type == isc_nm_tcpdnssocket);
REQUIRE(isc__nm_in_netthread());
UNUSED(size);
worker = &sock->mgr->workers[sock->tid];
INSIST(!worker->recvbuf_inuse);
@@ -917,9 +911,10 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
(isc__netievent_tcpdnsread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
UNUSED(worker);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
if (inactive(sock)) {
sock->reading = true;
@@ -1303,9 +1298,10 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
isc_nmsocket_t *sock = ievent->sock;
isc__nm_uvreq_t *uvreq = ievent->req;
UNUSED(worker);
REQUIRE(sock->type == isc_nm_tcpdnssocket);
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
result = tcpdns_send_direct(sock, uvreq);
if (result != ISC_R_SUCCESS) {
@@ -1316,12 +1312,13 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
static isc_result_t
tcpdns_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
int r;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_UVREQ(req));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(sock->type == isc_nm_tcpdnssocket);
int r;
uv_buf_t bufs[2] = { { .base = req->tcplen, .len = 2 },
{ .base = req->uvbuf.base,
.len = req->uvbuf.len } };
@@ -1342,12 +1339,13 @@ tcpdns_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
static void
tcpdns_stop_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);
uv_handle_set_data(handle, NULL);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing));
uv_handle_set_data(handle, NULL);
if (!atomic_compare_exchange_strong(&sock->closed, &(bool){ false },
true)) {
INSIST(0);
@@ -1364,6 +1362,7 @@ tcpdns_stop_cb(uv_handle_t *handle) {
static void
tcpdns_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);
uv_handle_set_data(handle, NULL);
REQUIRE(VALID_NMSOCK(sock));
@@ -1498,11 +1497,11 @@ isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0) {
(isc__netievent_tcpdnsclose_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
UNUSED(worker);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
tcpdns_close_direct(sock);
}
@@ -1560,19 +1559,22 @@ isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
(isc__netievent_tcpdnscancel_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
UNUSED(worker);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
failed_read_cb(sock, ISC_R_EOF);
}
void
isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
isc_nmsocket_t *sock = handle->sock;
sock = handle->sock;
sock->read_timeout = timeout;
if (uv_is_active((uv_handle_t *)&sock->timer)) {
@@ -1582,11 +1584,13 @@ isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
void
isc_nm_tcpdns_sequential(isc_nmhandle_t *handle) {
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
REQUIRE(handle->sock->type == isc_nm_tcpdnssocket);
isc_nmsocket_t *sock = handle->sock;
sock = handle->sock;
/*
* We don't want pipelining on this connection. That means
@@ -1603,11 +1607,13 @@ isc_nm_tcpdns_sequential(isc_nmhandle_t *handle) {
void
isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle, bool value) {
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
REQUIRE(handle->sock->type != isc_nm_tcpdnssocket);
isc_nmsocket_t *sock = handle->sock;
sock = handle->sock;
atomic_store(&sock->keepalive, value);
}