AC_CHECK_HEADERS([glob.h])
+#
+# Support for constructor and destructor attributes
+#
+AX_GCC_FUNC_ATTRIBUTE([constructor])
+AX_GCC_FUNC_ATTRIBUTE([destructor])
+
#
# Files to configure. These are listed here because we used to
# specify them as arguments to AC_OUTPUT.
dst__openssl_init(const char *engine) {
isc_result_t result = ISC_R_SUCCESS;
- isc_tls_initialize();
-
enable_fips_mode();
#if !defined(OPENSSL_NO_ENGINE)
}
e = NULL;
#endif /* if !defined(OPENSSL_NO_ENGINE) */
- isc_tls_destroy();
}
static isc_result_t
typedef struct ssl_ctx_st isc_tlsctx_t;
-void
-isc_tls_initialize(void);
-
-void
-isc_tls_destroy(void);
-
void
isc_tlsctx_free(isc_tlsctx_t **ctpx);
/*%
#define ISC_NONSTRING
#endif /* __GNUC__ */
+#if HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR && HAVE_FUNC_ATTRIBUTE_DESTRUCTOR
+#define ISC_CONSTRUCTOR(priority) __attribute__((constructor(priority)))
+#define ISC_DESTRUCTOR(priority) __attribute__((destructor(priority)))
+#elif WIN32
+#define ISC_CONSTRUCTOR(priority)
+#define ISC_DESTRUCTOR(priority)
+#else
+#error Either __attribute__((constructor|destructor))__ or DllMain support needed to compile BIND 9.
+#endif
+
/*%
* The opposite: silent warnings about stored values which are never read.
*/
#include <isc/bind9.h>
#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/tls.h>
+#include <isc/util.h>
+
+#include "mem_p.h"
+#include "tls_p.h"
/***
*** Functions
isc_lib_register(void) {
isc_bind9 = false;
}
+
+void
+isc__initialize(void) ISC_CONSTRUCTOR(101);
+void
+isc__shutdown(void) ISC_DESTRUCTOR(101);
+
+void
+isc__initialize(void) {
+ isc__mem_initialize();
+ isc__tls_initialize();
+}
+
+void
+isc__shutdown(void) {
+ isc__tls_shutdown();
+ isc__mem_shutdown();
+}
static ISC_LIST(isc_mem_t) contexts;
-static isc_once_t once = ISC_ONCE_INIT;
+static isc_once_t init_once = ISC_ONCE_INIT;
+static isc_once_t shut_once = ISC_ONCE_INIT;
static isc_mutex_t contextslock;
/*%
}
static void
-initialize_action(void) {
+mem_initialize(void) {
isc_mutex_init(&contextslock);
ISC_LIST_INIT(contexts);
totallost = 0;
}
+void
+isc__mem_initialize(void) {
+ RUNTIME_CHECK(isc_once_do(&init_once, mem_initialize) == ISC_R_SUCCESS);
+}
+
+static void
+mem_shutdown(void) {
+ isc__mem_checkdestroyed();
+
+ isc_mutex_destroy(&contextslock);
+}
+
+void
+isc__mem_shutdown(void) {
+ RUNTIME_CHECK(isc_once_do(&shut_once, mem_shutdown) == ISC_R_SUCCESS);
+}
+
static void
mem_create(isc_mem_t **ctxp, unsigned int flags) {
REQUIRE(ctxp != NULL && *ctxp == NULL);
STATIC_ASSERT(ALIGNMENT_SIZE >= sizeof(size_info),
"alignment size too small");
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
-
ctx = default_memalloc(sizeof(*ctx));
*ctx = (isc_mem_t){
}
#endif
+static atomic_uintptr_t checkdestroyed = ATOMIC_VAR_INIT(0);
+
void
isc_mem_checkdestroyed(FILE *file) {
-#if !ISC_MEM_TRACKLINES
- UNUSED(file);
-#endif /* if !ISC_MEM_TRACKLINES */
+ atomic_store_release(&checkdestroyed, (uintptr_t)file);
+}
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+void
+isc__mem_checkdestroyed(void) {
+ FILE *file = (FILE *)atomic_load_acquire(&checkdestroyed);
+
+ if (file == NULL) {
+ return;
+ }
LOCK(&contextslock);
if (!ISC_LIST_EMPTY(contexts)) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts"));
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
-
LOCK(&contextslock);
lost = totallost;
for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL;
json_object *memobj = (json_object *)memobj0;
memset(&summary, 0, sizeof(summary));
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
ctxarray = json_object_new_array();
CHECKMEM(ctxarray);
* information regarding copyright ownership.
*/
-#ifndef ISC_MEM_P_H
-#define ISC_MEM_P_H
+#pragma once
+
+#include <stdio.h>
+
+#include <isc/mem.h>
/*! \file */
* a single memory context.
*/
-#endif /* ISC_MEM_P_H */
+void
+isc__mem_checkdestroyed(void);
+
+void
+isc__mem_initialize(void);
+
+void
+isc__mem_shutdown(void);
isc__nm_winsock_initialize();
#endif /* WIN32 */
- isc_tls_initialize();
-
mgr = isc_mem_get(mctx, sizeof(*mgr));
*mgr = (isc_nm_t){ .nworkers = workers };
mgr->nworkers * sizeof(isc__networker_t));
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
- isc_tls_destroy();
-
#ifdef WIN32
isc__nm_winsock_destroy();
#endif /* WIN32 */
REQUIRE(VALID_NM(mgr));
REQUIRE(local != NULL);
REQUIRE(peer != NULL);
+ REQUIRE(sslctx != NULL);
sa_family = peer->addr.type.sa.sa_family;
csock->tls.state = TLS_STATE_NONE;
csock->tls.ssl = SSL_new(ssock->tls.ctx);
+
+ if (csock->tls.ssl == NULL) {
+ char errbuf[256];
+ unsigned long err = ERR_get_error();
+
+ ERR_error_string_n(err, errbuf, sizeof(errbuf));
+ fprintf(stderr, "%s:SSL_new(%p) -> %s\n", __func__,
+ ssock->tls.ctx, errbuf);
+ }
+
RUNTIME_CHECK(csock->tls.ssl != NULL);
r = BIO_new_bio_pair(&csock->tls.ssl_wbio, TLS_BUF_SIZE,
int tlsdns_listen_sock = -1;
isc_nm_t **nm = NULL;
- isc_tlsctx_createserver(NULL, NULL, &tlsdns_listen_ctx);
- isc_tlsctx_createclient(&tlsdns_connect_ctx);
+ if (isc_tlsctx_createserver(NULL, NULL, &tlsdns_listen_ctx) !=
+ ISC_R_SUCCESS) {
+ return (-1);
+ }
+ if (isc_tlsctx_createclient(&tlsdns_connect_ctx) != ISC_R_SUCCESS) {
+ return (-1);
+ }
tlsdns_listen_addr = (isc_sockaddr_t){ .length = 0 };
tlsdns_listen_sock = setup_ephemeral_port(&tlsdns_listen_addr,
#include <isc/util.h>
#include "openssl_shim.h"
+#include "tls_p.h"
static isc_once_t init_once = ISC_ONCE_INIT;
static isc_once_t shut_once = ISC_ONCE_INIT;
static atomic_bool init_done = ATOMIC_VAR_INIT(false);
static atomic_bool shut_done = ATOMIC_VAR_INIT(false);
-static isc_mem_t *isc__tls_mctx = NULL;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static isc_mutex_t *locks = NULL;
}
#endif
-#if 0
-static void *
-isc__tls_malloc(size_t size, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
-
- return (isc_mem_allocate(isc__tls_mctx, size));
-}
-
-static void *
-isc__tls_realloc(void *ptr, size_t size, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
-
- return (isc__mem_reallocate(isc__tls_mctx, ptr, size));
-}
-
-static void
-isc__tls_free(void *ptr, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
-
- if (ptr == NULL) {
- return;
- }
-
- isc__mem_free(isc__tls_mctx, ptr);
-}
-#endif
-
static void
-isc__tls_initialize(void) {
+tls_initialize(void) {
REQUIRE(!atomic_load(&init_done));
- isc_mem_create(&isc__tls_mctx);
- /* isc_mem_setdestroycheck(isc__tls_mctx, false); */
-
- /* REQUIRE(CRYPTO_set_mem_functions(isc__tls_malloc, isc__tls_realloc,
- * isc__tls_free) == 1); */
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
RUNTIME_CHECK(OPENSSL_init_ssl(OPENSSL_INIT_ENGINE_ALL_BUILTIN |
OPENSSL_INIT_LOAD_CONFIG,
NULL) == 1);
#else
nlocks = CRYPTO_num_locks();
- locks = isc_mem_get(isc__tls_mctx, nlocks * sizeof(locks[0]));
+ /*
+ * We can't use isc_mem API here, because it's called too
+ * early and when the isc_mem_debugging flags are changed
+ * later and ISC_MEM_DEBUGSIZE or ISC_MEM_DEBUGCTX flags are
+ * added, neither isc_mem_put() nor isc_mem_free() can be used
+ * to free up the memory allocated here because the flags were
+ * not set when calling isc_mem_get() or isc_mem_allocate()
+ * here.
+ *
+ * Actually, since this is a single allocation at library load
+ * and deallocation at library unload, using the standard
+ * allocator without the tracking is fine for this purpose.
+ */
+ locks = calloc(nlocks, sizeof(locks[0]));
isc_mutexblock_init(locks, nlocks);
CRYPTO_set_locking_callback(isc__tls_lock_callback);
CRYPTO_THREADID_set_callback(isc__tls_set_thread_id);
"seeded' message in the OpenSSL FAQ)");
}
- atomic_compare_exchange_strong(&init_done, &(bool){ false }, true);
+ REQUIRE(atomic_compare_exchange_strong(&init_done, &(bool){ false },
+ true));
}
void
-isc_tls_initialize(void) {
- isc_result_t result = isc_once_do(&init_once, isc__tls_initialize);
+isc__tls_initialize(void) {
+ isc_result_t result = isc_once_do(&init_once, tls_initialize);
REQUIRE(result == ISC_R_SUCCESS);
REQUIRE(atomic_load(&init_done));
}
static void
-isc__tls_destroy(void) {
+tls_shutdown(void) {
REQUIRE(atomic_load(&init_done));
REQUIRE(!atomic_load(&shut_done));
+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
CONF_modules_unload(1);
CRYPTO_set_locking_callback(NULL);
- /* REQUIRE(CRYPTO_set_mem_functions(OPENSSL_malloc, OPENSSL_realloc,
- * OPENSSL_free) == 1); */
-
if (locks != NULL) {
- INSIST(isc__tls_mctx != NULL);
isc_mutexblock_destroy(locks, nlocks);
- isc_mem_put(isc__tls_mctx, locks, nlocks * sizeof(locks[0]));
+ free(locks);
locks = NULL;
}
#endif
- isc_mem_detach(&isc__tls_mctx);
- atomic_compare_exchange_strong(&shut_done, &(bool){ false }, true);
+ REQUIRE(atomic_compare_exchange_strong(&shut_done, &(bool){ false },
+ true));
}
void
-isc_tls_destroy(void) {
- isc_result_t result = isc_once_do(&shut_once, isc__tls_destroy);
+isc__tls_shutdown(void) {
+ isc_result_t result = isc_once_do(&shut_once, tls_shutdown);
REQUIRE(result == ISC_R_SUCCESS);
REQUIRE(atomic_load(&shut_done));
}
REQUIRE(ctxp != NULL && *ctxp == NULL);
- isc_tls_initialize();
-
method = TLS_client_method();
if (method == NULL) {
goto ssl_error;
REQUIRE(ctxp != NULL && *ctxp == NULL);
- isc_tls_initialize();
-
if (ephemeral) {
INSIST(keyfile == NULL);
INSIST(certfile == NULL);
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
ISC_LOG_ERROR, "Error initializing TLS context: %s",
errbuf);
+
if (ctx != NULL) {
SSL_CTX_free(ctx);
}
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+void
+isc__tls_initialize(void);
+
+void
+isc__tls_shutdown(void);
#include <stdio.h>
#include <windows.h>
+#include <isc/mem.h>
+#include <isc/tls.h>
+#include <isc/util.h>
+
+#include "mem_p.h"
+#include "tls_p.h"
+
/*
* Called when we enter the DLL
*/
* Disable DllMain() invocation on Thread creation/destruction
*/
DisableThreadLibraryCalls(hinstDLL);
+ isc__mem_initialize();
+ isc__tls_initialize();
break;
/*
* termination or a call to FreeLibrary.
*/
case DLL_PROCESS_DETACH:
+ isc__tls_shutdown();
+ isc__mem_shutdown();
break;
case DLL_THREAD_ATTACH:
* disabled.
*/
INSIST(0);
+ ISC_UNREACHABLE();
break;
default:
isc_md_type_get_size
isc_md_type_get_block_size
isc_md
+isc__mem_checkdestroyed
+isc__mem_initialize
+isc__mem_shutdown
isc_mem_attach
isc_mem_checkdestroyed
isc_mem_create
isc_timermgr_createinctx
isc_timermgr_destroy
isc_timermgr_poke
-isc_tls_initialize
-isc_tls_destroy
+isc__tls_initialize
+isc__tls_shutdown
isc_tlsctx_createclient
isc_tlsctx_createserver
isc_tlsctx_free
./lib/isc/tests/uv_wrap.h C 2020,2021
./lib/isc/timer.c C 1998,1999,2000,2001,2002,2004,2005,2007,2008,2009,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
./lib/isc/tls.c C 2021
+./lib/isc/tls_p.h C 2021
./lib/isc/tm.c C 2014,2016,2018,2019,2020,2021
./lib/isc/unix/dir.c C 1999,2000,2001,2004,2005,2007,2008,2009,2011,2012,2016,2017,2018,2019,2020,2021
./lib/isc/unix/errno.c C 2016,2018,2019,2020,2021