diff options
author | Seonah Moon <seonah1.moon@samsung.com> | 2021-01-18 18:38:22 +0900 |
---|---|---|
committer | Seonah Moon <seonah1.moon@samsung.com> | 2021-01-18 18:39:10 +0900 |
commit | a586e92f2093407d29582430ebb69ebfc4756f06 (patch) | |
tree | 28652241164cb1f04a44d7b709ad45bf79d50598 /lib/isc | |
parent | 5341f72ee3d82cab6a4e3459f6f19ee3ecbc6f6c (diff) | |
download | bind-a586e92f2093407d29582430ebb69ebfc4756f06.tar.gz bind-a586e92f2093407d29582430ebb69ebfc4756f06.tar.bz2 bind-a586e92f2093407d29582430ebb69ebfc4756f06.zip |
Imported Upstream version 9.16.8upstream/9.16.8
Change-Id: I122b98d3f939c6e8533ee78070a065b6bec17085
Diffstat (limited to 'lib/isc')
324 files changed, 26139 insertions, 18126 deletions
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index ed87279e..294a1cd8 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -20,13 +20,17 @@ VERSION=@BIND9_VERSION@ CINCLUDES = -I${srcdir}/unix/include \ -I${srcdir}/pthreads/include \ -I./include \ - -I${srcdir}/include ${DNS_INCLUDES} @OPENSSL_INCLUDES@ + -I${srcdir}/include ${DNS_INCLUDES} \ + ${OPENSSL_CFLAGS} \ + ${JSON_C_CFLAGS} \ + ${LIBXML2_CFLAGS} \ + ${ZLIB_CFLAGS} CDEFINES = CWARNINGS = # Alphabetically UNIXOBJS = unix/pk11_api.@O@ \ - unix/app.@O@ unix/dir.@O@ unix/errno.@O@ \ + unix/dir.@O@ unix/errno.@O@ \ unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \ unix/interfaceiter.@O@ unix/meminfo.@O@ \ unix/net.@O@ unix/os.@O@ unix/resource.@O@ unix/socket.@O@ \ @@ -42,45 +46,49 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/errno.@O@ \ # Alphabetically OBJS = pk11.@O@ pk11_result.@O@ \ - aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ + aes.@O@ app.@O@ assertions.@O@ astack.@O@ \ + backtrace.@O@ base32.@O@ base64.@O@ \ bind9.@O@ buffer.@O@ bufferlist.@O@ \ commandline.@O@ counter.@O@ crc64.@O@ error.@O@ entropy.@O@ \ - event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmac.@O@ \ - httpd.@O@ iterated_hash.@O@ \ + event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ \ + hmac.@O@ hp.@O@ httpd.@O@ iterated_hash.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ md.@O@ mem.@O@ mutexblock.@O@ \ + netmgr/netmgr.@O@ netmgr/tcp.@O@ netmgr/udp.@O@ \ + netmgr/tcpdns.@O@ netmgr/uverr2result.@O@ netmgr/uv-compat.@O@ \ netaddr.@O@ netscope.@O@ nonce.@O@ openssl_shim.@O@ pool.@O@ \ - parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ - ratelimiter.@O@ region.@O@ regex.@O@ result.@O@ \ - rwlock.@O@ \ - serial.@O@ sockaddr.@O@ stats.@O@ \ + parseint.@O@ portset.@O@ queue.@O@ quota.@O@ \ + radix.@O@ random.@O@ ratelimiter.@O@ \ + region.@O@ regex.@O@ result.@O@ rwlock.@O@ \ + safe.@O@ serial.@O@ siphash.@O@ sockaddr.@O@ stats.@O@ \ string.@O@ symtab.@O@ task.@O@ taskpool.@O@ \ - tm.@O@ timer.@O@ version.@O@ \ + utf8.@O@ tm.@O@ timer.@O@ version.@O@ \ ${UNIXOBJS} ${THREADOBJS} SYMTBLOBJS = backtrace-emptytbl.@O@ # Alphabetically SRCS = pk11.c pk11_result.c \ - aes.c assertions.c backtrace.c base32.c base64.c bind9.c \ + aes.c app.c assertions.c astack.c \ + backtrace.c base32.c base64.c bind9.c \ buffer.c bufferlist.c commandline.c counter.c crc64.c \ - entropy.c error.c event.c hash.c ht.c heap.c hex.c hmac.c \ - httpd.c iterated_hash.c \ + entropy.c error.c event.c hash.c ht.c heap.c \ + hex.c hmac.c hp.c httpd.c iterated_hash.c \ lex.c lfsr.c lib.c log.c \ md.c mem.c mutexblock.c \ netaddr.c netscope.c nonce.c openssl_shim.c pool.c \ - parseint.c portset.c quota.c radix.c random.c \ + parseint.c portset.c queue.c quota.c radix.c random.c \ ratelimiter.c region.c regex.c result.c rwlock.c \ - serial.c sockaddr.c stats.c string.c \ + safe.c serial.c siphash.c sockaddr.c stats.c string.c \ symtab.c task.c taskpool.c timer.c \ - tm.c version.c + utf8.c tm.c version.c -LIBS = @OPENSSL_LIBS@ @LIBS@ +LIBS = ${OPENSSL_LIBS} ${JSON_C_LIBS} ${LIBUV_LIBS} ${LIBXML2_LIBS} ${ZLIB_LIBS} @LIBS@ # Note: the order of SUBDIRS is important. # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: -SUBDIRS = include unix pthreads +SUBDIRS = include netmgr unix pthreads TARGETS = timestamp TESTDIRS = @UNITTESTS@ diff --git a/lib/isc/aes.c b/lib/isc/aes.c index 38af1b79..2ad03618 100644 --- a/lib/isc/aes.c +++ b/lib/isc/aes.c @@ -3,39 +3,37 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file isc/aes.c */ -#include <config.h> +#include <openssl/evp.h> +#include <openssl/opensslv.h> -#include <isc/assertions.h> #include <isc/aes.h> +#include <isc/assertions.h> #include <isc/platform.h> #include <isc/string.h> #include <isc/types.h> #include <isc/util.h> -#include <openssl/opensslv.h> -#include <openssl/evp.h> - #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -#define EVP_CIPHER_CTX_new() &(_context), EVP_CIPHER_CTX_init(&_context) +#define EVP_CIPHER_CTX_new() &(_context), EVP_CIPHER_CTX_init(&_context) #define EVP_CIPHER_CTX_free(c) RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(c) == 1) -#endif +#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + * defined(LIBRESSL_VERSION_NUMBER) */ void isc_aes128_crypt(const unsigned char *key, const unsigned char *in, - unsigned char *out) -{ + unsigned char *out) { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) EVP_CIPHER_CTX _context; -#endif +#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + * defined(LIBRESSL_VERSION_NUMBER) */ EVP_CIPHER_CTX *c; int len; @@ -43,19 +41,19 @@ isc_aes128_crypt(const unsigned char *key, const unsigned char *in, RUNTIME_CHECK(c != NULL); RUNTIME_CHECK(EVP_EncryptInit(c, EVP_aes_128_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(c, 0); - RUNTIME_CHECK(EVP_EncryptUpdate(c, out, &len, in, - ISC_AES_BLOCK_LENGTH) == 1); + RUNTIME_CHECK( + EVP_EncryptUpdate(c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); EVP_CIPHER_CTX_free(c); } void isc_aes192_crypt(const unsigned char *key, const unsigned char *in, - unsigned char *out) -{ + unsigned char *out) { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) EVP_CIPHER_CTX _context; -#endif +#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + * defined(LIBRESSL_VERSION_NUMBER) */ EVP_CIPHER_CTX *c; int len; @@ -63,19 +61,19 @@ isc_aes192_crypt(const unsigned char *key, const unsigned char *in, RUNTIME_CHECK(c != NULL); RUNTIME_CHECK(EVP_EncryptInit(c, EVP_aes_192_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(c, 0); - RUNTIME_CHECK(EVP_EncryptUpdate(c, out, &len, in, - ISC_AES_BLOCK_LENGTH) == 1); + RUNTIME_CHECK( + EVP_EncryptUpdate(c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); EVP_CIPHER_CTX_free(c); } void isc_aes256_crypt(const unsigned char *key, const unsigned char *in, - unsigned char *out) -{ + unsigned char *out) { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) EVP_CIPHER_CTX _context; -#endif +#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + * defined(LIBRESSL_VERSION_NUMBER) */ EVP_CIPHER_CTX *c; int len; @@ -83,8 +81,8 @@ isc_aes256_crypt(const unsigned char *key, const unsigned char *in, RUNTIME_CHECK(c != NULL); RUNTIME_CHECK(EVP_EncryptInit(c, EVP_aes_256_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(c, 0); - RUNTIME_CHECK(EVP_EncryptUpdate(c, out, &len, in, - ISC_AES_BLOCK_LENGTH) == 1); + RUNTIME_CHECK( + EVP_EncryptUpdate(c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); EVP_CIPHER_CTX_free(c); } diff --git a/lib/isc/api b/lib/isc/api index 0f0b939f..b84f7a84 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -9,6 +9,7 @@ # 9.11: 160-169,1100-1199 # 9.12: 1200-1299 # 9.13/9.14: 1300-1499 -LIBINTERFACE = 1308 -LIBREVISION = 1 +# 9.15/9.16: 1500-1699 +LIBINTERFACE = 1607 +LIBREVISION = 0 LIBAGE = 0 diff --git a/lib/isc/app.c b/lib/isc/app.c new file mode 100644 index 00000000..5a5b533d --- /dev/null +++ b/lib/isc/app.c @@ -0,0 +1,542 @@ +/* + * 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. + */ + +/*! \file */ + +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> + +#ifndef WIN32 +#include <inttypes.h> +#include <signal.h> +#include <sys/time.h> +#endif /* WIN32 */ + +#include <isc/app.h> +#include <isc/atomic.h> +#include <isc/condition.h> +#include <isc/event.h> +#include <isc/mem.h> +#include <isc/mutex.h> +#include <isc/platform.h> +#include <isc/strerr.h> +#include <isc/string.h> +#include <isc/task.h> +#include <isc/thread.h> +#include <isc/time.h> +#include <isc/util.h> + +#ifdef WIN32 +#include <process.h> +#else /* WIN32 */ +#include <pthread.h> +#endif /* WIN32 */ + +/*% + * For BIND9 internal applications built with threads, we use a single app + * context and let multiple worker, I/O, timer threads do actual jobs. + */ + +static isc_thread_t blockedthread; +static atomic_bool is_running; + +#ifdef WIN32 +/* + * We need to remember which thread is the main thread... + */ +static isc_thread_t main_thread; +#endif /* ifdef WIN32 */ + +/* + * The application context of this module. + */ +#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') +#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) + +#ifdef WIN32 +#define NUM_EVENTS 2 + +enum { RELOAD_EVENT, SHUTDOWN_EVENT }; +#endif /* WIN32 */ + +struct isc_appctx { + unsigned int magic; + isc_mem_t *mctx; + isc_mutex_t lock; + isc_eventlist_t on_run; + atomic_bool shutdown_requested; + atomic_bool running; + atomic_bool want_shutdown; + atomic_bool want_reload; + atomic_bool blocked; +#ifdef WIN32 + HANDLE hEvents[NUM_EVENTS]; +#else /* WIN32 */ + isc_mutex_t readylock; + isc_condition_t ready; +#endif /* WIN32 */ +}; + +static isc_appctx_t isc_g_appctx; + +#ifndef WIN32 +static void +handle_signal(int sig, void (*handler)(int)) { + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + + if (sigfillset(&sa.sa_mask) != 0 || sigaction(sig, &sa, NULL) < 0) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "handle_signal() %d setup: %s", sig, strbuf); + } +} +#endif /* ifndef WIN32 */ + +isc_result_t +isc_app_ctxstart(isc_appctx_t *ctx) { + REQUIRE(VALID_APPCTX(ctx)); + + /* + * Start an ISC library application. + */ + + isc_mutex_init(&ctx->lock); + +#ifndef WIN32 + isc_mutex_init(&ctx->readylock); + isc_condition_init(&ctx->ready); +#endif /* WIN32 */ + + ISC_LIST_INIT(ctx->on_run); + + atomic_init(&ctx->shutdown_requested, false); + atomic_init(&ctx->running, false); + atomic_init(&ctx->want_shutdown, false); + atomic_init(&ctx->want_reload, false); + atomic_init(&ctx->blocked, false); + +#ifdef WIN32 + main_thread = GetCurrentThread(); + + /* Create the reload event in a non-signaled state */ + ctx->hEvents[RELOAD_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); + + /* Create the shutdown event in a non-signaled state */ + ctx->hEvents[SHUTDOWN_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); +#else /* WIN32 */ + int presult; + sigset_t sset; + char strbuf[ISC_STRERRORSIZE]; + + /* + * Always ignore SIGPIPE. + */ + handle_signal(SIGPIPE, SIG_IGN); + + handle_signal(SIGHUP, SIG_DFL); + handle_signal(SIGTERM, SIG_DFL); + handle_signal(SIGINT, SIG_DFL); + + /* + * Block SIGHUP, SIGINT, SIGTERM. + * + * If isc_app_start() is called from the main thread before any other + * threads have been created, then the pthread_sigmask() call below + * will result in all threads having SIGHUP, SIGINT and SIGTERM + * blocked by default, ensuring that only the thread that calls + * sigwait() for them will get those signals. + */ + if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || + sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) + { + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "isc_app_start() sigsetops: %s", strbuf); + } + presult = pthread_sigmask(SIG_BLOCK, &sset, NULL); + if (presult != 0) { + strerror_r(presult, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "isc_app_start() pthread_sigmask: %s", strbuf); + } + +#endif /* WIN32 */ + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_app_start(void) { + isc_g_appctx.magic = APPCTX_MAGIC; + isc_g_appctx.mctx = NULL; + /* The remaining members will be initialized in ctxstart() */ + + return (isc_app_ctxstart(&isc_g_appctx)); +} + +isc_result_t +isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, + void *arg) { + return (isc_app_ctxonrun(&isc_g_appctx, mctx, task, action, arg)); +} + +isc_result_t +isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, + isc_taskaction_t action, void *arg) { + isc_event_t *event; + isc_task_t *cloned_task = NULL; + + if (atomic_load_acquire(&ctx->running)) { + return (ISC_R_ALREADYRUNNING); + } + + /* + * Note that we store the task to which we're going to send the event + * in the event's "sender" field. + */ + isc_task_attach(task, &cloned_task); + event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, + action, arg, sizeof(*event)); + + LOCK(&ctx->lock); + ISC_LINK_INIT(event, ev_link); + ISC_LIST_APPEND(ctx->on_run, event, ev_link); + UNLOCK(&ctx->lock); + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_app_ctxrun(isc_appctx_t *ctx) { + isc_event_t *event, *next_event; + isc_task_t *task; + + REQUIRE(VALID_APPCTX(ctx)); + +#ifdef WIN32 + REQUIRE(main_thread == GetCurrentThread()); +#endif /* ifdef WIN32 */ + + if (atomic_compare_exchange_strong_acq_rel(&ctx->running, + &(bool){ false }, true)) + { + /* + * Post any on-run events (in FIFO order). + */ + LOCK(&ctx->lock); + for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; + event = next_event) { + next_event = ISC_LIST_NEXT(event, ev_link); + ISC_LIST_UNLINK(ctx->on_run, event, ev_link); + task = event->ev_sender; + event->ev_sender = NULL; + isc_task_sendanddetach(&task, &event); + } + UNLOCK(&ctx->lock); + } + +#ifndef WIN32 + /* + * BIND9 internal tools using multiple contexts do not + * rely on signal. */ + if (isc_bind9 && ctx != &isc_g_appctx) { + return (ISC_R_SUCCESS); + } +#endif /* WIN32 */ + + /* + * There is no danger if isc_app_shutdown() is called before we + * wait for signals. Signals are blocked, so any such signal will + * simply be made pending and we will get it when we call + * sigwait(). + */ + while (!atomic_load_acquire(&ctx->want_shutdown)) { +#ifdef WIN32 + DWORD dwWaitResult = WaitForMultipleObjects( + NUM_EVENTS, ctx->hEvents, FALSE, INFINITE); + + /* See why we returned */ + + if (WaitSucceeded(dwWaitResult, NUM_EVENTS)) { + /* + * The return was due to one of the events + * being signaled + */ + switch (WaitSucceededIndex(dwWaitResult)) { + case RELOAD_EVENT: + atomic_store_release(&ctx->want_reload, true); + + break; + + case SHUTDOWN_EVENT: + atomic_store_release(&ctx->want_shutdown, true); + break; + } + } +#else /* WIN32 */ + if (isc_bind9) { + sigset_t sset; + int sig; + /* + * BIND9 internal; single context: + * Wait for SIGHUP, SIGINT, or SIGTERM. + */ + if (sigemptyset(&sset) != 0 || + sigaddset(&sset, SIGHUP) != 0 || + sigaddset(&sset, SIGINT) != 0 || + sigaddset(&sset, SIGTERM) != 0) + { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "isc_app_run() sigsetops: %s", + strbuf); + } + + if (sigwait(&sset, &sig) == 0) { + switch (sig) { + case SIGINT: + case SIGTERM: + atomic_store_release( + &ctx->want_shutdown, true); + break; + case SIGHUP: + atomic_store_release(&ctx->want_reload, + true); + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + } + } else { + /* + * External, or BIND9 using multiple contexts: + * wait until woken up. + */ + if (atomic_load_acquire(&ctx->want_shutdown)) { + break; + } + if (!atomic_load_acquire(&ctx->want_reload)) { + LOCK(&ctx->readylock); + WAIT(&ctx->ready, &ctx->readylock); + UNLOCK(&ctx->readylock); + } + } +#endif /* WIN32 */ + if (atomic_compare_exchange_strong_acq_rel( + &ctx->want_reload, &(bool){ true }, false)) + { + return (ISC_R_RELOAD); + } + + if (atomic_load_acquire(&ctx->want_shutdown) && + atomic_load_acquire(&ctx->blocked)) + { + exit(1); + } + } + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_app_run(void) { + isc_result_t result; + + REQUIRE(atomic_compare_exchange_strong_acq_rel(&is_running, + &(bool){ false }, true)); + result = isc_app_ctxrun(&isc_g_appctx); + atomic_store_release(&is_running, false); + + return (result); +} + +bool +isc_app_isrunning() { + return (atomic_load_acquire(&is_running)); +} + +void +isc_app_ctxshutdown(isc_appctx_t *ctx) { + REQUIRE(VALID_APPCTX(ctx)); + + REQUIRE(atomic_load_acquire(&ctx->running)); + + /* If ctx->shutdown_requested == true, we are already shutting + * down and we want to just bail out. + */ + if (atomic_compare_exchange_strong_acq_rel(&ctx->shutdown_requested, + &(bool){ false }, true)) + { +#ifdef WIN32 + SetEvent(ctx->hEvents[SHUTDOWN_EVENT]); +#else /* WIN32 */ + if (isc_bind9 && ctx != &isc_g_appctx) { + /* BIND9 internal, but using multiple contexts */ + atomic_store_release(&ctx->want_shutdown, true); + } else if (isc_bind9) { + /* BIND9 internal, single context */ + if (kill(getpid(), SIGTERM) < 0) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "isc_app_shutdown() " + "kill: %s", + strbuf); + } + } else { + /* External, multiple contexts */ + atomic_store_release(&ctx->want_shutdown, true); + SIGNAL(&ctx->ready); + } +#endif /* WIN32 */ + } +} + +void +isc_app_shutdown(void) { + isc_app_ctxshutdown(&isc_g_appctx); +} + +void +isc_app_ctxsuspend(isc_appctx_t *ctx) { + REQUIRE(VALID_APPCTX(ctx)); + + REQUIRE(atomic_load(&ctx->running)); + + /* + * Don't send the reload signal if we're shutting down. + */ + if (!atomic_load_acquire(&ctx->shutdown_requested)) { +#ifdef WIN32 + SetEvent(ctx->hEvents[RELOAD_EVENT]); +#else /* WIN32 */ + if (isc_bind9 && ctx != &isc_g_appctx) { + /* BIND9 internal, but using multiple contexts */ + atomic_store_release(&ctx->want_reload, true); + } else if (isc_bind9) { + /* BIND9 internal, single context */ + if (kill(getpid(), SIGHUP) < 0) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, + "isc_app_reload() " + "kill: %s", + strbuf); + } + } else { + /* External, multiple contexts */ + atomic_store_release(&ctx->want_reload, true); + SIGNAL(&ctx->ready); + } +#endif /* WIN32 */ + } +} + +void +isc_app_reload(void) { + isc_app_ctxsuspend(&isc_g_appctx); +} + +void +isc_app_ctxfinish(isc_appctx_t *ctx) { + REQUIRE(VALID_APPCTX(ctx)); + + isc_mutex_destroy(&ctx->lock); +#ifndef WIN32 + isc_mutex_destroy(&ctx->readylock); + isc_condition_destroy(&ctx->ready); +#endif /* WIN32 */ +} + +void +isc_app_finish(void) { + isc_app_ctxfinish(&isc_g_appctx); +} + +void +isc_app_block(void) { + REQUIRE(atomic_load_acquire(&isc_g_appctx.running)); + REQUIRE(atomic_compare_exchange_strong_acq_rel(&isc_g_appctx.blocked, + &(bool){ false }, true)); + +#ifdef WIN32 + blockedthread = GetCurrentThread(); +#else /* WIN32 */ + sigset_t sset; + blockedthread = pthread_self(); + RUNTIME_CHECK(sigemptyset(&sset) == 0 && + sigaddset(&sset, SIGINT) == 0 && + sigaddset(&sset, SIGTERM) == 0); + RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0); +#endif /* WIN32 */ +} + +void +isc_app_unblock(void) { + REQUIRE(atomic_load_acquire(&isc_g_appctx.running)); + REQUIRE(atomic_compare_exchange_strong_acq_rel(&isc_g_appctx.blocked, + &(bool){ true }, false)); + +#ifdef WIN32 + REQUIRE(blockedthread == GetCurrentThread()); +#else /* WIN32 */ + REQUIRE(blockedthread == pthread_self()); + + sigset_t sset; + RUNTIME_CHECK(sigemptyset(&sset) == 0 && + sigaddset(&sset, SIGINT) == 0 && + sigaddset(&sset, SIGTERM) == 0); + RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); +#endif /* WIN32 */ +} + +isc_result_t +isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { + isc_appctx_t *ctx; + + REQUIRE(mctx != NULL); + REQUIRE(ctxp != NULL && *ctxp == NULL); + + ctx = isc_mem_get(mctx, sizeof(*ctx)); + + ctx->magic = APPCTX_MAGIC; + + ctx->mctx = NULL; + isc_mem_attach(mctx, &ctx->mctx); + + *ctxp = ctx; + + return (ISC_R_SUCCESS); +} + +void +isc_appctx_destroy(isc_appctx_t **ctxp) { + isc_appctx_t *ctx; + + REQUIRE(ctxp != NULL); + ctx = *ctxp; + *ctxp = NULL; + REQUIRE(VALID_APPCTX(ctx)); + + ctx->magic = 0; + + isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); +} diff --git a/lib/isc/assertions.c b/lib/isc/assertions.c index 8594f1df..1ff44093 100644 --- a/lib/isc/assertions.c +++ b/lib/isc/assertions.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdio.h> #include <stdlib.h> @@ -27,7 +24,7 @@ */ #ifndef BACKTRACE_MAXFRAME #define BACKTRACE_MAXFRAME 128 -#endif +#endif /* ifndef BACKTRACE_MAXFRAME */ /*% * Forward. @@ -45,8 +42,7 @@ static isc_assertioncallback_t isc_assertion_failed_cb = default_callback; /* coverity[+kill] */ void isc_assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ + const char *cond) { isc_assertion_failed_cb(file, line, type, cond); abort(); /* NOTREACHED */ @@ -55,10 +51,11 @@ isc_assertion_failed(const char *file, int line, isc_assertiontype_t type, /*% Set callback. */ void isc_assertion_setcallback(isc_assertioncallback_t cb) { - if (cb == NULL) + if (cb == NULL) { isc_assertion_failed_cb = default_callback; - else + } else { isc_assertion_failed_cb = cb; + } } /*% Type to Text */ @@ -85,7 +82,7 @@ isc_assertion_typetotext(isc_assertiontype_t type) { result = "INVARIANT"; break; default: - result = NULL; + result = "UNKNOWN"; } return (result); } @@ -96,8 +93,7 @@ isc_assertion_typetotext(isc_assertiontype_t type) { static void default_callback(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ + const char *cond) { void *tracebuf[BACKTRACE_MAXFRAME]; int i, nframes; const char *logsuffix = "."; @@ -109,8 +105,8 @@ default_callback(const char *file, int line, isc_assertiontype_t type, logsuffix = ", back trace"; } - fprintf(stderr, "%s:%d: %s(%s) failed%s\n", - file, line, isc_assertion_typetotext(type), cond, logsuffix); + fprintf(stderr, "%s:%d: %s(%s) failed%s\n", file, line, + isc_assertion_typetotext(type), cond, logsuffix); if (result == ISC_R_SUCCESS) { for (i = 0; i < nframes; i++) { diff --git a/lib/isc/astack.c b/lib/isc/astack.c new file mode 100644 index 00000000..d67df511 --- /dev/null +++ b/lib/isc/astack.c @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#include <inttypes.h> +#include <string.h> + +#include <isc/astack.h> +#include <isc/atomic.h> +#include <isc/mem.h> +#include <isc/mutex.h> +#include <isc/types.h> +#include <isc/util.h> + +struct isc_astack { + isc_mem_t *mctx; + size_t size; + size_t pos; + isc_mutex_t lock; + uintptr_t nodes[]; +}; + +isc_astack_t * +isc_astack_new(isc_mem_t *mctx, size_t size) { + isc_astack_t *stack = isc_mem_get( + mctx, sizeof(isc_astack_t) + size * sizeof(uintptr_t)); + + *stack = (isc_astack_t){ + .size = size, + }; + isc_mem_attach(mctx, &stack->mctx); + memset(stack->nodes, 0, size * sizeof(uintptr_t)); + isc_mutex_init(&stack->lock); + return (stack); +} + +bool +isc_astack_trypush(isc_astack_t *stack, void *obj) { + if (!isc_mutex_trylock(&stack->lock)) { + if (stack->pos >= stack->size) { + UNLOCK(&stack->lock); + return (false); + } + stack->nodes[stack->pos++] = (uintptr_t)obj; + UNLOCK(&stack->lock); + return (true); + } else { + return (false); + } +} + +void * +isc_astack_pop(isc_astack_t *stack) { + LOCK(&stack->lock); + uintptr_t rv; + if (stack->pos == 0) { + rv = 0; + } else { + rv = stack->nodes[--stack->pos]; + } + UNLOCK(&stack->lock); + return ((void *)rv); +} + +void +isc_astack_destroy(isc_astack_t *stack) { + LOCK(&stack->lock); + REQUIRE(stack->pos == 0); + UNLOCK(&stack->lock); + + isc_mutex_destroy(&stack->lock); + + isc_mem_putanddetach(&stack->mctx, stack, + sizeof(struct isc_astack) + + stack->size * sizeof(uintptr_t)); +} diff --git a/lib/isc/backtrace-emptytbl.c b/lib/isc/backtrace-emptytbl.c index 5822cfb1..5b5db82b 100644 --- a/lib/isc/backtrace-emptytbl.c +++ b/lib/isc/backtrace-emptytbl.c @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ /* @@ -20,10 +19,9 @@ * (e.g. libisc-nosymbol.a). */ -#include <config.h> - #include <isc/backtrace.h> LIBISC_EXTERNAL_DATA const int isc__backtrace_nsymbols = 0; -LIBISC_EXTERNAL_DATA const - isc_backtrace_symmap_t isc__backtrace_symtable[] = { { NULL, "" } }; +LIBISC_EXTERNAL_DATA const isc_backtrace_symmap_t isc__backtrace_symtable[] = { + { NULL, "" } +}; diff --git a/lib/isc/backtrace.c b/lib/isc/backtrace.c index 7c645d7d..080f32c0 100644 --- a/lib/isc/backtrace.c +++ b/lib/isc/backtrace.c @@ -3,22 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <string.h> #include <stdlib.h> +#include <string.h> #ifdef HAVE_LIBCTRACE #include <execinfo.h> -#endif +#endif /* ifdef HAVE_LIBCTRACE */ #include <isc/backtrace.h> #include <isc/result.h> @@ -49,12 +46,12 @@ #define BACKTRACE_WIN32 #elif defined(__x86_64__) || defined(__i386__) #define BACKTRACE_X86STACK -#else +#else /* ifdef HAVE_LIBCTRACE */ #define BACKTRACE_DISABLED -#endif /* HAVE_LIBCTRACE */ -#else /* USE_BACKTRACE */ +#endif /* HAVE_LIBCTRACE */ +#else /* USE_BACKTRACE */ #define BACKTRACE_DISABLED -#endif /* USE_BACKTRACE */ +#endif /* USE_BACKTRACE */ #ifdef BACKTRACE_LIBC isc_result_t @@ -65,24 +62,28 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { * Validate the arguments: intentionally avoid using REQUIRE(). * See notes in backtrace.h. */ - if (addrs == NULL || nframes == NULL) + if (addrs == NULL || nframes == NULL) { return (ISC_R_FAILURE); + } /* * backtrace(3) includes this function itself in the address array, * which should be eliminated from the returned sequence. */ n = backtrace(addrs, maxaddrs); - if (n < 2) + if (n < 2) { return (ISC_R_NOTFOUND); + } n--; memmove(addrs, &addrs[1], sizeof(void *) * n); *nframes = n; return (ISC_R_SUCCESS); } #elif defined(BACKTRACE_GCC) -extern int _Unwind_Backtrace(void* fn, void* a); -extern void* _Unwind_GetIP(void* ctx); +extern int +_Unwind_Backtrace(void *fn, void *a); +extern void * +_Unwind_GetIP(void *ctx); typedef struct { void **result; @@ -95,13 +96,14 @@ static int btcallback(void *uc, void *opq) { trace_arg_t *arg = (trace_arg_t *)opq; - if (arg->skip_count > 0) + if (arg->skip_count > 0) { arg->skip_count--; - else + } else { arg->result[arg->count++] = (void *)_Unwind_GetIP(uc); - if (arg->count == arg->max_depth) + } + if (arg->count == arg->max_depth) { return (5); /* _URC_END_OF_STACK */ - + } return (0); /* _URC_NO_REASON */ } @@ -110,8 +112,9 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { trace_arg_t arg; /* Argument validation: see above. */ - if (addrs == NULL || nframes == NULL) + if (addrs == NULL || nframes == NULL) { return (ISC_R_FAILURE); + } arg.skip_count = 1; arg.result = addrs; @@ -129,7 +132,7 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { unsigned long ftc = (unsigned long)maxaddrs; *nframes = (int)CaptureStackBackTrace(1, ftc, addrs, NULL); - return ISC_R_SUCCESS; + return (ISC_R_SUCCESS); } #elif defined(BACKTRACE_X86STACK) #ifdef __x86_64__ @@ -137,7 +140,7 @@ static unsigned long getrbp(void) { __asm("movq %rbp, %rax\n"); } -#endif +#endif /* ifdef __x86_64__ */ static void ** getnextframeptr(void **sp) { @@ -149,12 +152,14 @@ getnextframeptr(void **sp) { */ /* prohibit the stack frames from growing downwards */ - if (newsp <= sp) + if (newsp <= sp) { return (NULL); + } /* A heuristics to reject "too large" frame: this actually happened. */ - if ((char *)newsp - (char *)sp > 100000) + if ((char *)newsp - (char *)sp > 100000) { return (NULL); + } /* * Not sure if other checks used in glog are needed at this moment. @@ -171,26 +176,28 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { void **sp; /* Argument validation: see above. */ - if (addrs == NULL || nframes == NULL) + if (addrs == NULL || nframes == NULL) { return (ISC_R_FAILURE); + } #ifdef __x86_64__ sp = (void **)getrbp(); - if (sp == NULL) + if (sp == NULL) { return (ISC_R_NOTFOUND); + } /* * sp is the frame ptr of this function itself due to the call to * getrbp(), so need to unwind one frame for consistency. */ sp = getnextframeptr(sp); -#else +#else /* ifdef __x86_64__ */ /* * i386: the frame pointer is stored 2 words below the address for the * first argument. Note that the body of this function cannot be * inlined since it depends on the address of the function argument. */ sp = (void **)&addrs - 2; -#endif +#endif /* ifdef __x86_64__ */ while (sp != NULL && i < maxaddrs) { addrs[i++] = *(sp + 1); @@ -205,24 +212,25 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { /* Argument validation: see above. */ - if (addrs == NULL || nframes == NULL) + if (addrs == NULL || nframes == NULL) { return (ISC_R_FAILURE); + } UNUSED(maxaddrs); return (ISC_R_NOTIMPLEMENTED); } -#endif +#endif /* ifdef BACKTRACE_LIBC */ isc_result_t isc_backtrace_getsymbolfromindex(int idx, const void **addrp, - const char **symbolp) -{ + const char **symbolp) { REQUIRE(addrp != NULL && *addrp == NULL); REQUIRE(symbolp != NULL && *symbolp == NULL); - if (idx < 0 || idx >= isc__backtrace_nsymbols) + if (idx < 0 || idx >= isc__backtrace_nsymbols) { return (ISC_R_RANGE); + } *addrp = isc__backtrace_symtable[idx].addr; *symbolp = isc__backtrace_symtable[idx].symbol; @@ -248,17 +256,17 @@ symtbl_compare(const void *addr, const void *entryarg) { } /* entry + 1 is a valid entry from now on. */ - if (addr < entry->addr) + if (addr < entry->addr) { return (-1); - else if (addr >= (entry + 1)->addr) + } else if (addr >= (entry + 1)->addr) { return (1); + } return (0); } isc_result_t isc_backtrace_getsymbol(const void *addr, const char **symbolp, - unsigned long *offsetp) -{ + unsigned long *offsetp) { isc_result_t result = ISC_R_SUCCESS; isc_backtrace_symmap_t *found; @@ -266,11 +274,13 @@ isc_backtrace_getsymbol(const void *addr, const char **symbolp, * Validate the arguments: intentionally avoid using REQUIRE(). * See notes in backtrace.h. */ - if (symbolp == NULL || *symbolp != NULL || offsetp == NULL) + if (symbolp == NULL || *symbolp != NULL || offsetp == NULL) { return (ISC_R_FAILURE); + } - if (isc__backtrace_nsymbols < 1) + if (isc__backtrace_nsymbols < 1) { return (ISC_R_NOTFOUND); + } /* * Search the table for the entry that meets: @@ -278,12 +288,12 @@ isc_backtrace_getsymbol(const void *addr, const char **symbolp, */ found = bsearch(addr, isc__backtrace_symtable, isc__backtrace_nsymbols, sizeof(isc__backtrace_symtable[0]), symtbl_compare); - if (found == NULL) + if (found == NULL) { result = ISC_R_NOTFOUND; - else { + } else { *symbolp = found->symbol; - *offsetp = (unsigned long) ((const char *)addr - - (char *)found->addr); + *offsetp = (unsigned long)((const char *)addr - + (char *)found->addr); } return (result); diff --git a/lib/isc/base32.c b/lib/isc/base32.c index 557b543e..8e664753 100644 --- a/lib/isc/base32.c +++ b/lib/isc/base32.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdbool.h> #include <isc/base32.h> @@ -23,13 +20,13 @@ #include <isc/string.h> #include <isc/util.h> -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ +#define RETERR(x) \ + do { \ + isc_result_t _r = (x); \ + if (_r != ISC_R_SUCCESS) \ + return ((_r)); \ } while (0) - /*@{*/ /*! * These static functions are also present in lib/dns/rdata.c. I'm not @@ -43,60 +40,60 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); /*@}*/ -static const char base32[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=abcdefghijklmnopqrstuvwxyz234567"; -static const char base32hex[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv"; +static const char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=" + "abcdefghijklmnopqrstuvwxyz234567"; +static const char base32hex[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV=" + "0123456789abcdefghijklmnopqrstuv"; static isc_result_t base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, - isc_buffer_t *target, const char base[], char pad) -{ + isc_buffer_t *target, const char base[], char pad) { char buf[9]; unsigned int loops = 0; - if (wordlength >= 0 && wordlength < 8) + if (wordlength >= 0 && wordlength < 8) { wordlength = 8; + } memset(buf, 0, sizeof(buf)); while (source->length > 0) { - buf[0] = base[((source->base[0]>>3)&0x1f)]; /* 5 + */ + buf[0] = base[((source->base[0] >> 3) & 0x1f)]; /* 5 + */ if (source->length == 1) { - buf[1] = base[(source->base[0]<<2)&0x1c]; + buf[1] = base[(source->base[0] << 2) & 0x1c]; buf[2] = buf[3] = buf[4] = pad; buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } - buf[1] = base[((source->base[0]<<2)&0x1c)| /* 3 = 8 */ - ((source->base[1]>>6)&0x03)]; /* 2 + */ - buf[2] = base[((source->base[1]>>1)&0x1f)]; /* 5 + */ + buf[1] = base[((source->base[0] << 2) & 0x1c) | /* 3 = 8 */ + ((source->base[1] >> 6) & 0x03)]; /* 2 + */ + buf[2] = base[((source->base[1] >> 1) & 0x1f)]; /* 5 + */ if (source->length == 2) { - buf[3] = base[(source->base[1]<<4)&0x10]; + buf[3] = base[(source->base[1] << 4) & 0x10]; buf[4] = buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } - buf[3] = base[((source->base[1]<<4)&0x10)| /* 1 = 8 */ - ((source->base[2]>>4)&0x0f)]; /* 4 + */ + buf[3] = base[((source->base[1] << 4) & 0x10) | /* 1 = 8 */ + ((source->base[2] >> 4) & 0x0f)]; /* 4 + */ if (source->length == 3) { - buf[4] = base[(source->base[2]<<1)&0x1e]; + buf[4] = base[(source->base[2] << 1) & 0x1e]; buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } - buf[4] = base[((source->base[2]<<1)&0x1e)| /* 4 = 8 */ - ((source->base[3]>>7)&0x01)]; /* 1 + */ - buf[5] = base[((source->base[3]>>2)&0x1f)]; /* 5 + */ + buf[4] = base[((source->base[2] << 1) & 0x1e) | /* 4 = 8 */ + ((source->base[3] >> 7) & 0x01)]; /* 1 + */ + buf[5] = base[((source->base[3] >> 2) & 0x1f)]; /* 5 + */ if (source->length == 4) { - buf[6] = base[(source->base[3]<<3)&0x18]; + buf[6] = base[(source->base[3] << 3) & 0x18]; buf[7] = pad; RETERR(str_totext(buf, target)); break; } - buf[6] = base[((source->base[3]<<3)&0x18)| /* 2 = 8 */ - ((source->base[4]>>5)&0x07)]; /* 3 + */ - buf[7] = base[source->base[4]&0x1f]; /* 5 = 8 */ + buf[6] = base[((source->base[3] << 3) & 0x18) | /* 2 = 8 */ + ((source->base[4] >> 5) & 0x07)]; /* 3 + */ + buf[7] = base[source->base[4] & 0x1f]; /* 5 = 8 */ RETERR(str_totext(buf, target)); isc_region_consume(source, 5); @@ -108,53 +105,51 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, RETERR(str_totext(wordbreak, target)); } } - if (source->length > 0) + if (source->length > 0) { isc_region_consume(source, source->length); + } return (ISC_R_SUCCESS); } isc_result_t -isc_base32_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target) -{ - return (base32_totext(source, wordlength, wordbreak, target, - base32, '=')); +isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target) { + return (base32_totext(source, wordlength, wordbreak, target, base32, + '=')); } isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target) -{ - return (base32_totext(source, wordlength, wordbreak, target, - base32hex, '=')); + const char *wordbreak, isc_buffer_t *target) { + return (base32_totext(source, wordlength, wordbreak, target, base32hex, + '=')); } isc_result_t isc_base32hexnp_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target) -{ - return (base32_totext(source, wordlength, wordbreak, target, - base32hex, 0)); + const char *wordbreak, isc_buffer_t *target) { + return (base32_totext(source, wordlength, wordbreak, target, base32hex, + 0)); } /*% * State of a base32 decoding process in progress. */ typedef struct { - int length; /*%< Desired length of binary data or -1 */ - isc_buffer_t *target; /*%< Buffer for resulting binary data */ - int digits; /*%< Number of buffered base32 digits */ - bool seen_end; /*%< True if "=" end marker seen */ + int length; /*%< Desired length of binary data or -1 */ + isc_buffer_t *target; /*%< Buffer for resulting binary data */ + int digits; /*%< Number of buffered base32 digits */ + bool seen_end; /*%< True if "=" end marker seen */ int val[8]; - const char *base; /*%< Which encoding we are using */ - int seen_32; /*%< Number of significant bytes if non zero */ - bool pad; /*%< Expect padding */ + const char *base; /*%< Which encoding we are using */ + int seen_32; /*%< Number of significant bytes if non + * zero */ + bool pad; /*%< Expect padding */ } base32_decode_ctx_t; static inline void base32_decode_init(base32_decode_ctx_t *ctx, int length, const char base[], - bool pad, isc_buffer_t *target) -{ + bool pad, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = false; ctx->seen_32 = 0; @@ -169,65 +164,75 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { const char *s; unsigned int last; - if (ctx->seen_end) + if (ctx->seen_end) { return (ISC_R_BADBASE32); - if ((s = strchr(ctx->base, c)) == NULL) + } + if ((s = strchr(ctx->base, c)) == NULL) { return (ISC_R_BADBASE32); + } last = (unsigned int)(s - ctx->base); /* * Handle lower case. */ - if (last > 32) + if (last > 32) { last -= 33; + } /* * Check that padding is contiguous. */ - if (last != 32 && ctx->seen_32 != 0) + if (last != 32 && ctx->seen_32 != 0) { return (ISC_R_BADBASE32); + } /* * If padding is not permitted flag padding as a error. */ - if (last == 32 && !ctx->pad) + if (last == 32 && !ctx->pad) { return (ISC_R_BADBASE32); + } /* * Check that padding starts at the right place and that * bits that should be zero are. * Record how many significant bytes in answer (seen_32). */ - if (last == 32 && ctx->seen_32 == 0) + if (last == 32 && ctx->seen_32 == 0) { switch (ctx->digits) { case 0: case 1: return (ISC_R_BADBASE32); case 2: - if ((ctx->val[1]&0x03) != 0) + if ((ctx->val[1] & 0x03) != 0) { return (ISC_R_BADBASE32); + } ctx->seen_32 = 1; break; case 3: return (ISC_R_BADBASE32); case 4: - if ((ctx->val[3]&0x0f) != 0) + if ((ctx->val[3] & 0x0f) != 0) { return (ISC_R_BADBASE32); - ctx->seen_32 = 3; + } + ctx->seen_32 = 2; break; case 5: - if ((ctx->val[4]&0x01) != 0) + if ((ctx->val[4] & 0x01) != 0) { return (ISC_R_BADBASE32); + } ctx->seen_32 = 3; break; case 6: return (ISC_R_BADBASE32); case 7: - if ((ctx->val[6]&0x07) != 0) + if ((ctx->val[6] & 0x07) != 0) { return (ISC_R_BADBASE32); + } ctx->seen_32 = 4; break; } + } /* * Zero fill pad values. @@ -242,17 +247,20 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { ctx->seen_end = true; n = ctx->seen_32; } - buf[0] = (ctx->val[0]<<3)|(ctx->val[1]>>2); - buf[1] = (ctx->val[1]<<6)|(ctx->val[2]<<1)|(ctx->val[3]>>4); - buf[2] = (ctx->val[3]<<4)|(ctx->val[4]>>1); - buf[3] = (ctx->val[4]<<7)|(ctx->val[5]<<2)|(ctx->val[6]>>3); - buf[4] = (ctx->val[6]<<5)|(ctx->val[7]); + buf[0] = (ctx->val[0] << 3) | (ctx->val[1] >> 2); + buf[1] = (ctx->val[1] << 6) | (ctx->val[2] << 1) | + (ctx->val[3] >> 4); + buf[2] = (ctx->val[3] << 4) | (ctx->val[4] >> 1); + buf[3] = (ctx->val[4] << 7) | (ctx->val[5] << 2) | + (ctx->val[6] >> 3); + buf[4] = (ctx->val[6] << 5) | (ctx->val[7]); RETERR(mem_tobuffer(ctx->target, buf, n)); if (ctx->length >= 0) { - if (n > ctx->length) + if (n > ctx->length) { return (ISC_R_BADBASE32); - else + } else { ctx->length -= n; + } } ctx->digits = 0; } @@ -261,9 +269,9 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { static inline isc_result_t base32_decode_finish(base32_decode_ctx_t *ctx) { - - if (ctx->length > 0) + if (ctx->length > 0) { return (ISC_R_UNEXPECTEDEND); + } /* * Add missing padding if required. */ @@ -273,15 +281,15 @@ base32_decode_finish(base32_decode_ctx_t *ctx) { RETERR(base32_decode_char(ctx, '=')); } while (ctx->digits != 0); } - if (ctx->digits != 0) + if (ctx->digits != 0) { return (ISC_R_BADBASE32); + } return (ISC_R_SUCCESS); } static isc_result_t base32_tobuffer(isc_lex_t *lexer, const char base[], bool pad, - isc_buffer_t *target, int length) -{ + isc_buffer_t *target, int length) { unsigned int before, after; base32_decode_ctx_t ctx; isc_textregion_t *tr; @@ -339,17 +347,18 @@ isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { static isc_result_t base32_decodestring(const char *cstr, const char base[], bool pad, - isc_buffer_t *target) -{ + isc_buffer_t *target) { base32_decode_ctx_t ctx; base32_decode_init(&ctx, -1, base, pad, target); for (;;) { int c = *cstr++; - if (c == '\0') + if (c == '\0') { break; - if (c == ' ' || c == '\t' || c == '\n' || c== '\r') + } + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { continue; + } RETERR(base32_decode_char(&ctx, c)); } RETERR(base32_decode_finish(&ctx)); @@ -372,9 +381,8 @@ isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target) { } static isc_result_t -base32_decoderegion(isc_region_t *source, const char base[], - bool pad, isc_buffer_t *target) -{ +base32_decoderegion(isc_region_t *source, const char base[], bool pad, + isc_buffer_t *target) { base32_decode_ctx_t ctx; base32_decode_init(&ctx, -1, base, pad, target); @@ -410,8 +418,9 @@ str_totext(const char *source, isc_buffer_t *target) { isc_buffer_availableregion(target, ®ion); l = strlen(source); - if (l > region.length) + if (l > region.length) { return (ISC_R_NOSPACE); + } memmove(region.base, source, l); isc_buffer_add(target, l); @@ -423,8 +432,9 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); - if (length > tr.length) + if (length > tr.length) { return (ISC_R_NOSPACE); + } memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); diff --git a/lib/isc/base64.c b/lib/isc/base64.c index 1eaf0141..a1a34e1d 100644 --- a/lib/isc/base64.c +++ b/lib/isc/base64.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdbool.h> #include <isc/base64.h> @@ -22,13 +19,13 @@ #include <isc/string.h> #include <isc/util.h> -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ +#define RETERR(x) \ + do { \ + isc_result_t _r = (x); \ + if (_r != ISC_R_SUCCESS) \ + return ((_r)); \ } while (0) - /*@{*/ /*! * These static functions are also present in lib/dns/rdata.c. I'm not @@ -40,50 +37,49 @@ str_totext(const char *source, isc_buffer_t *target); static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); -static const char base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw" + "xyz0123456789+/="; /*@}*/ isc_result_t -isc_base64_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target) -{ +isc_base64_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target) { char buf[5]; unsigned int loops = 0; - if (wordlength < 4) + if (wordlength < 4) { wordlength = 4; + } memset(buf, 0, sizeof(buf)); while (source->length > 2) { - buf[0] = base64[(source->base[0]>>2)&0x3f]; - buf[1] = base64[((source->base[0]<<4)&0x30)| - ((source->base[1]>>4)&0x0f)]; - buf[2] = base64[((source->base[1]<<2)&0x3c)| - ((source->base[2]>>6)&0x03)]; - buf[3] = base64[source->base[2]&0x3f]; + buf[0] = base64[(source->base[0] >> 2) & 0x3f]; + buf[1] = base64[((source->base[0] << 4) & 0x30) | + ((source->base[1] >> 4) & 0x0f)]; + buf[2] = base64[((source->base[1] << 2) & 0x3c) | + ((source->base[2] >> 6) & 0x03)]; + buf[3] = base64[source->base[2] & 0x3f]; RETERR(str_totext(buf, target)); isc_region_consume(source, 3); loops++; - if (source->length != 0 && - (int)((loops + 1) * 4) >= wordlength) + if (source->length != 0 && (int)((loops + 1) * 4) >= wordlength) { loops = 0; RETERR(str_totext(wordbreak, target)); } } if (source->length == 2) { - buf[0] = base64[(source->base[0]>>2)&0x3f]; - buf[1] = base64[((source->base[0]<<4)&0x30)| - ((source->base[1]>>4)&0x0f)]; - buf[2] = base64[((source->base[1]<<2)&0x3c)]; + buf[0] = base64[(source->base[0] >> 2) & 0x3f]; + buf[1] = base64[((source->base[0] << 4) & 0x30) | + ((source->base[1] >> 4) & 0x0f)]; + buf[2] = base64[((source->base[1] << 2) & 0x3c)]; buf[3] = '='; RETERR(str_totext(buf, target)); isc_region_consume(source, 2); } else if (source->length == 1) { - buf[0] = base64[(source->base[0]>>2)&0x3f]; - buf[1] = base64[((source->base[0]<<4)&0x30)]; + buf[0] = base64[(source->base[0] >> 2) & 0x3f]; + buf[1] = base64[((source->base[0] << 4) & 0x30)]; buf[2] = buf[3] = '='; RETERR(str_totext(buf, target)); isc_region_consume(source, 1); @@ -95,16 +91,15 @@ isc_base64_totext(isc_region_t *source, int wordlength, * State of a base64 decoding process in progress. */ typedef struct { - int length; /*%< Desired length of binary data or -1 */ - isc_buffer_t *target; /*%< Buffer for resulting binary data */ - int digits; /*%< Number of buffered base64 digits */ - bool seen_end; /*%< True if "=" end marker seen */ + int length; /*%< Desired length of binary data or -1 */ + isc_buffer_t *target; /*%< Buffer for resulting binary data */ + int digits; /*%< Number of buffered base64 digits */ + bool seen_end; /*%< True if "=" end marker seen */ int val[4]; } base64_decode_ctx_t; static inline void -base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target) -{ +base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = false; ctx->length = length; @@ -115,47 +110,55 @@ static inline isc_result_t base64_decode_char(base64_decode_ctx_t *ctx, int c) { const char *s; - if (ctx->seen_end) + if (ctx->seen_end) { return (ISC_R_BADBASE64); - if ((s = strchr(base64, c)) == NULL) + } + if ((s = strchr(base64, c)) == NULL) { return (ISC_R_BADBASE64); + } ctx->val[ctx->digits++] = (int)(s - base64); if (ctx->digits == 4) { int n; unsigned char buf[3]; - if (ctx->val[0] == 64 || ctx->val[1] == 64) + if (ctx->val[0] == 64 || ctx->val[1] == 64) { return (ISC_R_BADBASE64); - if (ctx->val[2] == 64 && ctx->val[3] != 64) + } + if (ctx->val[2] == 64 && ctx->val[3] != 64) { return (ISC_R_BADBASE64); + } /* * Check that bits that should be zero are. */ - if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0) + if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0) { return (ISC_R_BADBASE64); + } /* * We don't need to test for ctx->val[2] != 64 as * the bottom two bits of 64 are zero. */ - if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0) + if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0) { return (ISC_R_BADBASE64); - n = (ctx->val[2] == 64) ? 1 : - (ctx->val[3] == 64) ? 2 : 3; + } + n = (ctx->val[2] == 64) ? 1 : (ctx->val[3] == 64) ? 2 : 3; if (n != 3) { ctx->seen_end = true; - if (ctx->val[2] == 64) + if (ctx->val[2] == 64) { ctx->val[2] = 0; - if (ctx->val[3] == 64) + } + if (ctx->val[3] == 64) { ctx->val[3] = 0; + } } - buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4); - buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2); - buf[2] = (ctx->val[2]<<6)|(ctx->val[3]); + buf[0] = (ctx->val[0] << 2) | (ctx->val[1] >> 4); + buf[1] = (ctx->val[1] << 4) | (ctx->val[2] >> 2); + buf[2] = (ctx->val[2] << 6) | (ctx->val[3]); RETERR(mem_tobuffer(ctx->target, buf, n)); if (ctx->length >= 0) { - if (n > ctx->length) + if (n > ctx->length) { return (ISC_R_BADBASE64); - else + } else { ctx->length -= n; + } } ctx->digits = 0; } @@ -164,10 +167,12 @@ base64_decode_char(base64_decode_ctx_t *ctx, int c) { static inline isc_result_t base64_decode_finish(base64_decode_ctx_t *ctx) { - if (ctx->length > 0) + if (ctx->length > 0) { return (ISC_R_UNEXPECTEDEND); - if (ctx->digits != 0) + } + if (ctx->digits != 0) { return (ISC_R_BADBASE64); + } return (ISC_R_SUCCESS); } @@ -220,10 +225,12 @@ isc_base64_decodestring(const char *cstr, isc_buffer_t *target) { base64_decode_init(&ctx, -1, target); for (;;) { int c = *cstr++; - if (c == '\0') + if (c == '\0') { break; - if (c == ' ' || c == '\t' || c == '\n' || c== '\r') + } + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { continue; + } RETERR(base64_decode_char(&ctx, c)); } RETERR(base64_decode_finish(&ctx)); @@ -238,8 +245,9 @@ str_totext(const char *source, isc_buffer_t *target) { isc_buffer_availableregion(target, ®ion); l = strlen(source); - if (l > region.length) + if (l > region.length) { return (ISC_R_NOSPACE); + } memmove(region.base, source, l); isc_buffer_add(target, l); @@ -251,8 +259,9 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); - if (length > tr.length) + if (length > tr.length) { return (ISC_R_NOSPACE); + } memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); diff --git a/lib/isc/bind9.c b/lib/isc/bind9.c index e5b2fefc..1ab9d3e8 100644 --- a/lib/isc/bind9.c +++ b/lib/isc/bind9.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,6 @@ /*! \file */ -#include <config.h> - #include <stdbool.h> #include <isc/bind9.h> diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c index 987795be..1db0eb02 100644 --- a/lib/isc/buffer.c +++ b/lib/isc/buffer.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,11 +11,9 @@ /*! \file */ -#include <config.h> - #include <inttypes.h> -#include <stdbool.h> #include <stdarg.h> +#include <stdbool.h> #include <isc/buffer.h> #include <isc/mem.h> @@ -262,10 +260,11 @@ isc_buffer_compact(isc_buffer_t *b) { (void)memmove(b->base, src, (size_t)length); } - if (b->active > b->current) + if (b->active > b->current) { b->active -= b->current; - else + } else { b->active = 0; + } b->current = 0; b->used = length; } @@ -431,8 +430,7 @@ isc__buffer_putuint48(isc_buffer_t *b, uint64_t val) { void isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, - unsigned int length) -{ + unsigned int length) { isc_result_t result; REQUIRE(ISC_BUFFER_VALID(b)); if (ISC_UNLIKELY(b->autore)) { @@ -470,7 +468,7 @@ isc__buffer_putstr(isc_buffer_t *b, const char *source) { void isc_buffer_putdecint(isc_buffer_t *b, int64_t v) { - unsigned int l=0; + unsigned int l = 0; unsigned char *cp; char buf[21]; isc_result_t result; @@ -502,9 +500,7 @@ isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src) { isc_buffer_usedregion(src, ®ion); - result = isc_buffer_allocate(mctx, &dst, region.length); - if (result != ISC_R_SUCCESS) - return (result); + isc_buffer_allocate(mctx, &dst, region.length); result = isc_buffer_copyregion(dst, ®ion); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */ @@ -538,33 +534,21 @@ isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { return (ISC_R_SUCCESS); } -isc_result_t +void isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, - unsigned int length) -{ - isc_buffer_t *dbuf; - unsigned char * bdata; - REQUIRE(dynbuffer != NULL); - REQUIRE(*dynbuffer == NULL); + unsigned int length) { + REQUIRE(dynbuffer != NULL && *dynbuffer == NULL); - dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t)); - if (dbuf == NULL) - return (ISC_R_NOMEMORY); - - bdata = isc_mem_get(mctx, length); - if (bdata == NULL) { - isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t)); - return (ISC_R_NOMEMORY); - } + isc_buffer_t *dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t)); + unsigned char *bdata = isc_mem_get(mctx, length); isc_buffer_init(dbuf, bdata, length); - dbuf->mctx = mctx; ENSURE(ISC_BUFFER_VALID(dbuf)); - *dynbuffer = dbuf; + dbuf->mctx = mctx; - return (ISC_R_SUCCESS); + *dynbuffer = dbuf; } isc_result_t @@ -602,17 +586,14 @@ isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) { * it doesn't remap pages, but does ordinary copy. So is * isc_mem_reallocate(), which has additional issues. */ - bdata = isc_mem_get((*dynbuffer)->mctx, (unsigned int) len); - if (bdata == NULL) { - return (ISC_R_NOMEMORY); - } + bdata = isc_mem_get((*dynbuffer)->mctx, (unsigned int)len); memmove(bdata, (*dynbuffer)->base, (*dynbuffer)->length); isc_mem_put((*dynbuffer)->mctx, (*dynbuffer)->base, (*dynbuffer)->length); (*dynbuffer)->base = bdata; - (*dynbuffer)->length = (unsigned int) len; + (*dynbuffer)->length = (unsigned int)len; return (ISC_R_SUCCESS); } @@ -627,7 +608,7 @@ isc_buffer_free(isc_buffer_t **dynbuffer) { REQUIRE((*dynbuffer)->mctx != NULL); dbuf = *dynbuffer; - *dynbuffer = NULL; /* destroy external reference */ + *dynbuffer = NULL; /* destroy external reference */ mctx = dbuf->mctx; dbuf->mctx = NULL; diff --git a/lib/isc/bufferlist.c b/lib/isc/bufferlist.c index f6ebdea6..8393d1da 100644 --- a/lib/isc/bufferlist.c +++ b/lib/isc/bufferlist.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stddef.h> #include <isc/buffer.h> diff --git a/lib/isc/commandline.c b/lib/isc/commandline.c index 6f256928..037552d8 100644 --- a/lib/isc/commandline.c +++ b/lib/isc/commandline.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -38,7 +38,6 @@ * SUCH DAMAGE. */ - /*! \file * This file was adapted from the NetBSD project's source tree, RCS ID: * NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp @@ -47,8 +46,6 @@ * and format in the ISC coding style. */ -#include <config.h> - #include <stdbool.h> #include <stdio.h> @@ -73,18 +70,18 @@ LIBISC_EXTERNAL_DATA bool isc_commandline_reset = true; static char endopt = '\0'; -#define BADOPT '?' -#define BADARG ':' -#define ENDOPT &endopt +#define BADOPT '?' +#define BADARG ':' +#define ENDOPT &endopt /*! * getopt -- * Parse argc/argv argument vector. */ int -isc_commandline_parse(int argc, char * const *argv, const char *options) { +isc_commandline_parse(int argc, char *const *argv, const char *options) { static char *place = ENDOPT; - const char *option; /* Index into *options of option. */ + const char *option; /* Index into *options of option. */ REQUIRE(argc >= 0 && argv != NULL && options != NULL); @@ -98,11 +95,13 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) { isc_commandline_reset = false; } - if (isc_commandline_progname == NULL) + if (isc_commandline_progname == NULL) { isc_commandline_progname = argv[0]; + } if (isc_commandline_index >= argc || - *(place = argv[isc_commandline_index]) != '-') { + *(place = argv[isc_commandline_index]) != '-') + { /* * Index out of range or points to non-option. */ @@ -130,13 +129,15 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) { * distinguish ':' from the argument specifier in the options string. */ if (isc_commandline_option == ':' || option == NULL) { - if (*place == '\0') + if (*place == '\0') { isc_commandline_index++; + } - if (isc_commandline_errprint && *options != ':') + if (isc_commandline_errprint && *options != ':') { fprintf(stderr, "%s: illegal option -- %c\n", isc_commandline_progname, isc_commandline_option); + } return (BADOPT); } @@ -150,26 +151,24 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) { /* * Skip to next argv if at the end of the current argv. */ - if (*place == '\0') + if (*place == '\0') { ++isc_commandline_index; - + } } else { /* * Option needs an argument. */ - if (*place != '\0') + if (*place != '\0') { /* * Option is in this argv, -D1 style. */ isc_commandline_argument = place; - - else if (argc > ++isc_commandline_index) + } else if (argc > ++isc_commandline_index) { /* * Option is next argv, -D 1 style. */ isc_commandline_argument = argv[isc_commandline_index]; - - else { + } else { /* * Argument needed, but no more argv. */ @@ -179,13 +178,17 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) { * Silent failure with "missing argument" return * when ':' starts options string, per historical spec. */ - if (*options == ':') + if (*options == ':') { return (BADARG); + } - if (isc_commandline_errprint) - fprintf(stderr, "%s: option requires an argument -- %c\n", + if (isc_commandline_errprint) { + fprintf(stderr, + "%s: option requires an argument -- " + "%c\n", isc_commandline_progname, isc_commandline_option); + } return (BADOPT); } @@ -203,21 +206,19 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) { isc_result_t isc_commandline_strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, - char ***argvp, unsigned int n) -{ + char ***argvp, unsigned int n) { isc_result_t result; - restart: +restart: /* Discard leading whitespace. */ - while (*s == ' ' || *s == '\t') + while (*s == ' ' || *s == '\t') { s++; + } if (*s == '\0') { /* We have reached the end of the string. */ *argcp = n; *argvp = isc_mem_get(mctx, n * sizeof(char *)); - if (*argvp == NULL) - return (ISC_R_NOMEMORY); } else { char *p = s; while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') { @@ -236,7 +237,7 @@ isc_commandline_strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, */ while (*t != '\0') { t++; - *(t-1) = *t; + *(t - 1) = *t; } while (*p != '\0' && *p != '}') { p++; @@ -247,13 +248,15 @@ isc_commandline_strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, p++; } /* normal case, no "grouping" */ - } else if (*p != '\0') + } else if (*p != '\0') { *p++ = '\0'; + } - result = isc_commandline_strtoargv(mctx, p, - argcp, argvp, n + 1); - if (result != ISC_R_SUCCESS) + result = isc_commandline_strtoargv(mctx, p, argcp, argvp, + n + 1); + if (result != ISC_R_SUCCESS) { return (result); + } (*argvp)[n] = s; } diff --git a/lib/isc/counter.c b/lib/isc/counter.c index 5dbf93e0..7c46a712 100644 --- a/lib/isc/counter.c +++ b/lib/isc/counter.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,6 @@ /*! \file */ -#include <config.h> - #include <stdbool.h> #include <stddef.h> @@ -20,17 +18,18 @@ #include <isc/counter.h> #include <isc/magic.h> #include <isc/mem.h> +#include <isc/refcount.h> #include <isc/util.h> -#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r') -#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC) +#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r') +#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC) struct isc_counter { - unsigned int magic; - isc_mem_t *mctx; - atomic_uint_fast32_t references; - atomic_uint_fast32_t limit; - atomic_uint_fast32_t used; + unsigned int magic; + isc_mem_t *mctx; + isc_refcount_t references; + atomic_uint_fast32_t limit; + atomic_uint_fast32_t used; }; isc_result_t @@ -40,15 +39,13 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) { REQUIRE(counterp != NULL && *counterp == NULL); counter = isc_mem_get(mctx, sizeof(*counter)); - if (counter == NULL) - return (ISC_R_NOMEMORY); counter->mctx = NULL; isc_mem_attach(mctx, &counter->mctx); - atomic_store(&counter->references, 1); - atomic_store(&counter->limit, limit); - atomic_store(&counter->used, 0); + isc_refcount_init(&counter->references, 1); + atomic_init(&counter->limit, limit); + atomic_init(&counter->used, 0); counter->magic = COUNTER_MAGIC; *counterp = counter; @@ -57,22 +54,21 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) { isc_result_t isc_counter_increment(isc_counter_t *counter) { - isc_result_t result = ISC_R_SUCCESS; + uint32_t used = atomic_fetch_add_relaxed(&counter->used, 1) + 1; + uint32_t limit = atomic_load_acquire(&counter->limit); - uint32_t used = atomic_fetch_add(&counter->used, 1) + 1; - if (atomic_load(&counter->limit) != 0 && - used >= atomic_load(&counter->limit)) { - result = ISC_R_QUOTA; + if (limit != 0 && used >= limit) { + return (ISC_R_QUOTA); } - return (result); + return (ISC_R_SUCCESS); } unsigned int isc_counter_used(isc_counter_t *counter) { REQUIRE(VALID_COUNTER(counter)); - return (atomic_load(&counter->used)); + return (atomic_load_acquire(&counter->used)); } void @@ -87,13 +83,14 @@ isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) { REQUIRE(VALID_COUNTER(source)); REQUIRE(targetp != NULL && *targetp == NULL); - INSIST(atomic_fetch_add(&source->references, 1) > 0); + isc_refcount_increment(&source->references); *targetp = source; } static void destroy(isc_counter_t *counter) { + isc_refcount_destroy(&counter->references); counter->magic = 0; isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter)); } @@ -101,18 +98,13 @@ destroy(isc_counter_t *counter) { void isc_counter_detach(isc_counter_t **counterp) { isc_counter_t *counter; - uint32_t oldrefs; REQUIRE(counterp != NULL && *counterp != NULL); counter = *counterp; - REQUIRE(VALID_COUNTER(counter)); - *counterp = NULL; + REQUIRE(VALID_COUNTER(counter)); - oldrefs = atomic_fetch_sub(&counter->references, 1); - INSIST(oldrefs > 0); - - if (oldrefs == 1) { + if (isc_refcount_decrement(&counter->references) == 1) { destroy(counter); } } diff --git a/lib/isc/crc64.c b/lib/isc/crc64.c index 847bef39..0c00d1c0 100644 --- a/lib/isc/crc64.c +++ b/lib/isc/crc64.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <inttypes.h> #include <isc/assertions.h> @@ -107,8 +105,8 @@ static const uint64_t crc64_table[256] = { 0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL, 0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL, 0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL, - 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, - 0xD80C07CD676F8394ULL, 0x9AFCE626CE85B507ULL + 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL, + 0x9AFCE626CE85B507ULL }; void @@ -127,12 +125,11 @@ isc_crc64_update(uint64_t *crc, const void *data, size_t len) { REQUIRE(data != NULL); while (len-- > 0U) { - i = ((int) (*crc >> 56) ^ *p++) & 0xff; + i = ((int)(*crc >> 56) ^ *p++) & 0xff; *crc = crc64_table[i] ^ (*crc << 8); } } - void isc_crc64_final(uint64_t *crc) { REQUIRE(crc != NULL); diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c index c75a297b..b31528a8 100644 --- a/lib/isc/entropy.c +++ b/lib/isc/entropy.c @@ -3,28 +3,24 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> +#include <openssl/err.h> +#include <openssl/rand.h> -#include <isc/util.h> #include <isc/types.h> +#include <isc/util.h> #include "entropy_private.h" -#include <openssl/rand.h> -#include <openssl/err.h> - void isc_entropy_get(void *buf, size_t buflen) { if (RAND_bytes(buf, buflen) < 1) { - FATAL_ERROR(__FILE__, - __LINE__, - "RAND_bytes(): %s", + FATAL_ERROR(__FILE__, __LINE__, "RAND_bytes(): %s", ERR_error_string(ERR_get_error(), NULL)); } } diff --git a/lib/isc/entropy_private.h b/lib/isc/entropy_private.h index f9133c74..34cc3395 100644 --- a/lib/isc/entropy_private.h +++ b/lib/isc/entropy_private.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/error.c b/lib/isc/error.c index 438a8af1..cf76a73f 100644 --- a/lib/isc/error.c +++ b/lib/isc/error.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdio.h> #include <stdlib.h> @@ -23,12 +20,12 @@ /*% Default unexpected callback. */ static void default_unexpected_callback(const char *, int, const char *, va_list) - ISC_FORMAT_PRINTF(3, 0); + ISC_FORMAT_PRINTF(3, 0); /*% Default fatal callback. */ static void default_fatal_callback(const char *, int, const char *, va_list) - ISC_FORMAT_PRINTF(3, 0); + ISC_FORMAT_PRINTF(3, 0); /*% unexpected_callback */ static isc_errorcallback_t unexpected_callback = default_unexpected_callback; @@ -36,18 +33,20 @@ static isc_errorcallback_t fatal_callback = default_fatal_callback; void isc_error_setunexpected(isc_errorcallback_t cb) { - if (cb == NULL) + if (cb == NULL) { unexpected_callback = default_unexpected_callback; - else + } else { unexpected_callback = cb; + } } void isc_error_setfatal(isc_errorcallback_t cb) { - if (cb == NULL) + if (cb == NULL) { fatal_callback = default_fatal_callback; - else + } else { fatal_callback = cb; + } } void @@ -76,8 +75,7 @@ isc_error_runtimecheck(const char *file, int line, const char *expression) { static void default_unexpected_callback(const char *file, int line, const char *format, - va_list args) -{ + va_list args) { fprintf(stderr, "%s:%d: ", file, line); vfprintf(stderr, format, args); fprintf(stderr, "\n"); @@ -86,8 +84,7 @@ default_unexpected_callback(const char *file, int line, const char *format, static void default_fatal_callback(const char *file, int line, const char *format, - va_list args) -{ + va_list args) { fprintf(stderr, "%s:%d: fatal error: ", file, line); vfprintf(stderr, format, args); fprintf(stderr, "\n"); diff --git a/lib/isc/event.c b/lib/isc/event.c index 500b6fdc..71462db9 100644 --- a/lib/isc/event.c +++ b/lib/isc/event.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! * \file */ -#include <config.h> - #include <isc/event.h> #include <isc/mem.h> #include <isc/util.h> @@ -33,27 +30,23 @@ destroy(isc_event_t *event) { isc_event_t * isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, - isc_taskaction_t action, void *arg, size_t size) -{ + isc_taskaction_t action, void *arg, size_t size) { isc_event_t *event; REQUIRE(size >= sizeof(struct isc_event)); REQUIRE(action != NULL); event = isc_mem_get(mctx, size); - if (event == NULL) - return (NULL); - ISC_EVENT_INIT(event, size, 0, NULL, type, action, arg, - sender, destroy, mctx); + ISC_EVENT_INIT(event, size, 0, NULL, type, action, arg, sender, destroy, + mctx); return (event); } isc_event_t * isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, - isc_taskaction_t action, const void *arg, size_t size) -{ + isc_taskaction_t action, const void *arg, size_t size) { isc_event_t *event; void *deconst_arg; @@ -61,8 +54,6 @@ isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, REQUIRE(action != NULL); event = isc_mem_get(mctx, size); - if (event == NULL) - return (NULL); /* * Removing the const attribute from "arg" is the best of two @@ -78,8 +69,8 @@ isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, */ DE_CONST(arg, deconst_arg); - ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg, - sender, destroy, mctx); + ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg, sender, + destroy, mctx); return (event); } @@ -90,13 +81,13 @@ isc_event_free(isc_event_t **eventp) { REQUIRE(eventp != NULL); event = *eventp; + *eventp = NULL; REQUIRE(event != NULL); REQUIRE(!ISC_LINK_LINKED(event, ev_link)); REQUIRE(!ISC_LINK_LINKED(event, ev_ratelink)); - if (event->ev_destroy != NULL) + if (event->ev_destroy != NULL) { (event->ev_destroy)(event); - - *eventp = NULL; + } } diff --git a/lib/isc/fsaccess.c b/lib/isc/fsaccess.c index 595ece55..2fa14868 100644 --- a/lib/isc/fsaccess.c +++ b/lib/isc/fsaccess.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - /*! \file * \brief * This file contains the OS-independent functionality of the API. @@ -27,23 +25,26 @@ * <isc/fsaccess.h>. Could check consistency with sizeof(isc_fsaccess_t) * and the number of bits in each function. */ -#define STEP (ISC__FSACCESS_PERMISSIONBITS) -#define GROUP (STEP) -#define OTHER (STEP * 2) +#define STEP (ISC__FSACCESS_PERMISSIONBITS) +#define GROUP (STEP) +#define OTHER (STEP * 2) void isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access) { REQUIRE(trustee <= 0x7); REQUIRE(permission <= 0xFF); - if ((trustee & ISC_FSACCESS_OWNER) != 0) + if ((trustee & ISC_FSACCESS_OWNER) != 0) { *access |= permission; + } - if ((trustee & ISC_FSACCESS_GROUP) != 0) + if ((trustee & ISC_FSACCESS_GROUP) != 0) { *access |= (permission << GROUP); + } - if ((trustee & ISC_FSACCESS_OTHER) != 0) + if ((trustee & ISC_FSACCESS_OTHER) != 0) { *access |= (permission << OTHER); + } } void @@ -51,15 +52,17 @@ isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access) { REQUIRE(trustee <= 0x7); REQUIRE(permission <= 0xFF); - - if ((trustee & ISC_FSACCESS_OWNER) != 0) + if ((trustee & ISC_FSACCESS_OWNER) != 0) { *access &= ~permission; + } - if ((trustee & ISC_FSACCESS_GROUP) != 0) + if ((trustee & ISC_FSACCESS_GROUP) != 0) { *access &= ~(permission << GROUP); + } - if ((trustee & ISC_FSACCESS_OTHER) != 0) + if ((trustee & ISC_FSACCESS_OTHER) != 0) { *access &= ~(permission << OTHER); + } } static isc_result_t @@ -69,15 +72,13 @@ check_bad_bits(isc_fsaccess_t access, bool is_dir) { /* * Check for disallowed user bits. */ - if (is_dir) - bits = ISC_FSACCESS_READ | - ISC_FSACCESS_WRITE | + if (is_dir) { + bits = ISC_FSACCESS_READ | ISC_FSACCESS_WRITE | ISC_FSACCESS_EXECUTE; - else - bits = ISC_FSACCESS_CREATECHILD | - ISC_FSACCESS_ACCESSCHILD | - ISC_FSACCESS_DELETECHILD | - ISC_FSACCESS_LISTDIRECTORY; + } else { + bits = ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_ACCESSCHILD | + ISC_FSACCESS_DELETECHILD | ISC_FSACCESS_LISTDIRECTORY; + } /* * Set group bad bits. @@ -89,10 +90,11 @@ check_bad_bits(isc_fsaccess_t access, bool is_dir) { bits |= bits << STEP; if ((access & bits) != 0) { - if (is_dir) + if (is_dir) { return (ISC_R_NOTFILE); - else + } else { return (ISC_R_NOTDIRECTORY); + } } return (ISC_R_SUCCESS); diff --git a/lib/isc/hash.c b/lib/isc/hash.c index 456e9458..9a757795 100644 --- a/lib/isc/hash.c +++ b/lib/isc/hash.c @@ -3,90 +3,87 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -/* - * 32 bit Fowler/Noll/Vo FNV-1a hash code with modification for BIND - */ - -#include <config.h> // IWYU pragma: keep - +#include <inttypes.h> #include <stdbool.h> #include <stddef.h> -#include <inttypes.h> +#if defined(WIN32) || defined(WIN64) +#include <malloc.h> +#endif /* if defined(WIN32) || defined(WIN64) */ -#include "isc/hash.h" // IWYU pragma: keep +#include "entropy_private.h" +#include "isc/hash.h" /* IWYU pragma: keep */ #include "isc/likely.h" #include "isc/once.h" #include "isc/random.h" #include "isc/result.h" +#include "isc/siphash.h" +#include "isc/string.h" #include "isc/types.h" #include "isc/util.h" -static uint32_t fnv_offset_basis; -static isc_once_t fnv_once = ISC_ONCE_INIT; -static bool fnv_initialized = false; - -static unsigned char maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; +static uint8_t isc_hash_key[16]; +static uint8_t isc_hash32_key[8]; +static bool hash_initialized = false; +static isc_once_t isc_hash_once = ISC_ONCE_INIT; static void -fnv_initialize(void) { +isc_hash_initialize(void) { /* - * This function should not leave fnv_offset_basis set to - * 0. Also, after this function has been called, if it is called - * again, it should not change fnv_offset_basis. + * Set a constant key to help in problem reproduction should + * fuzzing find a crash or a hang. */ - while (fnv_offset_basis == 0) { - fnv_offset_basis = isc_random32(); - } - - fnv_initialized = true; + uint64_t key[2] = { 0, 1 }; +#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + isc_entropy_get(key, sizeof(key)); +#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + memmove(isc_hash_key, key, sizeof(isc_hash_key)); +#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + isc_entropy_get(key, sizeof(key)); +#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + memmove(isc_hash32_key, key, sizeof(isc_hash32_key)); + hash_initialized = true; } +static uint8_t maptolower[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0xff +}; + const void * isc_hash_get_initializer(void) { - if (ISC_UNLIKELY(!fnv_initialized)) - RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == - ISC_R_SUCCESS); + if (ISC_UNLIKELY(!hash_initialized)) { + RUNTIME_CHECK( + isc_once_do(&isc_hash_once, isc_hash_initialize) == + ISC_R_SUCCESS); + } - return (&fnv_offset_basis); + return (isc_hash_key); } void @@ -94,111 +91,60 @@ isc_hash_set_initializer(const void *initializer) { REQUIRE(initializer != NULL); /* - * Ensure that fnv_initialize() is not called after + * Ensure that isc_hash_initialize() is not called after * isc_hash_set_initializer() is called. */ - if (ISC_UNLIKELY(!fnv_initialized)) - RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == - ISC_R_SUCCESS); + if (ISC_UNLIKELY(!hash_initialized)) { + RUNTIME_CHECK( + isc_once_do(&isc_hash_once, isc_hash_initialize) == + ISC_R_SUCCESS); + } - fnv_offset_basis = *((const unsigned int *)initializer); + memmove(isc_hash_key, initializer, sizeof(isc_hash_key)); } -#define FNV_32_PRIME ((uint32_t)0x01000193) - -uint32_t -isc_hash_function(const void *data, size_t length, bool case_sensitive, - const uint32_t *previous_hashp) -{ - uint32_t hval; - const unsigned char *bp; - const unsigned char *be; +uint64_t +isc_hash64(const void *data, const size_t length, const bool case_sensitive) { + uint64_t hval; REQUIRE(length == 0 || data != NULL); - if (ISC_UNLIKELY(!fnv_initialized)) { - RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == - ISC_R_SUCCESS); - } - - hval = ISC_UNLIKELY(previous_hashp != NULL) ? *previous_hashp - : fnv_offset_basis; - - if (length == 0) { - return (hval); - } - - bp = (const unsigned char *)data; - be = bp + length; - - /* - * Fowler-Noll-Vo FNV-1a hash function. - * - * NOTE: A random FNV offset basis is used by default to avoid - * collision attacks as the hash function is reversible. This - * makes the mapping non-deterministic, but the distribution in - * the domain is still uniform. - */ + RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) == + ISC_R_SUCCESS); if (case_sensitive) { - while (bp < be) { - hval ^= *bp++; - hval *= FNV_32_PRIME; - } + isc_siphash24(isc_hash_key, data, length, (uint8_t *)&hval); } else { - while (bp < be) { - hval ^= maptolower[*bp++]; - hval *= FNV_32_PRIME; + uint8_t input[1024]; + REQUIRE(length <= 1024); + for (unsigned int i = 0; i < length; i++) { + input[i] = maptolower[((const uint8_t *)data)[i]]; } + isc_siphash24(isc_hash_key, input, length, (uint8_t *)&hval); } return (hval); } uint32_t -isc_hash_function_reverse(const void *data, size_t length, bool case_sensitive, - const uint32_t *previous_hashp) -{ +isc_hash32(const void *data, const size_t length, const bool case_sensitive) { uint32_t hval; - const unsigned char *bp; - const unsigned char *be; REQUIRE(length == 0 || data != NULL); - if (ISC_UNLIKELY(!fnv_initialized)) { - RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == - ISC_R_SUCCESS); - } - - hval = ISC_UNLIKELY(previous_hashp != NULL) ? *previous_hashp - : fnv_offset_basis; - - if (length == 0) { - return (hval); - } - - bp = (const unsigned char *)data; - be = bp + length; - - /* - * Fowler-Noll-Vo FNV-1a hash function. - * - * NOTE: A random FNV offset basis is used by default to avoid - * collision attacks as the hash function is reversible. This - * makes the mapping non-deterministic, but the distribution in - * the domain is still uniform. - */ + RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) == + ISC_R_SUCCESS); if (case_sensitive) { - while (--be >= bp) { - hval ^= *be; - hval *= FNV_32_PRIME; - } + isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval); } else { - while (--be >= bp) { - hval ^= maptolower[*be]; - hval *= FNV_32_PRIME; + uint8_t input[1024]; + REQUIRE(length <= 1024); + for (unsigned int i = 0; i < length; i++) { + input[i] = maptolower[((const uint8_t *)data)[i]]; } + isc_halfsiphash24(isc_hash_key, input, length, + (uint8_t *)&hval); } return (hval); diff --git a/lib/isc/heap.c b/lib/isc/heap.c index 22fa81ca..678c4628 100644 --- a/lib/isc/heap.c +++ b/lib/isc/heap.c @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file * Heap implementation of priority queues adapted from the following: * @@ -20,14 +19,12 @@ * ISBN 0-201-06673-4, chapter 11. */ -#include <config.h> - #include <stdbool.h> #include <isc/heap.h> #include <isc/magic.h> #include <isc/mem.h> -#include <isc/string.h> /* Required for memmove. */ +#include <isc/string.h> /* Required for memmove. */ #include <isc/util.h> /*@{*/ @@ -37,34 +34,34 @@ * not 0-based. The parent is index/2, and the left-child is index*2. * The right child is index*2+1. */ -#define heap_parent(i) ((i) >> 1) -#define heap_left(i) ((i) << 1) +#define heap_parent(i) ((i) >> 1) +#define heap_left(i) ((i) << 1) /*@}*/ -#define SIZE_INCREMENT 1024 +#define SIZE_INCREMENT 1024 -#define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P') -#define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC) +#define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P') +#define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC) /*% * When the heap is in a consistent state, the following invariant * holds true: for every element i > 1, heap_parent(i) has a priority * higher than or equal to that of i. */ -#define HEAPCONDITION(i) ((i) == 1 || \ - ! heap->compare(heap->array[(i)], \ - heap->array[heap_parent(i)])) +#define HEAPCONDITION(i) \ + ((i) == 1 || \ + !heap->compare(heap->array[(i)], heap->array[heap_parent(i)])) /*% ISC heap structure. */ struct isc_heap { - unsigned int magic; - isc_mem_t * mctx; - unsigned int size; - unsigned int size_increment; - unsigned int last; - void **array; - isc_heapcompare_t compare; - isc_heapindex_t index; + unsigned int magic; + isc_mem_t *mctx; + unsigned int size; + unsigned int size_increment; + unsigned int last; + void **array; + isc_heapcompare_t compare; + isc_heapindex_t index; }; #ifdef ISC_HEAP_CHECK @@ -75,31 +72,28 @@ heap_check(isc_heap_t *heap) { INSIST(HEAPCONDITION(i)); } } -#else +#else /* ifdef ISC_HEAP_CHECK */ #define heap_check(x) (void)0 -#endif +#endif /* ifdef ISC_HEAP_CHECK */ isc_result_t -isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, - isc_heapindex_t idx, unsigned int size_increment, - isc_heap_t **heapp) -{ +isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, isc_heapindex_t idx, + unsigned int size_increment, isc_heap_t **heapp) { isc_heap_t *heap; REQUIRE(heapp != NULL && *heapp == NULL); REQUIRE(compare != NULL); heap = isc_mem_get(mctx, sizeof(*heap)); - if (heap == NULL) - return (ISC_R_NOMEMORY); heap->magic = HEAP_MAGIC; heap->size = 0; heap->mctx = NULL; isc_mem_attach(mctx, &heap->mctx); - if (size_increment == 0) + if (size_increment == 0) { heap->size_increment = SIZE_INCREMENT; - else + } else { heap->size_increment = size_increment; + } heap->last = 0; heap->array = NULL; heap->compare = compare; @@ -116,15 +110,15 @@ isc_heap_destroy(isc_heap_t **heapp) { REQUIRE(heapp != NULL); heap = *heapp; + *heapp = NULL; REQUIRE(VALID_HEAP(heap)); - if (heap->array != NULL) + if (heap->array != NULL) { isc_mem_put(heap->mctx, heap->array, heap->size * sizeof(void *)); + } heap->magic = 0; isc_mem_putanddetach(&heap->mctx, heap, sizeof(*heap)); - - *heapp = NULL; } static bool @@ -136,8 +130,6 @@ resize(isc_heap_t *heap) { new_size = heap->size + heap->size_increment; new_array = isc_mem_get(heap->mctx, new_size * sizeof(void *)); - if (new_array == NULL) - return (false); if (heap->array != NULL) { memmove(new_array, heap->array, heap->size * sizeof(void *)); isc_mem_put(heap->mctx, heap->array, @@ -153,16 +145,18 @@ static void float_up(isc_heap_t *heap, unsigned int i, void *elt) { unsigned int p; - for (p = heap_parent(i) ; - i > 1 && heap->compare(elt, heap->array[p]) ; - i = p, p = heap_parent(i)) { + for (p = heap_parent(i); i > 1 && heap->compare(elt, heap->array[p]); + i = p, p = heap_parent(i)) + { heap->array[i] = heap->array[p]; - if (heap->index != NULL) + if (heap->index != NULL) { (heap->index)(heap->array[i], i); + } } heap->array[i] = elt; - if (heap->index != NULL) + if (heap->index != NULL) { (heap->index)(heap->array[i], i); + } INSIST(HEAPCONDITION(i)); heap_check(heap); @@ -176,19 +170,23 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) { while (i <= half_size) { /* Find the smallest of the (at most) two children. */ j = heap_left(i); - if (j < size && heap->compare(heap->array[j+1], - heap->array[j])) + if (j < size && + heap->compare(heap->array[j + 1], heap->array[j])) { j++; - if (heap->compare(elt, heap->array[j])) + } + if (heap->compare(elt, heap->array[j])) { break; + } heap->array[i] = heap->array[j]; - if (heap->index != NULL) + if (heap->index != NULL) { (heap->index)(heap->array[i], i); + } i = j; } heap->array[i] = elt; - if (heap->index != NULL) + if (heap->index != NULL) { (heap->index)(heap->array[i], i); + } INSIST(HEAPCONDITION(i)); heap_check(heap); @@ -203,8 +201,9 @@ isc_heap_insert(isc_heap_t *heap, void *elt) { heap_check(heap); new_last = heap->last + 1; RUNTIME_CHECK(new_last > 0); /* overflow check */ - if (new_last >= heap->size && !resize(heap)) + if (new_last >= heap->size && !resize(heap)) { return (ISC_R_NOMEMORY); + } heap->last = new_last; float_up(heap, new_last, elt); @@ -221,8 +220,9 @@ isc_heap_delete(isc_heap_t *heap, unsigned int idx) { REQUIRE(idx >= 1 && idx <= heap->last); heap_check(heap); - if (heap->index != NULL) + if (heap->index != NULL) { (heap->index)(heap->array[idx], 0); + } if (idx == heap->last) { heap->array[heap->last] = NULL; heap->last--; @@ -234,10 +234,11 @@ isc_heap_delete(isc_heap_t *heap, unsigned int idx) { less = heap->compare(elt, heap->array[idx]); heap->array[idx] = elt; - if (less) + if (less) { float_up(heap, idx, heap->array[idx]); - else + } else { sink_down(heap, idx, heap->array[idx]); + } } } @@ -263,8 +264,9 @@ isc_heap_element(isc_heap_t *heap, unsigned int idx) { REQUIRE(idx >= 1); heap_check(heap); - if (idx <= heap->last) + if (idx <= heap->last) { return (heap->array[idx]); + } return (NULL); } @@ -275,6 +277,7 @@ isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) { REQUIRE(VALID_HEAP(heap)); REQUIRE(action != NULL); - for (i = 1 ; i <= heap->last ; i++) + for (i = 1; i <= heap->last; i++) { (action)(heap->array[i], uap); + } } diff --git a/lib/isc/hex.c b/lib/isc/hex.c index d19dc154..2bf58027 100644 --- a/lib/isc/hex.c +++ b/lib/isc/hex.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <ctype.h> #include <stdbool.h> @@ -23,13 +20,13 @@ #include <isc/string.h> #include <isc/util.h> -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ +#define RETERR(x) \ + do { \ + isc_result_t _r = (x); \ + if (_r != ISC_R_SUCCESS) \ + return ((_r)); \ } while (0) - /* * BEW: These static functions are copied from lib/dns/rdata.c. */ @@ -42,14 +39,14 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); static const char hex[] = "0123456789ABCDEF"; isc_result_t -isc_hex_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target) -{ +isc_hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target) { char buf[3]; unsigned int loops = 0; - if (wordlength < 2) + if (wordlength < 2) { wordlength = 2; + } memset(buf, 0, sizeof(buf)); while (source->length > 0) { @@ -59,8 +56,7 @@ isc_hex_totext(isc_region_t *source, int wordlength, isc_region_consume(source, 1); loops++; - if (source->length != 0 && - (int)((loops + 1) * 2) >= wordlength) + if (source->length != 0 && (int)((loops + 1) * 2) >= wordlength) { loops = 0; RETERR(str_totext(wordbreak, target)); @@ -73,15 +69,14 @@ isc_hex_totext(isc_region_t *source, int wordlength, * State of a hex decoding process in progress. */ typedef struct { - int length; /*%< Desired length of binary data or -1 */ - isc_buffer_t *target; /*%< Buffer for resulting binary data */ - int digits; /*%< Number of buffered hex digits */ + int length; /*%< Desired length of binary data or -1 */ + isc_buffer_t *target; /*%< Buffer for resulting binary data */ + int digits; /*%< Number of buffered hex digits */ int val[2]; } hex_decode_ctx_t; static inline void -hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target) -{ +hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target) { ctx->digits = 0; ctx->length = length; ctx->target = target; @@ -91,8 +86,9 @@ static inline isc_result_t hex_decode_char(hex_decode_ctx_t *ctx, int c) { const char *s; - if ((s = strchr(hex, toupper(c))) == NULL) + if ((s = strchr(hex, toupper(c))) == NULL) { return (ISC_R_BADHEX); + } ctx->val[ctx->digits++] = (int)(s - hex); if (ctx->digits == 2) { unsigned char num; @@ -100,10 +96,11 @@ hex_decode_char(hex_decode_ctx_t *ctx, int c) { num = (ctx->val[0] << 4) + (ctx->val[1]); RETERR(mem_tobuffer(ctx->target, &num, 1)); if (ctx->length >= 0) { - if (ctx->length == 0) + if (ctx->length == 0) { return (ISC_R_BADHEX); - else + } else { ctx->length -= 1; + } } ctx->digits = 0; } @@ -112,10 +109,12 @@ hex_decode_char(hex_decode_ctx_t *ctx, int c) { static inline isc_result_t hex_decode_finish(hex_decode_ctx_t *ctx) { - if (ctx->length > 0) + if (ctx->length > 0) { return (ISC_R_UNEXPECTEDEND); - if (ctx->digits != 0) + } + if (ctx->digits != 0) { return (ISC_R_BADHEX); + } return (ISC_R_SUCCESS); } @@ -168,10 +167,12 @@ isc_hex_decodestring(const char *cstr, isc_buffer_t *target) { hex_decode_init(&ctx, -1, target); for (;;) { int c = *cstr++; - if (c == '\0') + if (c == '\0') { break; - if (c == ' ' || c == '\t' || c == '\n' || c== '\r') + } + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { continue; + } RETERR(hex_decode_char(&ctx, c)); } RETERR(hex_decode_finish(&ctx)); @@ -186,8 +187,9 @@ str_totext(const char *source, isc_buffer_t *target) { isc_buffer_availableregion(target, ®ion); l = strlen(source); - if (l > region.length) + if (l > region.length) { return (ISC_R_NOSPACE); + } memmove(region.base, source, l); isc_buffer_add(target, l); @@ -199,8 +201,9 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); - if (length > tr.length) + if (length > tr.length) { return (ISC_R_NOSPACE); + } memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); diff --git a/lib/isc/hmac.c b/lib/isc/hmac.c index 31fc6914..c300a306 100644 --- a/lib/isc/hmac.c +++ b/lib/isc/hmac.c @@ -3,13 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> +#include <openssl/hmac.h> +#include <openssl/opensslv.h> #include <isc/assertions.h> #include <isc/hmac.h> @@ -20,16 +21,13 @@ #include <isc/types.h> #include <isc/util.h> -#include <openssl/hmac.h> -#include <openssl/opensslv.h> - #include "openssl_shim.h" isc_hmac_t * isc_hmac_new(void) { - isc_hmac_t *hmac = HMAC_CTX_new(); + HMAC_CTX *hmac = HMAC_CTX_new(); RUNTIME_CHECK(hmac != NULL); - return (hmac); + return ((struct hmac *)hmac); } void @@ -42,9 +40,8 @@ isc_hmac_free(isc_hmac_t *hmac) { } isc_result_t -isc_hmac_init(isc_hmac_t *hmac, const void *key, - size_t keylen, isc_md_type_t md_type) -{ +isc_hmac_init(isc_hmac_t *hmac, const void *key, size_t keylen, + const isc_md_type_t *md_type) { REQUIRE(hmac != NULL); REQUIRE(key != NULL); @@ -63,7 +60,7 @@ isc_result_t isc_hmac_reset(isc_hmac_t *hmac) { REQUIRE(hmac != NULL); - if (HMAC_CTX_reset(hmac) != 1) { + if (HMAC_CTX_reset(hmac) != 1) { return (ISC_R_CRYPTOFAILURE); } @@ -87,8 +84,7 @@ isc_hmac_update(isc_hmac_t *hmac, const unsigned char *buf, const size_t len) { isc_result_t isc_hmac_final(isc_hmac_t *hmac, unsigned char *digest, - unsigned int *digestlen) -{ + unsigned int *digestlen) { REQUIRE(hmac != NULL); REQUIRE(digest != NULL); @@ -99,7 +95,7 @@ isc_hmac_final(isc_hmac_t *hmac, unsigned char *digest, return (ISC_R_SUCCESS); } -isc_md_type_t +const isc_md_type_t * isc_hmac_get_md_type(isc_hmac_t *hmac) { REQUIRE(hmac != NULL); @@ -121,14 +117,11 @@ isc_hmac_get_block_size(isc_hmac_t *hmac) { } isc_result_t -isc_hmac(isc_md_type_t type, const void *key, const int keylen, - const unsigned char *buf, const size_t len, - unsigned char *digest, unsigned int *digestlen) -{ - isc_hmac_t *hmac = NULL; +isc_hmac(const isc_md_type_t *type, const void *key, const int keylen, + const unsigned char *buf, const size_t len, unsigned char *digest, + unsigned int *digestlen) { isc_result_t res; - - hmac = isc_hmac_new(); + isc_hmac_t *hmac = isc_hmac_new(); res = isc_hmac_init(hmac, key, keylen, type); if (res != ISC_R_SUCCESS) { @@ -144,7 +137,7 @@ isc_hmac(isc_md_type_t type, const void *key, const int keylen, if (res != ISC_R_SUCCESS) { goto end; } - end: +end: isc_hmac_free(hmac); return (res); diff --git a/lib/isc/hp.c b/lib/isc/hp.c new file mode 100644 index 00000000..3ea13bbe --- /dev/null +++ b/lib/isc/hp.c @@ -0,0 +1,216 @@ +/* + * 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. + */ + +/* + * Hazard Pointer implementation. + * + * This work is based on C++ code available from: + * https://github.com/pramalhe/ConcurrencyFreaks/ + * + * Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Concurrency Freaks nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <inttypes.h> + +#include <isc/atomic.h> +#include <isc/hp.h> +#include <isc/mem.h> +#include <isc/once.h> +#include <isc/string.h> +#include <isc/thread.h> +#include <isc/util.h> + +#define HP_MAX_THREADS 128 +static int isc__hp_max_threads = HP_MAX_THREADS; +#define HP_MAX_HPS 4 /* This is named 'K' in the HP paper */ +#define CLPAD (128 / sizeof(uintptr_t)) +#define HP_THRESHOLD_R 0 /* This is named 'R' in the HP paper */ + +/* Maximum number of retired objects per thread */ +static int isc__hp_max_retired = HP_MAX_THREADS * HP_MAX_HPS; + +#define TID_UNKNOWN -1 + +static atomic_int_fast32_t tid_v_base = ATOMIC_VAR_INIT(0); + +ISC_THREAD_LOCAL int tid_v = TID_UNKNOWN; + +typedef struct retirelist { + int size; + uintptr_t *list; +} retirelist_t; + +struct isc_hp { + int max_hps; + isc_mem_t *mctx; + atomic_uintptr_t **hp; + retirelist_t **rl; + isc_hp_deletefunc_t *deletefunc; +}; + +static inline int +tid() { + if (tid_v == TID_UNKNOWN) { + tid_v = atomic_fetch_add(&tid_v_base, 1); + REQUIRE(tid_v < isc__hp_max_threads); + } + + return (tid_v); +} + +void +isc_hp_init(int max_threads) { + isc__hp_max_threads = max_threads; + isc__hp_max_retired = max_threads * HP_MAX_HPS; +} + +isc_hp_t * +isc_hp_new(isc_mem_t *mctx, size_t max_hps, isc_hp_deletefunc_t *deletefunc) { + isc_hp_t *hp = isc_mem_get(mctx, sizeof(*hp)); + + if (max_hps == 0) { + max_hps = HP_MAX_HPS; + } + + *hp = (isc_hp_t){ .max_hps = max_hps, .deletefunc = deletefunc }; + + isc_mem_attach(mctx, &hp->mctx); + + hp->hp = isc_mem_get(mctx, isc__hp_max_threads * sizeof(hp->hp[0])); + hp->rl = isc_mem_get(mctx, isc__hp_max_threads * sizeof(hp->rl[0])); + + for (int i = 0; i < isc__hp_max_threads; i++) { + hp->hp[i] = isc_mem_get(mctx, CLPAD * 2 * sizeof(hp->hp[i][0])); + hp->rl[i] = isc_mem_get(mctx, sizeof(*hp->rl[0])); + *hp->rl[i] = (retirelist_t){ .size = 0 }; + + for (int j = 0; j < hp->max_hps; j++) { + atomic_init(&hp->hp[i][j], 0); + } + hp->rl[i]->list = isc_mem_get( + hp->mctx, isc__hp_max_retired * sizeof(uintptr_t)); + } + + return (hp); +} + +void +isc_hp_destroy(isc_hp_t *hp) { + for (int i = 0; i < isc__hp_max_threads; i++) { + isc_mem_put(hp->mctx, hp->hp[i], + CLPAD * 2 * sizeof(hp->hp[i][0])); + + for (int j = 0; j < hp->rl[i]->size; j++) { + void *data = (void *)hp->rl[i]->list[j]; + hp->deletefunc(data); + } + isc_mem_put(hp->mctx, hp->rl[i]->list, + isc__hp_max_retired * sizeof(uintptr_t)); + isc_mem_put(hp->mctx, hp->rl[i], sizeof(*hp->rl[0])); + } + isc_mem_put(hp->mctx, hp->hp, isc__hp_max_threads * sizeof(hp->hp[0])); + isc_mem_put(hp->mctx, hp->rl, isc__hp_max_threads * sizeof(hp->rl[0])); + + isc_mem_putanddetach(&hp->mctx, hp, sizeof(*hp)); +} + +void +isc_hp_clear(isc_hp_t *hp) { + for (int i = 0; i < hp->max_hps; i++) { + atomic_store_release(&hp->hp[tid()][i], 0); + } +} + +void +isc_hp_clear_one(isc_hp_t *hp, int ihp) { + atomic_store_release(&hp->hp[tid()][ihp], 0); +} + +uintptr_t +isc_hp_protect(isc_hp_t *hp, int ihp, atomic_uintptr_t *atom) { + uintptr_t n = 0; + uintptr_t ret; + while ((ret = atomic_load(atom)) != n) { + atomic_store(&hp->hp[tid()][ihp], ret); + n = ret; + } + return (ret); +} + +uintptr_t +isc_hp_protect_ptr(isc_hp_t *hp, int ihp, atomic_uintptr_t ptr) { + atomic_store(&hp->hp[tid()][ihp], atomic_load(&ptr)); + return (atomic_load(&ptr)); +} + +uintptr_t +isc_hp_protect_release(isc_hp_t *hp, int ihp, atomic_uintptr_t ptr) { + atomic_store_release(&hp->hp[tid()][ihp], atomic_load(&ptr)); + return (atomic_load(&ptr)); +} + +void +isc_hp_retire(isc_hp_t *hp, uintptr_t ptr) { + hp->rl[tid()]->list[hp->rl[tid()]->size++] = ptr; + INSIST(hp->rl[tid()]->size < isc__hp_max_retired); + + if (hp->rl[tid()]->size < HP_THRESHOLD_R) { + return; + } + + for (int iret = 0; iret < hp->rl[tid()]->size; iret++) { + uintptr_t obj = hp->rl[tid()]->list[iret]; + bool can_delete = true; + for (int itid = 0; itid < isc__hp_max_threads && can_delete; + itid++) { + for (int ihp = hp->max_hps - 1; ihp >= 0; ihp--) { + if (atomic_load(&hp->hp[itid][ihp]) == obj) { + can_delete = false; + break; + } + } + } + + if (can_delete) { + size_t bytes = (hp->rl[tid()]->size - iret) * + sizeof(hp->rl[tid()]->list[0]); + memmove(&hp->rl[tid()]->list[iret], + &hp->rl[tid()]->list[iret + 1], bytes); + hp->rl[tid()]->size--; + hp->deletefunc((void *)obj); + } + } +} diff --git a/lib/isc/ht.c b/lib/isc/ht.c index fde728a4..82f8ac86 100644 --- a/lib/isc/ht.c +++ b/lib/isc/ht.c @@ -3,30 +3,27 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <inttypes.h> #include <string.h> #include <isc/hash.h> #include <isc/ht.h> -#include <isc/types.h> #include <isc/magic.h> #include <isc/mem.h> #include <isc/result.h> +#include <isc/types.h> #include <isc/util.h> - typedef struct isc_ht_node isc_ht_node_t; -#define ISC_HT_MAGIC ISC_MAGIC('H', 'T', 'a', 'b') -#define ISC_HT_VALID(ht) ISC_MAGIC_VALID(ht, ISC_HT_MAGIC) +#define ISC_HT_MAGIC ISC_MAGIC('H', 'T', 'a', 'b') +#define ISC_HT_VALID(ht) ISC_MAGIC_VALID(ht, ISC_HT_MAGIC) struct isc_ht_node { void *value; @@ -57,25 +54,18 @@ isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits) { REQUIRE(htp != NULL && *htp == NULL); REQUIRE(mctx != NULL); - REQUIRE(bits >= 1 && bits <= (sizeof(size_t)*8 - 1)); + REQUIRE(bits >= 1 && bits <= (sizeof(size_t) * 8 - 1)); ht = isc_mem_get(mctx, sizeof(struct isc_ht)); - if (ht == NULL) { - return (ISC_R_NOMEMORY); - } ht->mctx = NULL; isc_mem_attach(mctx, &ht->mctx); - ht->size = ((size_t)1<<bits); - ht->mask = ((size_t)1<<bits)-1; + ht->size = ((size_t)1 << bits); + ht->mask = ((size_t)1 << bits) - 1; ht->count = 0; - ht->table = isc_mem_get(ht->mctx, ht->size * sizeof(isc_ht_node_t*)); - if (ht->table == NULL) { - isc_mem_putanddetach(&ht->mctx, ht, sizeof(struct isc_ht)); - return (ISC_R_NOMEMORY); - } + ht->table = isc_mem_get(ht->mctx, ht->size * sizeof(isc_ht_node_t *)); for (i = 0; i < ht->size; i++) { ht->table[i] = NULL; @@ -108,29 +98,27 @@ isc_ht_destroy(isc_ht_t **htp) { ht->count--; isc_mem_put(ht->mctx, node, offsetof(isc_ht_node_t, key) + - node->keysize); + node->keysize); node = next; } } INSIST(ht->count == 0); - isc_mem_put(ht->mctx, ht->table, ht->size * sizeof(isc_ht_node_t*)); + isc_mem_put(ht->mctx, ht->table, ht->size * sizeof(isc_ht_node_t *)); isc_mem_putanddetach(&ht->mctx, ht, sizeof(struct isc_ht)); - } isc_result_t -isc_ht_add(isc_ht_t *ht, const unsigned char *key, - uint32_t keysize, void *value) -{ +isc_ht_add(isc_ht_t *ht, const unsigned char *key, uint32_t keysize, + void *value) { isc_ht_node_t *node; uint32_t hash; REQUIRE(ISC_HT_VALID(ht)); REQUIRE(key != NULL && keysize > 0); - hash = isc_hash_function(key, keysize, true, NULL); + hash = isc_hash_function(key, keysize, true); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && @@ -141,8 +129,6 @@ isc_ht_add(isc_ht_t *ht, const unsigned char *key, } node = isc_mem_get(ht->mctx, offsetof(isc_ht_node_t, key) + keysize); - if (node == NULL) - return (ISC_R_NOMEMORY); memmove(node->key, key, keysize); node->keysize = keysize; @@ -155,9 +141,8 @@ isc_ht_add(isc_ht_t *ht, const unsigned char *key, } isc_result_t -isc_ht_find(const isc_ht_t *ht, const unsigned char *key, - uint32_t keysize, void **valuep) -{ +isc_ht_find(const isc_ht_t *ht, const unsigned char *key, uint32_t keysize, + void **valuep) { isc_ht_node_t *node; uint32_t hash; @@ -165,14 +150,14 @@ isc_ht_find(const isc_ht_t *ht, const unsigned char *key, REQUIRE(key != NULL && keysize > 0); REQUIRE(valuep == NULL || *valuep == NULL); - hash = isc_hash_function(key, keysize, true, NULL); + hash = isc_hash_function(key, keysize, true); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && - memcmp(key, node->key, keysize) == 0) - { - if (valuep != NULL) + memcmp(key, node->key, keysize) == 0) { + if (valuep != NULL) { *valuep = node->value; + } return (ISC_R_SUCCESS); } node = node->next; @@ -190,18 +175,19 @@ isc_ht_delete(isc_ht_t *ht, const unsigned char *key, uint32_t keysize) { REQUIRE(key != NULL && keysize > 0); prev = NULL; - hash = isc_hash_function(key, keysize, true, NULL); + hash = isc_hash_function(key, keysize, true); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && memcmp(key, node->key, keysize) == 0) { - if (prev == NULL) + if (prev == NULL) { ht->table[hash & ht->mask] = node->next; - else + } else { prev->next = node->next; + } isc_mem_put(ht->mctx, node, offsetof(isc_ht_node_t, key) + - node->keysize); + node->keysize); ht->count--; return (ISC_R_SUCCESS); @@ -221,8 +207,6 @@ isc_ht_iter_create(isc_ht_t *ht, isc_ht_iter_t **itp) { REQUIRE(itp != NULL && *itp == NULL); it = isc_mem_get(ht->mctx, sizeof(isc_ht_iter_t)); - if (it == NULL) - return (ISC_R_NOMEMORY); it->ht = ht; it->i = 0; @@ -241,10 +225,9 @@ isc_ht_iter_destroy(isc_ht_iter_t **itp) { REQUIRE(itp != NULL && *itp != NULL); it = *itp; + *itp = NULL; ht = it->ht; isc_mem_put(ht->mctx, it, sizeof(isc_ht_iter_t)); - - *itp = NULL; } isc_result_t @@ -252,11 +235,13 @@ isc_ht_iter_first(isc_ht_iter_t *it) { REQUIRE(it != NULL); it->i = 0; - while (it->i < it->ht->size && it->ht->table[it->i] == NULL) + while (it->i < it->ht->size && it->ht->table[it->i] == NULL) { it->i++; + } - if (it->i == it->ht->size) + if (it->i == it->ht->size) { return (ISC_R_NOMORE); + } it->cur = it->ht->table[it->i]; @@ -273,8 +258,9 @@ isc_ht_iter_next(isc_ht_iter_t *it) { do { it->i++; } while (it->i < it->ht->size && it->ht->table[it->i] == NULL); - if (it->i >= it->ht->size) + if (it->i >= it->ht->size) { return (ISC_R_NOMORE); + } it->cur = it->ht->table[it->i]; } @@ -299,14 +285,14 @@ isc_ht_iter_delcurrent_next(isc_ht_iter_t *it) { do { it->i++; } while (it->i < ht->size && ht->table[it->i] == NULL); - if (it->i >= ht->size) + if (it->i >= ht->size) { result = ISC_R_NOMORE; - else + } else { it->cur = ht->table[it->i]; + } } - hash = isc_hash_function(to_delete->key, to_delete->keysize, true, - NULL); + hash = isc_hash_function(to_delete->key, to_delete->keysize, true); node = ht->table[hash & ht->mask]; while (node != to_delete) { prev = node; @@ -314,10 +300,11 @@ isc_ht_iter_delcurrent_next(isc_ht_iter_t *it) { INSIST(node != NULL); } - if (prev == NULL) + if (prev == NULL) { ht->table[hash & ht->mask] = node->next; - else + } else { prev->next = node->next; + } isc_mem_put(ht->mctx, node, offsetof(isc_ht_node_t, key) + node->keysize); ht->count--; @@ -335,8 +322,8 @@ isc_ht_iter_current(isc_ht_iter_t *it, void **valuep) { } void -isc_ht_iter_currentkey(isc_ht_iter_t *it, unsigned char **key, size_t *keysize) -{ +isc_ht_iter_currentkey(isc_ht_iter_t *it, unsigned char **key, + size_t *keysize) { REQUIRE(it != NULL); REQUIRE(it->cur != NULL); REQUIRE(key != NULL && *key == NULL); @@ -349,5 +336,5 @@ unsigned int isc_ht_count(isc_ht_t *ht) { REQUIRE(ISC_HT_VALID(ht)); - return(ht->count); + return (ht->count); } diff --git a/lib/isc/httpd.c b/lib/isc/httpd.c index f6a01a45..776455a7 100644 --- a/lib/isc/httpd.c +++ b/lib/isc/httpd.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <inttypes.h> #include <stdbool.h> #include <string.h> @@ -22,6 +19,7 @@ #include <isc/httpd.h> #include <isc/mem.h> #include <isc/print.h> +#include <isc/refcount.h> #include <isc/socket.h> #include <isc/string.h> #include <isc/task.h> @@ -30,63 +28,58 @@ #ifdef HAVE_ZLIB #include <zlib.h> -#endif +#endif /* ifdef HAVE_ZLIB */ /*% * TODO: * - * o Put in better checks to make certain things are passed in correctly. - * This includes a magic number for externally-visible structures, - * checking for NULL-ness before dereferencing, etc. * o Make the URL processing external functions which will fill-in a buffer * structure we provide, or return an error and we will render a generic * page and close the client. */ -#define MSHUTTINGDOWN(cm) ((cm->flags & ISC_HTTPDMGR_FLAGSHUTTINGDOWN) != 0) +#define MSHUTTINGDOWN(cm) ((cm->flags & ISC_HTTPDMGR_FLAGSHUTTINGDOWN) != 0) #define MSETSHUTTINGDOWN(cm) (cm->flags |= ISC_HTTPDMGR_FLAGSHUTTINGDOWN) -#ifdef DEBUG_HTTPD -#define ENTER(x) do { fprintf(stderr, "ENTER %s\n", (x)); } while (0) -#define EXIT(x) do { fprintf(stderr, "EXIT %s\n", (x)); } while (0) -#define NOTICE(x) do { fprintf(stderr, "NOTICE %s\n", (x)); } while (0) -#else -#define ENTER(x) do { } while(0) -#define EXIT(x) do { } while(0) -#define NOTICE(x) do { } while(0) -#endif - -#define HTTP_RECVLEN 1024 -#define HTTP_SENDGROW 1024 -#define HTTP_SEND_MAXLEN 10240 - -#define HTTPD_CLOSE 0x0001 /* Got a Connection: close header */ -#define HTTPD_FOUNDHOST 0x0002 /* Got a Host: header */ -#define HTTPD_KEEPALIVE 0x0004 /* Got a Connection: Keep-Alive */ -#define HTTPD_ACCEPT_DEFLATE 0x0008 +#define HTTP_RECVLEN 1024 +#define HTTP_SENDGROW 1024 +#define HTTP_SEND_MAXLEN 10240 + +#define HTTPD_CLOSE 0x0001 /* Got a Connection: close header */ +#define HTTPD_FOUNDHOST 0x0002 /* Got a Host: header */ +#define HTTPD_KEEPALIVE 0x0004 /* Got a Connection: Keep-Alive */ +#define HTTPD_ACCEPT_DEFLATE 0x0008 + +#define HTTPD_MAGIC ISC_MAGIC('H', 't', 'p', 'd') +#define VALID_HTTPD(m) ISC_MAGIC_VALID(m, HTTPD_MAGIC) + +#define HTTPDMGR_MAGIC ISC_MAGIC('H', 'p', 'd', 'm') +#define VALID_HTTPDMGR(m) ISC_MAGIC_VALID(m, HTTPDMGR_MAGIC) /*% http client */ struct isc_httpd { - isc_httpdmgr_t *mgr; /*%< our parent */ - ISC_LINK(isc_httpd_t) link; - unsigned int state; - isc_socket_t *sock; + unsigned int magic; /* HTTPD_MAGIC */ + isc_refcount_t references; + isc_httpdmgr_t *mgr; /*%< our parent */ + ISC_LINK(isc_httpd_t) link; + unsigned int state; + isc_socket_t *sock; /*% * Received data state. */ - char recvbuf[HTTP_RECVLEN]; /*%< receive buffer */ - uint32_t recvlen; /*%< length recv'd */ - char *headers; /*%< set in process_request() */ - unsigned int method; - char *url; - char *querystring; - char *protocol; + char recvbuf[HTTP_RECVLEN]; /*%< receive buffer */ + uint32_t recvlen; /*%< length recv'd */ + char *headers; /*%< set in process_request() */ + unsigned int method; + char *url; + char *querystring; + char *protocol; /* * Flags on the httpd client. */ - int flags; + int flags; /*% * Transmit data state. @@ -98,8 +91,8 @@ struct isc_httpd { * to the client. * * The bufflist is the list of buffers we are currently transmitting. - * The headerbuffer is where we render our headers to. If we run out of - * space when rendering a header, we will change the size of our + * The headerbuffer is where we render our headers to. If we run out + * of space when rendering a header, we will change the size of our * buffer. We will not free it until we are finished, and will * allocate an additional HTTP_SENDGROW bytes per header space grow. * @@ -114,43 +107,45 @@ struct isc_httpd { * compressed HTTP data, if compression is used. * */ - isc_buffer_t headerbuffer; - isc_buffer_t compbuffer; - isc_buffer_t *sendbuffer; - - const char *mimetype; - unsigned int retcode; - const char *retmsg; - isc_buffer_t bodybuffer; - isc_httpdfree_t *freecb; - void *freecb_arg; + isc_buffer_t headerbuffer; + isc_buffer_t compbuffer; + isc_buffer_t *sendbuffer; + + const char *mimetype; + unsigned int retcode; + const char *retmsg; + isc_buffer_t bodybuffer; + isc_httpdfree_t *freecb; + void *freecb_arg; }; /*% lightweight socket manager for httpd output */ struct isc_httpdmgr { - isc_mem_t *mctx; - isc_socket_t *sock; /*%< listening socket */ - isc_task_t *task; /*%< owning task */ - isc_timermgr_t *timermgr; + unsigned int magic; /* HTTPDMGR_MAGIC */ + isc_refcount_t references; + isc_mem_t *mctx; + isc_socket_t *sock; /*%< listening socket */ + isc_task_t *task; /*%< owning task */ + isc_timermgr_t *timermgr; - isc_httpdclientok_t *client_ok; /*%< client validator */ - isc_httpdondestroy_t *ondestroy; /*%< cleanup callback */ - void *cb_arg; /*%< argument for the above */ + isc_httpdclientok_t *client_ok; /*%< client validator */ + isc_httpdondestroy_t *ondestroy; /*%< cleanup callback */ + void *cb_arg; /*%< argument for the above */ - unsigned int flags; - ISC_LIST(isc_httpd_t) running; /*%< running clients */ + unsigned int flags; + ISC_LIST(isc_httpd_t) running; /*%< running clients */ - isc_mutex_t lock; + isc_mutex_t lock; - ISC_LIST(isc_httpdurl_t) urls; /*%< urls we manage */ - isc_httpdaction_t *render_404; - isc_httpdaction_t *render_500; + ISC_LIST(isc_httpdurl_t) urls; /*%< urls we manage */ + isc_httpdaction_t *render_404; + isc_httpdaction_t *render_500; }; /*% * HTTP methods. */ -#define ISC_HTTPD_METHODUNKNOWN 0 +#define ISC_HTTPD_METHODUNKNOWN 0 #define ISC_HTTPD_METHODGET 1 #define ISC_HTTPD_METHODPOST 2 @@ -185,76 +180,155 @@ struct isc_httpdmgr { */ #define ISC_HTTPD_STATEIDLE 0 #define ISC_HTTPD_STATERECV 1 -#define ISC_HTTPD_STATERECVDONE 2 +#define ISC_HTTPD_STATERECVDONE 2 #define ISC_HTTPD_STATESEND 3 -#define ISC_HTTPD_STATESENDDONE 4 +#define ISC_HTTPD_STATESENDDONE 4 #define ISC_HTTPD_ISRECV(c) ((c)->state == ISC_HTTPD_STATERECV) -#define ISC_HTTPD_ISRECVDONE(c) ((c)->state == ISC_HTTPD_STATERECVDONE) +#define ISC_HTTPD_ISRECVDONE(c) ((c)->state == ISC_HTTPD_STATERECVDONE) #define ISC_HTTPD_ISSEND(c) ((c)->state == ISC_HTTPD_STATESEND) -#define ISC_HTTPD_ISSENDDONE(c) ((c)->state == ISC_HTTPD_STATESENDDONE) +#define ISC_HTTPD_ISSENDDONE(c) ((c)->state == ISC_HTTPD_STATESENDDONE) /*% * Overall magic test that means we're not idle. */ -#define ISC_HTTPD_SETRECV(c) ((c)->state = ISC_HTTPD_STATERECV) -#define ISC_HTTPD_SETRECVDONE(c) ((c)->state = ISC_HTTPD_STATERECVDONE) -#define ISC_HTTPD_SETSEND(c) ((c)->state = ISC_HTTPD_STATESEND) -#define ISC_HTTPD_SETSENDDONE(c) ((c)->state = ISC_HTTPD_STATESENDDONE) - -static void isc_httpd_accept(isc_task_t *, isc_event_t *); -static void isc_httpd_recvdone(isc_task_t *, isc_event_t *); -static void isc_httpd_senddone(isc_task_t *, isc_event_t *); -static void destroy_client(isc_httpd_t **); -static isc_result_t process_request(isc_httpd_t *, int); -static void httpdmgr_destroy(isc_httpdmgr_t *); -static isc_result_t grow_headerspace(isc_httpd_t *); -static void reset_client(isc_httpd_t *httpd); +#define ISC_HTTPD_SETRECV(c) ((c)->state = ISC_HTTPD_STATERECV) +#define ISC_HTTPD_SETRECVDONE(c) ((c)->state = ISC_HTTPD_STATERECVDONE) +#define ISC_HTTPD_SETSEND(c) ((c)->state = ISC_HTTPD_STATESEND) +#define ISC_HTTPD_SETSENDDONE(c) ((c)->state = ISC_HTTPD_STATESENDDONE) + +static void +isc_httpd_accept(isc_task_t *, isc_event_t *); +static void +isc_httpd_recvdone(isc_task_t *, isc_event_t *); +static void +isc_httpd_senddone(isc_task_t *, isc_event_t *); +static isc_result_t +process_request(isc_httpd_t *, int); +static isc_result_t +grow_headerspace(isc_httpd_t *); +static void +reset_client(isc_httpd_t *httpd); static isc_httpdaction_t render_404; static isc_httpdaction_t render_500; +#if ENABLE_AFL static void (*finishhook)(void) = NULL; +#endif /* ENABLE_AFL */ static void -destroy_client(isc_httpd_t **httpdp) { - isc_httpd_t *httpd = *httpdp; - isc_httpdmgr_t *httpdmgr = httpd->mgr; +maybe_destroy_httpd(isc_httpd_t *); +static void +destroy_httpd(isc_httpd_t *); +static void +maybe_destroy_httpdmgr(isc_httpdmgr_t *); +static void +destroy_httpdmgr(isc_httpdmgr_t *); + +static void +isc_httpdmgr_attach(isc_httpdmgr_t *, isc_httpdmgr_t **); +static void +isc_httpdmgr_detach(isc_httpdmgr_t **); + +static void +maybe_destroy_httpd(isc_httpd_t *httpd) { + if (isc_refcount_decrement(&httpd->references) == 1) { + destroy_httpd(httpd); + } +} + +static inline void +free_buffer(isc_mem_t *mctx, isc_buffer_t *buffer) { isc_region_t r; - *httpdp = NULL; + isc_buffer_region(buffer, &r); + if (r.length > 0) { + isc_mem_put(mctx, r.base, r.length); + } +} +static void +destroy_httpd(isc_httpd_t *httpd) { + isc_httpdmgr_t *httpdmgr; + + REQUIRE(VALID_HTTPD(httpd)); + + httpdmgr = httpd->mgr; + REQUIRE(VALID_HTTPDMGR(httpdmgr)); + + /* + * Unlink before calling isc_socket_detach so + * isc_httpdmgr_shutdown does not dereference a NULL pointer + * when calling isc_socket_cancel(). + */ LOCK(&httpdmgr->lock); + ISC_LIST_UNLINK(httpdmgr->running, httpd, link); + UNLOCK(&httpdmgr->lock); + httpd->magic = 0; + isc_refcount_destroy(&httpd->references); isc_socket_detach(&httpd->sock); - ISC_LIST_UNLINK(httpdmgr->running, httpd, link); - isc_buffer_region(&httpd->headerbuffer, &r); - if (r.length > 0) { - isc_mem_put(httpdmgr->mctx, r.base, r.length); + free_buffer(httpdmgr->mctx, &httpd->headerbuffer); + free_buffer(httpdmgr->mctx, &httpd->compbuffer); + + isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); + +#if ENABLE_AFL + if (finishhook != NULL) { + finishhook(); } +#endif /* ENABLE_AFL */ - isc_buffer_region(&httpd->compbuffer, &r); - if (r.length > 0) { - isc_mem_put(httpdmgr->mctx, r.base, r.length); + isc_httpdmgr_detach(&httpdmgr); +} + +static inline isc_result_t +httpdmgr_socket_accept(isc_task_t *task, isc_httpdmgr_t *httpdmgr) { + isc_result_t result = ISC_R_SUCCESS; + + /* decremented in isc_httpd_accept */ + isc_refcount_increment(&httpdmgr->references); + result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, + httpdmgr); + if (result != ISC_R_SUCCESS) { + INSIST(isc_refcount_decrement(&httpdmgr->references) > 1); } + return (result); +} - isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); +static inline void +httpd_socket_recv(isc_httpd_t *httpd, isc_region_t *region, isc_task_t *task) { + isc_result_t result = ISC_R_SUCCESS; - UNLOCK(&httpdmgr->lock); + /* decremented in isc_httpd_recvdone */ + (void)isc_refcount_increment(&httpd->references); + result = isc_socket_recv(httpd->sock, region, 1, task, + isc_httpd_recvdone, httpd); + if (result != ISC_R_SUCCESS) { + INSIST(isc_refcount_decrement(&httpd->references) > 1); + } +} - if (finishhook != NULL) - finishhook(); +static inline void +httpd_socket_send(isc_httpd_t *httpd, isc_region_t *region, isc_task_t *task) { + isc_result_t result = ISC_R_SUCCESS; - httpdmgr_destroy(httpdmgr); + /* decremented in isc_httpd_senddone */ + (void)isc_refcount_increment(&httpd->references); + result = isc_socket_send(httpd->sock, region, task, isc_httpd_senddone, + httpd); + if (result != ISC_R_SUCCESS) { + INSIST(isc_refcount_decrement(&httpd->references) > 1); + } } isc_result_t isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, isc_httpdclientok_t *client_ok, isc_httpdondestroy_t *ondestroy, void *cb_arg, - isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdmgrp) -{ + isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdmgrp) { isc_result_t result; isc_httpdmgr_t *httpdmgr; @@ -265,25 +339,25 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, REQUIRE(httpdmgrp != NULL && *httpdmgrp == NULL); httpdmgr = isc_mem_get(mctx, sizeof(isc_httpdmgr_t)); - if (httpdmgr == NULL) - return (ISC_R_NOMEMORY); + + *httpdmgr = (isc_httpdmgr_t){ .timermgr = tmgr, /* XXXMLG no attach + * function? */ + .client_ok = client_ok, + .ondestroy = ondestroy, + .cb_arg = cb_arg, + .render_404 = render_404, + .render_500 = render_500 }; isc_mutex_init(&httpdmgr->lock); - httpdmgr->mctx = NULL; isc_mem_attach(mctx, &httpdmgr->mctx); - httpdmgr->sock = NULL; isc_socket_attach(sock, &httpdmgr->sock); - httpdmgr->task = NULL; isc_task_attach(task, &httpdmgr->task); - httpdmgr->timermgr = tmgr; /* XXXMLG no attach function? */ - httpdmgr->client_ok = client_ok; - httpdmgr->ondestroy = ondestroy; - httpdmgr->cb_arg = cb_arg; - httpdmgr->flags = 0; ISC_LIST_INIT(httpdmgr->running); ISC_LIST_INIT(httpdmgr->urls); + isc_refcount_init(&httpdmgr->references, 1); + /* XXXMLG ignore errors on isc_socket_listen() */ result = isc_socket_listen(sock, SOMAXCONN); if (result != ISC_R_SUCCESS) { @@ -295,17 +369,20 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, (void)isc_socket_filter(sock, "httpready"); - result = isc_socket_accept(sock, task, isc_httpd_accept, httpdmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; + httpdmgr->magic = HTTPDMGR_MAGIC; - httpdmgr->render_404 = render_404; - httpdmgr->render_500 = render_500; + result = httpdmgr_socket_accept(task, httpdmgr); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } *httpdmgrp = httpdmgr; return (ISC_R_SUCCESS); - cleanup: +cleanup: + httpdmgr->magic = 0; + isc_refcount_decrementz(&httpdmgr->references); + isc_refcount_destroy(&httpdmgr->references); isc_task_detach(&httpdmgr->task); isc_socket_detach(&httpdmgr->sock); isc_mem_detach(&httpdmgr->mctx); @@ -315,30 +392,43 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, } static void -httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) { - isc_mem_t *mctx; - isc_httpdurl_t *url; +isc_httpdmgr_attach(isc_httpdmgr_t *source, isc_httpdmgr_t **targetp) { + REQUIRE(VALID_HTTPDMGR(source)); + REQUIRE(targetp != NULL && *targetp == NULL); - ENTER("httpdmgr_destroy"); + isc_refcount_increment(&source->references); - LOCK(&httpdmgr->lock); + *targetp = source; +} - if (!MSHUTTINGDOWN(httpdmgr)) { - NOTICE("httpdmgr_destroy not shutting down yet"); - UNLOCK(&httpdmgr->lock); - return; - } +static void +isc_httpdmgr_detach(isc_httpdmgr_t **httpdmgrp) { + REQUIRE(httpdmgrp != NULL && VALID_HTTPDMGR(*httpdmgrp)); + isc_httpdmgr_t *httpdmgr = *httpdmgrp; + *httpdmgrp = NULL; - /* - * If all clients are not shut down, don't do anything yet. - */ - if (!ISC_LIST_EMPTY(httpdmgr->running)) { - NOTICE("httpdmgr_destroy clients still active"); - UNLOCK(&httpdmgr->lock); - return; + maybe_destroy_httpdmgr(httpdmgr); +} + +static void +maybe_destroy_httpdmgr(isc_httpdmgr_t *httpdmgr) { + if (isc_refcount_decrement(&httpdmgr->references) == 1) { + destroy_httpdmgr(httpdmgr); } +} + +static void +destroy_httpdmgr(isc_httpdmgr_t *httpdmgr) { + isc_httpdurl_t *url; - NOTICE("httpdmgr_destroy detaching socket, task, and timermgr"); + isc_refcount_destroy(&httpdmgr->references); + + LOCK(&httpdmgr->lock); + + httpdmgr->magic = 0; + + INSIST(MSHUTTINGDOWN(httpdmgr)); + INSIST(ISC_LIST_EMPTY(httpdmgr->running)); isc_socket_detach(&httpdmgr->sock); isc_task_detach(&httpdmgr->task); @@ -359,13 +449,10 @@ httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) { UNLOCK(&httpdmgr->lock); isc_mutex_destroy(&httpdmgr->lock); - if (httpdmgr->ondestroy != NULL) + if (httpdmgr->ondestroy != NULL) { (httpdmgr->ondestroy)(httpdmgr->cb_arg); - - mctx = httpdmgr->mctx; - isc_mem_putanddetach(&mctx, httpdmgr, sizeof(isc_httpdmgr_t)); - - EXIT("httpdmgr_destroy"); + } + isc_mem_putanddetach(&httpdmgr->mctx, httpdmgr, sizeof(isc_httpdmgr_t)); } #define LENGTHOK(s) (httpd->recvbuf - (s) < (int)httpd->recvlen) @@ -377,8 +464,7 @@ httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) { */ static bool have_header(isc_httpd_t *httpd, const char *header, const char *value, - const char *eov) -{ + const char *eov) { char *cr, *nl, *h; size_t hlen, vlen = 0; @@ -395,44 +481,56 @@ have_header(isc_httpd_t *httpd, const char *header, const char *value, * Skip to next line; */ cr = strchr(h, '\r'); - if (cr != NULL && cr[1] == '\n') + if (cr != NULL && cr[1] == '\n') { cr++; + } nl = strchr(h, '\n'); /* last header? */ h = cr; - if (h == NULL || (nl != NULL && nl < h)) + if (h == NULL || (nl != NULL && nl < h)) { h = nl; - if (h == NULL) + } + if (h == NULL) { return (false); + } h++; continue; } - if (value == NULL) + if (value == NULL) { return (true); + } /* * Skip optional leading white space. */ h += hlen; - while (*h == ' ' || *h == '\t') + while (*h == ' ' || *h == '\t') { h++; + } /* * Terminate token search on NULL or EOL. */ while (*h != 0 && *h != '\r' && *h != '\n') { - if (strncasecmp(h, value, vlen) == 0) - if (strchr(eov, h[vlen]) != NULL) + if (strncasecmp(h, value, vlen) == 0) { + if (strchr(eov, h[vlen]) != NULL) { return (true); + /* + * Skip to next token. + */ + } + } /* * Skip to next token. */ h += strcspn(h, eov); - if (h[0] == '\r' && h[1] == '\n') + if (h[0] == '\r' && h[1] == '\n') { h++; - if (h[0] != 0) + } + if (h[0] != 0) { h++; + } } return (false); } @@ -444,8 +542,6 @@ process_request(isc_httpd_t *httpd, int length) { char *p; int delim; - ENTER("request"); - httpd->recvlen += length; httpd->recvbuf[httpd->recvlen] = 0; @@ -461,8 +557,9 @@ process_request(isc_httpd_t *httpd, int length) { s = strstr(httpd->recvbuf, "\n\n"); delim = 1; } - if (s == NULL) + if (s == NULL) { return (ISC_R_NOTFOUND); + } /* * NUL terminate request at the blank line. @@ -493,33 +590,41 @@ process_request(isc_httpd_t *httpd, int length) { s = p; while (LENGTHOK(s) && BUFLENOK(s) && (*s != '\n' && *s != '\r' && *s != '\0' && *s != ' ')) + { s++; - if (!LENGTHOK(s)) + } + if (!LENGTHOK(s)) { return (ISC_R_NOTFOUND); - if (!BUFLENOK(s)) + } + if (!BUFLENOK(s)) { return (ISC_R_NOMEMORY); + } *s = 0; /* * Make the URL relative. */ - if ((strncmp(p, "http:/", 6) == 0) - || (strncmp(p, "https:/", 7) == 0)) { + if ((strncmp(p, "http:/", 6) == 0) || (strncmp(p, "https:/", 7) == 0)) { /* Skip first / */ - while (*p != '/' && *p != 0) + while (*p != '/' && *p != 0) { p++; - if (*p == 0) + } + if (*p == 0) { return (ISC_R_RANGE); + } p++; /* Skip second / */ - while (*p != '/' && *p != 0) + while (*p != '/' && *p != 0) { p++; - if (*p == 0) + } + if (*p == 0) { return (ISC_R_RANGE); + } p++; /* Find third / */ - while (*p != '/' && *p != 0) + while (*p != '/' && *p != 0) { p++; + } if (*p == 0) { p--; *p = '/'; @@ -545,162 +650,165 @@ process_request(isc_httpd_t *httpd, int length) { * HTTP/1.0 or HTTP/1.1 for now. */ while (LENGTHOK(s) && BUFLENOK(s) && - (*s != '\n' && *s != '\r' && *s != '\0')) + (*s != '\n' && *s != '\r' && *s != '\0')) { s++; - if (!LENGTHOK(s)) + } + if (!LENGTHOK(s)) { return (ISC_R_NOTFOUND); - if (!BUFLENOK(s)) + } + if (!BUFLENOK(s)) { return (ISC_R_NOMEMORY); + } /* * Check that we have the expected eol delimiter. */ - if (strncmp(s, delim == 1 ? "\n" : "\r\n", delim) != 0) + if (strncmp(s, delim == 1 ? "\n" : "\r\n", delim) != 0) { return (ISC_R_RANGE); + } *s = 0; - if ((strncmp(p, "HTTP/1.0", 8) != 0) - && (strncmp(p, "HTTP/1.1", 8) != 0)) + if ((strncmp(p, "HTTP/1.0", 8) != 0) && + (strncmp(p, "HTTP/1.1", 8) != 0)) { return (ISC_R_RANGE); + } httpd->protocol = p; - p = s + delim; /* skip past eol */ + p = s + delim; /* skip past eol */ s = p; httpd->headers = s; - if (have_header(httpd, "Connection:", "close", ", \t\r\n")) + if (have_header(httpd, "Connection:", "close", ", \t\r\n")) { httpd->flags |= HTTPD_CLOSE; + } - if (have_header(httpd, "Host:", NULL, NULL)) + if (have_header(httpd, "Host:", NULL, NULL)) { httpd->flags |= HTTPD_FOUNDHOST; + } if (strncmp(httpd->protocol, "HTTP/1.0", 8) == 0) { - if (have_header(httpd, "Connection:", "Keep-Alive", - ", \t\r\n")) + if (have_header(httpd, "Connection:", "Keep-Alive", ", \t\r\n")) + { httpd->flags |= HTTPD_KEEPALIVE; - else + } else { httpd->flags |= HTTPD_CLOSE; + } } /* * Check for Accept-Encoding: */ #ifdef HAVE_ZLIB - if (have_header(httpd, "Accept-Encoding:", "deflate", ";, \t\r\n")) + if (have_header(httpd, "Accept-Encoding:", "deflate", ";, \t\r\n")) { httpd->flags |= HTTPD_ACCEPT_DEFLATE; -#endif + } +#endif /* ifdef HAVE_ZLIB */ /* * Standards compliance hooks here. */ - if (strcmp(httpd->protocol, "HTTP/1.1") == 0 - && ((httpd->flags & HTTPD_FOUNDHOST) == 0)) + if (strcmp(httpd->protocol, "HTTP/1.1") == 0 && + ((httpd->flags & HTTPD_FOUNDHOST) == 0)) + { return (ISC_R_RANGE); - - EXIT("request"); + } return (ISC_R_SUCCESS); } static void +isc_httpd_create(isc_httpdmgr_t *httpdmgr, isc_socket_t *sock, + isc_httpd_t **httpdp) { + isc_httpd_t *httpd; + char *headerdata; + + REQUIRE(VALID_HTTPDMGR(httpdmgr)); + REQUIRE(httpdp != NULL && *httpdp == NULL); + + httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); + + *httpd = (isc_httpd_t){ .sock = sock }; + + isc_httpdmgr_attach(httpdmgr, &httpd->mgr); + + isc_refcount_init(&httpd->references, 1); + ISC_HTTPD_SETRECV(httpd); + isc_socket_setname(httpd->sock, "httpd", NULL); + + /* + * Initialize the buffer for our headers. + */ + headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); + isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW); + + isc_buffer_initnull(&httpd->compbuffer); + isc_buffer_initnull(&httpd->bodybuffer); + reset_client(httpd); + + ISC_LINK_INIT(httpd, link); + ISC_LIST_APPEND(httpdmgr->running, httpd, link); + + httpd->magic = HTTPD_MAGIC; + + *httpdp = httpd; +} + +static void isc_httpd_accept(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; isc_httpdmgr_t *httpdmgr = ev->ev_arg; - isc_httpd_t *httpd; + isc_httpd_t *httpd = NULL; isc_region_t r; isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev; isc_sockaddr_t peeraddr; - char *headerdata; - ENTER("accept"); + REQUIRE(VALID_HTTPDMGR(httpdmgr)); LOCK(&httpdmgr->lock); if (MSHUTTINGDOWN(httpdmgr)) { - NOTICE("accept shutting down, goto out"); goto out; } if (nev->result == ISC_R_CANCELED) { - NOTICE("accept canceled, goto out"); goto out; } if (nev->result != ISC_R_SUCCESS) { /* XXXMLG log failure */ - NOTICE("accept returned failure, goto requeue"); goto requeue; } (void)isc_socket_getpeername(nev->newsocket, &peeraddr); if (httpdmgr->client_ok != NULL && - !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) { - isc_socket_detach(&nev->newsocket); - goto requeue; - } - - httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); - if (httpd == NULL) { - /* XXXMLG log failure */ - NOTICE("accept failed to allocate memory, goto requeue"); + !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) + { isc_socket_detach(&nev->newsocket); goto requeue; } - httpd->mgr = httpdmgr; - ISC_LINK_INIT(httpd, link); - ISC_LIST_APPEND(httpdmgr->running, httpd, link); - ISC_HTTPD_SETRECV(httpd); - httpd->sock = nev->newsocket; - isc_socket_setname(httpd->sock, "httpd", NULL); - httpd->flags = 0; - - /* - * Initialize the buffer for our headers. - */ - headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); - if (headerdata == NULL) { - isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); - isc_socket_detach(&nev->newsocket); - goto requeue; - } - isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW); - - isc_buffer_initnull(&httpd->compbuffer); - isc_buffer_initnull(&httpd->bodybuffer); - httpd->sendbuffer = NULL; - reset_client(httpd); + isc_httpd_create(httpdmgr, nev->newsocket, &httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; - result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, - httpd); - /* FIXME!!! */ - POST(result); - NOTICE("accept queued recv on socket"); - requeue: - result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, - httpdmgr); - if (result != ISC_R_SUCCESS) { - /* XXXMLG what to do? Log failure... */ - NOTICE("accept could not reaccept due to failure"); - } + httpd_socket_recv(httpd, &r, task); - out: +requeue: + (void)httpdmgr_socket_accept(task, httpdmgr); + +out: UNLOCK(&httpdmgr->lock); - httpdmgr_destroy(httpdmgr); + if (httpd != NULL) { + maybe_destroy_httpd(httpd); + } + maybe_destroy_httpdmgr(httpdmgr); isc_event_free(&ev); - - EXIT("accept"); } static isc_result_t -render_404(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ +render_404(const char *url, isc_httpdurl_t *urlinfo, const char *querystring, + const char *headers, void *arg, unsigned int *retcode, + const char **retmsg, const char **mimetype, isc_buffer_t *b, + isc_httpdfree_t **freecb, void **freecb_args) { static char msg[] = "No such URL.\r\n"; UNUSED(url); @@ -721,12 +829,10 @@ render_404(const char *url, isc_httpdurl_t *urlinfo, } static isc_result_t -render_500(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ +render_500(const char *url, isc_httpdurl_t *urlinfo, const char *querystring, + const char *headers, void *arg, unsigned int *retcode, + const char **retmsg, const char **mimetype, isc_buffer_t *b, + isc_httpdfree_t **freecb, void **freecb_args) { static char msg[] = "Internal server failure.\r\n"; UNUSED(url); @@ -769,8 +875,6 @@ alloc_compspace(isc_httpd_t *httpd, unsigned int size) { } newspace = isc_mem_get(httpd->mgr->mctx, size); - if (newspace == NULL) - return (ISC_R_NOMEMORY); isc_buffer_reinit(&httpd->compbuffer, newspace, size); if (r.base != NULL) { @@ -804,7 +908,7 @@ isc_httpd_compress(isc_httpd_t *httpd) { inputlen = isc_buffer_usedlength(&httpd->bodybuffer); result = alloc_compspace(httpd, inputlen); if (result != ISC_R_SUCCESS) { - return result; + return (result); } isc_buffer_region(&httpd->compbuffer, &r); @@ -813,8 +917,8 @@ isc_httpd_compress(isc_httpd_t *httpd) { * compressed data size would be bigger than the input size. */ memset(&zstr, 0, sizeof(zstr)); - zstr.total_in = zstr.avail_in = - zstr.total_out = zstr.avail_out = inputlen; + zstr.total_in = zstr.avail_in = zstr.total_out = zstr.avail_out = + inputlen; zstr.next_in = isc_buffer_base(&httpd->bodybuffer); zstr.next_out = r.base; @@ -831,7 +935,7 @@ isc_httpd_compress(isc_httpd_t *httpd) { return (ISC_R_FAILURE); } } -#endif +#endif /* ifdef HAVE_ZLIB */ static void isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { @@ -845,30 +949,25 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { bool is_compressed = false; char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - ENTER("recv"); + REQUIRE(VALID_HTTPD(httpd)); INSIST(ISC_HTTPD_ISRECV(httpd)); if (sev->result != ISC_R_SUCCESS) { - NOTICE("recv destroying client"); - destroy_client(&httpd); goto out; } result = process_request(httpd, sev->n); if (result == ISC_R_NOTFOUND) { if (httpd->recvlen >= HTTP_RECVLEN - 1) { - destroy_client(&httpd); goto out; } r.base = (unsigned char *)httpd->recvbuf + httpd->recvlen; r.length = HTTP_RECVLEN - httpd->recvlen - 1; - /* check return code? */ - (void)isc_socket_recv(httpd->sock, &r, 1, task, - isc_httpd_recvdone, httpd); + + httpd_socket_recv(httpd, &r, task); goto out; } else if (result != ISC_R_SUCCESS) { - destroy_client(&httpd); goto out; } @@ -881,63 +980,57 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { isc_buffer_initnull(&httpd->bodybuffer); isc_time_now(&now); isc_time_formathttptimestamp(&now, datebuf, sizeof(datebuf)); + LOCK(&httpd->mgr->lock); url = ISC_LIST_HEAD(httpd->mgr->urls); while (url != NULL) { - if (strcmp(httpd->url, url->url) == 0) + if (strcmp(httpd->url, url->url) == 0) { break; + } url = ISC_LIST_NEXT(url, link); } - if (url == NULL) - result = httpd->mgr->render_404(httpd->url, NULL, - httpd->querystring, - NULL, NULL, - &httpd->retcode, - &httpd->retmsg, - &httpd->mimetype, - &httpd->bodybuffer, - &httpd->freecb, - &httpd->freecb_arg); - else - result = url->action(httpd->url, url, - httpd->querystring, - httpd->headers, - url->action_arg, + UNLOCK(&httpd->mgr->lock); + + if (url == NULL) { + result = httpd->mgr->render_404( + httpd->url, NULL, httpd->querystring, NULL, NULL, + &httpd->retcode, &httpd->retmsg, &httpd->mimetype, + &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); + } else { + result = url->action(httpd->url, url, httpd->querystring, + httpd->headers, url->action_arg, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); + } if (result != ISC_R_SUCCESS) { - result = httpd->mgr->render_500(httpd->url, url, - httpd->querystring, - NULL, NULL, - &httpd->retcode, - &httpd->retmsg, - &httpd->mimetype, - &httpd->bodybuffer, - &httpd->freecb, - &httpd->freecb_arg); + result = httpd->mgr->render_500( + httpd->url, url, httpd->querystring, NULL, NULL, + &httpd->retcode, &httpd->retmsg, &httpd->mimetype, + &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); RUNTIME_CHECK(result == ISC_R_SUCCESS); } #ifdef HAVE_ZLIB if ((httpd->flags & HTTPD_ACCEPT_DEFLATE) != 0) { - result = isc_httpd_compress(httpd); - if (result == ISC_R_SUCCESS) { - is_compressed = true; - } + result = isc_httpd_compress(httpd); + if (result == ISC_R_SUCCESS) { + is_compressed = true; + } } -#endif +#endif /* ifdef HAVE_ZLIB */ isc_httpd_response(httpd); - if ((httpd->flags & HTTPD_KEEPALIVE) != 0) + if ((httpd->flags & HTTPD_KEEPALIVE) != 0) { isc_httpd_addheader(httpd, "Connection", "Keep-Alive"); + } isc_httpd_addheader(httpd, "Content-Type", httpd->mimetype); isc_httpd_addheader(httpd, "Date", datebuf); isc_httpd_addheader(httpd, "Expires", datebuf); if (url != NULL && url->isstatic) { char loadbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_formathttptimestamp(&url->loadtime, - loadbuf, sizeof(loadbuf)); + isc_time_formathttptimestamp(&url->loadtime, loadbuf, + sizeof(loadbuf)); isc_httpd_addheader(httpd, "Last-Modified", loadbuf); isc_httpd_addheader(httpd, "Cache-Control: public", NULL); } else { @@ -948,23 +1041,25 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { isc_httpd_addheader(httpd, "Server: libisc", NULL); - if (is_compressed == true) { + if (is_compressed) { isc_httpd_addheader(httpd, "Content-Encoding", "deflate"); - isc_httpd_addheaderuint(httpd, "Content-Length", - isc_buffer_usedlength(&httpd->compbuffer)); + isc_httpd_addheaderuint( + httpd, "Content-Length", + isc_buffer_usedlength(&httpd->compbuffer)); } else { - isc_httpd_addheaderuint(httpd, "Content-Length", - isc_buffer_usedlength(&httpd->bodybuffer)); + isc_httpd_addheaderuint( + httpd, "Content-Length", + isc_buffer_usedlength(&httpd->bodybuffer)); } - isc_httpd_endheaders(httpd); /* done */ + isc_httpd_endheaders(httpd); /* done */ /* * Append either the compressed or the non-compressed response body to * the response headers and store the result in httpd->sendbuffer. */ - isc_buffer_dup(httpd->mgr->mctx, - &httpd->sendbuffer, &httpd->headerbuffer); + isc_buffer_dup(httpd->mgr->mctx, &httpd->sendbuffer, + &httpd->headerbuffer); isc_buffer_setautorealloc(httpd->sendbuffer, true); databuffer = (is_compressed ? &httpd->compbuffer : &httpd->bodybuffer); isc_buffer_usedregion(databuffer, &r); @@ -975,23 +1070,22 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { */ isc_buffer_usedregion(httpd->sendbuffer, &r); - /* check return code? */ - (void)isc_socket_send(httpd->sock, &r, task, - isc_httpd_senddone, httpd); + httpd_socket_send(httpd, &r, task); - out: +out: + maybe_destroy_httpd(httpd); isc_event_free(&ev); - EXIT("recv"); } void isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) { isc_httpdmgr_t *httpdmgr; isc_httpd_t *httpd; + + REQUIRE(httpdmgrp != NULL); httpdmgr = *httpdmgrp; *httpdmgrp = NULL; - - ENTER("isc_httpdmgr_shutdown"); + REQUIRE(VALID_HTTPDMGR(httpdmgr)); LOCK(&httpdmgr->lock); @@ -1008,7 +1102,7 @@ isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) { UNLOCK(&httpdmgr->lock); - EXIT("isc_httpdmgr_shutdown"); + maybe_destroy_httpdmgr(httpdmgr); } static isc_result_t @@ -1019,12 +1113,11 @@ grow_headerspace(isc_httpd_t *httpd) { isc_buffer_region(&httpd->headerbuffer, &r); newlen = r.length + HTTP_SENDGROW; - if (newlen > HTTP_SEND_MAXLEN) + if (newlen > HTTP_SEND_MAXLEN) { return (ISC_R_NOSPACE); + } newspace = isc_mem_get(httpd->mgr->mctx, newlen); - if (newspace == NULL) - return (ISC_R_NOMEMORY); isc_buffer_reinit(&httpd->headerbuffer, newspace, newlen); @@ -1038,45 +1131,50 @@ isc_httpd_response(isc_httpd_t *httpd) { isc_result_t result; unsigned int needlen; + REQUIRE(VALID_HTTPD(httpd)); + needlen = strlen(httpd->protocol) + 1; /* protocol + space */ - needlen += 3 + 1; /* room for response code, always 3 bytes */ - needlen += strlen(httpd->retmsg) + 2; /* return msg + CRLF */ + needlen += 3 + 1; /* room for response code, always 3 bytes */ + needlen += strlen(httpd->retmsg) + 2; /* return msg + CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } } return (isc_buffer_printf(&httpd->headerbuffer, "%s %03u %s\r\n", - httpd->protocol, httpd->retcode, - httpd->retmsg)); + httpd->protocol, httpd->retcode, + httpd->retmsg)); } isc_result_t -isc_httpd_addheader(isc_httpd_t *httpd, const char *name, - const char *val) -{ +isc_httpd_addheader(isc_httpd_t *httpd, const char *name, const char *val) { isc_result_t result; unsigned int needlen; + REQUIRE(VALID_HTTPD(httpd)); + needlen = strlen(name); /* name itself */ - if (val != NULL) + if (val != NULL) { needlen += 2 + strlen(val); /* :<space> and val */ + } needlen += 2; /* CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } } if (val != NULL) { return (isc_buffer_printf(&httpd->headerbuffer, "%s: %s\r\n", - name, val)); + name, val)); } else { return (isc_buffer_printf(&httpd->headerbuffer, "%s\r\n", - name)); + name)); } } @@ -1084,10 +1182,13 @@ isc_result_t isc_httpd_endheaders(isc_httpd_t *httpd) { isc_result_t result; + REQUIRE(VALID_HTTPD(httpd)); + while (isc_buffer_availablelength(&httpd->headerbuffer) < 2) { result = grow_headerspace(httpd); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } } return (isc_buffer_printf(&httpd->headerbuffer, "\r\n")); @@ -1099,20 +1200,23 @@ isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val) { unsigned int needlen; char buf[sizeof "18446744073709551616"]; + REQUIRE(VALID_HTTPD(httpd)); + snprintf(buf, sizeof(buf), "%d", val); - needlen = strlen(name); /* name itself */ + needlen = strlen(name); /* name itself */ needlen += 2 + strlen(buf); /* :<space> and val */ - needlen += 2; /* CRLF */ + needlen += 2; /* CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } } return (isc_buffer_printf(&httpd->headerbuffer, "%s: %s\r\n", name, - buf)); + buf)); } static void @@ -1121,7 +1225,8 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) { isc_region_t r; isc_socketevent_t *sev = (isc_socketevent_t *)ev; - ENTER("senddone"); + REQUIRE(VALID_HTTPD(httpd)); + INSIST(ISC_HTTPD_ISSEND(httpd)); isc_buffer_free(&httpd->sendbuffer); @@ -1139,34 +1244,28 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) { b = &httpd->bodybuffer; httpd->freecb(b, httpd->freecb_arg); } - NOTICE("senddone free callback performed"); } if (sev->result != ISC_R_SUCCESS) { - destroy_client(&httpd); goto out; } if ((httpd->flags & HTTPD_CLOSE) != 0) { - destroy_client(&httpd); goto out; } ISC_HTTPD_SETRECV(httpd); - NOTICE("senddone restarting recv on socket"); - reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; - /* check return code? */ - (void)isc_socket_recv(httpd->sock, &r, 1, task, - isc_httpd_recvdone, httpd); + + httpd_socket_recv(httpd, &r, task); out: + maybe_destroy_httpd(httpd); isc_event_free(&ev); - EXIT("senddone"); } static void @@ -1195,32 +1294,27 @@ reset_client(isc_httpd_t *httpd) { isc_result_t isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url, - isc_httpdaction_t *func, void *arg) -{ + isc_httpdaction_t *func, void *arg) { + /* REQUIRE(VALID_HTTPDMGR(httpdmgr)); Dummy function */ + return (isc_httpdmgr_addurl2(httpdmgr, url, false, func, arg)); } isc_result_t -isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, - bool isstatic, - isc_httpdaction_t *func, void *arg) -{ +isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, bool isstatic, + isc_httpdaction_t *func, void *arg) { isc_httpdurl_t *item; + REQUIRE(VALID_HTTPDMGR(httpdmgr)); + if (url == NULL) { httpdmgr->render_404 = func; return (ISC_R_SUCCESS); } item = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpdurl_t)); - if (item == NULL) - return (ISC_R_NOMEMORY); item->url = isc_mem_strdup(httpdmgr->mctx, url); - if (item->url == NULL) { - isc_mem_put(httpdmgr->mctx, item, sizeof(isc_httpdurl_t)); - return (ISC_R_NOMEMORY); - } item->action = func; item->action_arg = arg; @@ -1228,13 +1322,19 @@ isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, isc_time_now(&item->loadtime); ISC_LINK_INIT(item, link); + + LOCK(&httpdmgr->lock); ISC_LIST_APPEND(httpdmgr->urls, item, link); + UNLOCK(&httpdmgr->lock); return (ISC_R_SUCCESS); } void -isc_httpd_setfinishhook(void (*fn)(void)) -{ +isc_httpd_setfinishhook(void (*fn)(void)) { +#if ENABLE_AFL finishhook = fn; +#else /* ENABLE_AFL */ + UNUSED(fn); +#endif /* ENABLE_AFL */ } diff --git a/lib/isc/include/.clang-format b/lib/isc/include/.clang-format new file mode 120000 index 00000000..0e62f72b --- /dev/null +++ b/lib/isc/include/.clang-format @@ -0,0 +1 @@ +../../../.clang-format.headers
\ No newline at end of file diff --git a/lib/isc/include/Makefile.in b/lib/isc/include/Makefile.in index 3b21e6e0..1e62514e 100644 --- a/lib/isc/include/Makefile.in +++ b/lib/isc/include/Makefile.in @@ -2,7 +2,7 @@ # # 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 http://mozilla.org/MPL/2.0/. +# 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. diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index 9577e4bd..2a43437f 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -2,7 +2,7 @@ # # 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 http://mozilla.org/MPL/2.0/. +# 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. @@ -18,23 +18,22 @@ VERSION=@BIND9_VERSION@ # machine generated. The latter are handled specially in the # install target below. # -HEADERS = aes.h app.h assertions.h atomic.h backtrace.h \ +HEADERS = aes.h app.h assertions.h astack.h atomic.h backtrace.h \ base32.h base64.h bind9.h buffer.h bufferlist.h \ - commandline.h counter.h crc64.h deprecated.h \ - errno.h error.h event.h eventclass.h \ + cmocka.h commandline.h counter.h crc64.h deprecated.h \ + endian.h errno.h error.h event.h eventclass.h \ file.h formatcheck.h fsaccess.h fuzz.h \ - hash.h heap.h hex.h hmac.h ht.h httpd.h \ + hash.h heap.h hex.h hmac.h hp.h ht.h httpd.h \ interfaceiter.h iterated_hash.h \ - json.h lang.h lex.h lfsr.h lib.h likely.h list.h log.h \ - magic.h md.h mem.h meminfo.h mutexblock.h \ - netaddr.h netscope.h nonce.h os.h parseint.h \ + lang.h lex.h lfsr.h lib.h likely.h list.h log.h \ + magic.h md.h mem.h meminfo.h mutexatomic.h mutexblock.h \ + netaddr.h netmgr.h netscope.h nonce.h os.h parseint.h \ pool.h portset.h print.h queue.h quota.h \ radix.h random.h ratelimiter.h refcount.h regex.h \ region.h resource.h result.h resultclass.h rwlock.h \ - safe.h serial.h sockaddr.h socket.h \ + safe.h serial.h siphash.h sockaddr.h socket.h \ stats.h stdio.h strerr.h string.h symtab.h \ - task.h taskpool.h timer.h tm.h types.h util.h version.h \ - xml.h + task.h taskpool.h timer.h tm.h types.h utf8.h util.h version.h SUBDIRS = TARGETS = diff --git a/lib/isc/include/isc/aes.h b/lib/isc/include/isc/aes.h index 6d6a8e4b..42b6ab12 100644 --- a/lib/isc/include/isc/aes.h +++ b/lib/isc/include/isc/aes.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file isc/aes.h */ #ifndef ISC_AES_H diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h index 75161b9f..9786d421 100644 --- a/lib/isc/include/isc/app.h +++ b/lib/isc/include/isc/app.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_APP_H #define ISC_APP_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/app.h * \brief ISC Application Support @@ -90,9 +89,9 @@ typedef isc_event_t isc_appevent_t; -#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0) -#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1) -#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535) +#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0) +#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1) +#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535) /*% * This structure is actually just the common prefix of an application context @@ -103,14 +102,7 @@ typedef isc_event_t isc_appevent_t; * of the isc_app_ routines to work. app implementations must maintain * all app context invariants. */ -struct isc_appctx { - unsigned int impmagic; - unsigned int magic; -}; - -#define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c') -#define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \ - (c)->magic == ISCAPI_APPCTX_MAGIC) +struct isc_appctx; ISC_LANG_BEGINDECLS @@ -184,10 +176,10 @@ isc_app_isrunning(void); *\li false App is not running. */ -isc_result_t +void isc_app_ctxshutdown(isc_appctx_t *ctx); -isc_result_t +void isc_app_shutdown(void); /*!< * \brief Request application shutdown. @@ -205,13 +197,13 @@ isc_app_shutdown(void); *\li ISC_R_UNEXPECTED */ -isc_result_t +void isc_app_ctxsuspend(isc_appctx_t *ctx); /*!< * \brief This has the same behavior as isc_app_ctxsuspend(). */ -isc_result_t +void isc_app_reload(void); /*!< * \brief Request application reload. @@ -295,44 +287,6 @@ isc_appctx_destroy(isc_appctx_t **ctxp); *\li *ctxp == NULL. */ -void -isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr); -/*!< - * \brief Associate a task manager with an application context. - * - * This must be done before running tasks within the application context. - * - * Requires: - *\li 'ctx' is a valid application context. - *\li 'taskmgr' is a valid task manager. - */ - -void -isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr); -/*!< - * \brief Associate a socket manager with an application context. - * - * This must be done before handling socket events within the application - * context. - * - * Requires: - *\li 'ctx' is a valid application context. - *\li 'socketmgr' is a valid socket manager. - */ - -void -isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr); -/*!< - * \brief Associate a socket timer with an application context. - * - * This must be done before handling timer events within the application - * context. - * - * Requires: - *\li 'ctx' is a valid application context. - *\li 'timermgr' is a valid timer manager. - */ - ISC_LANG_ENDDECLS #endif /* ISC_APP_H */ diff --git a/lib/isc/include/isc/assertions.h b/lib/isc/include/isc/assertions.h index e89b43ec..7823f65c 100644 --- a/lib/isc/include/isc/assertions.h +++ b/lib/isc/include/isc/assertions.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -34,38 +34,38 @@ typedef void (*isc_assertioncallback_t)(const char *, int, isc_assertiontype_t, /* coverity[+kill] */ ISC_PLATFORM_NORETURN_PRE -void isc_assertion_failed(const char *, int, isc_assertiontype_t, - const char *) ISC_PLATFORM_NORETURN_POST; - void -isc_assertion_setcallback(isc_assertioncallback_t); +isc_assertion_failed(const char *, int, isc_assertiontype_t, + const char *) ISC_PLATFORM_NORETURN_POST; + +void isc_assertion_setcallback(isc_assertioncallback_t); const char * isc_assertion_typetotext(isc_assertiontype_t type); -#define ISC_REQUIRE(cond) \ - ((void) (ISC_LIKELY(cond) || \ - ((isc_assertion_failed)(__FILE__, __LINE__, \ - isc_assertiontype_require, \ - #cond), 0))) +#define ISC_REQUIRE(cond) \ + ((void)(ISC_LIKELY(cond) || \ + ((isc_assertion_failed)(__FILE__, __LINE__, \ + isc_assertiontype_require, #cond), \ + 0))) -#define ISC_ENSURE(cond) \ - ((void) (ISC_LIKELY(cond) || \ - ((isc_assertion_failed)(__FILE__, __LINE__, \ - isc_assertiontype_ensure, \ - #cond), 0))) +#define ISC_ENSURE(cond) \ + ((void)(ISC_LIKELY(cond) || \ + ((isc_assertion_failed)(__FILE__, __LINE__, \ + isc_assertiontype_ensure, #cond), \ + 0))) -#define ISC_INSIST(cond) \ - ((void) (ISC_LIKELY(cond) || \ - ((isc_assertion_failed)(__FILE__, __LINE__, \ - isc_assertiontype_insist, \ - #cond), 0))) +#define ISC_INSIST(cond) \ + ((void)(ISC_LIKELY(cond) || \ + ((isc_assertion_failed)(__FILE__, __LINE__, \ + isc_assertiontype_insist, #cond), \ + 0))) -#define ISC_INVARIANT(cond) \ - ((void) (ISC_LIKELY(cond) || \ - ((isc_assertion_failed)(__FILE__, __LINE__, \ - isc_assertiontype_invariant, \ - #cond), 0))) +#define ISC_INVARIANT(cond) \ + ((void)(ISC_LIKELY(cond) || \ + ((isc_assertion_failed)(__FILE__, __LINE__, \ + isc_assertiontype_invariant, #cond), \ + 0))) ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/astack.h b/lib/isc/include/isc/astack.h new file mode 100644 index 00000000..c85fee64 --- /dev/null +++ b/lib/isc/include/isc/astack.h @@ -0,0 +1,47 @@ +/* + * 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 + +#include <inttypes.h> + +#include <isc/mem.h> +#include <isc/types.h> + +isc_astack_t * +isc_astack_new(isc_mem_t *mctx, size_t size); +/*%< + * Allocate and initialize a new array stack of size 'size'. + */ + +void +isc_astack_destroy(isc_astack_t *stack); +/*%< + * Free an array stack 'stack'. + * + * Requires: + * \li 'stack' is empty. + */ + +bool +isc_astack_trypush(isc_astack_t *stack, void *obj); +/*%< + * Try to push 'obj' onto array stack 'astack'. On failure, either + * because the stack size limit has been reached or because another + * thread has already changed the stack pointer, return 'false'. + */ + +void * +isc_astack_pop(isc_astack_t *stack); +/*%< + * Pop an object off of array stack 'stack'. If the stack is empty, + * return NULL. + */ diff --git a/lib/isc/include/isc/atomic.h b/lib/isc/include/isc/atomic.h index 893f5526..0d95e589 100644 --- a/lib/isc/include/isc/atomic.h +++ b/lib/isc/include/isc/atomic.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,17 +11,65 @@ #pragma once +#ifdef ISC_MUTEX_ATOMICS +#include <isc/mutexatomic.h> +#else /* ifdef ISC_MUTEX_ATOMICS */ #if HAVE_STDATOMIC_H #include <stdatomic.h> -#else +#else /* if HAVE_STDATOMIC_H */ #include <isc/stdatomic.h> -#endif +#endif /* if HAVE_STDATOMIC_H */ +#endif /* ifdef ISC_MUTEX_ATOMICS */ /* * We define a few additional macros to make things easier */ -#define atomic_store_relaxed(o, v) atomic_store_explicit((o), \ - (v), \ - memory_order_relaxed) +/* Relaxed Memory Ordering */ + +#define atomic_store_relaxed(o, v) \ + atomic_store_explicit((o), (v), memory_order_relaxed) #define atomic_load_relaxed(o) atomic_load_explicit((o), memory_order_relaxed) +#define atomic_fetch_add_relaxed(o, v) \ + atomic_fetch_add_explicit((o), (v), memory_order_relaxed) +#define atomic_fetch_sub_relaxed(o, v) \ + atomic_fetch_sub_explicit((o), (v), memory_order_relaxed) +#define atomic_fetch_or_relaxed(o, v) \ + atomic_fetch_or_explicit((o), (v), memory_order_relaxed) +#define atomic_fetch_and_relaxed(o, v) \ + atomic_fetch_and_explicit((o), (v), memory_order_relaxed) +#define atomic_exchange_relaxed(o, v) \ + atomic_exchange_explicit((o), (v), memory_order_relaxed) +#define atomic_compare_exchange_weak_relaxed(o, e, d) \ + atomic_compare_exchange_weak_explicit( \ + (o), (e), (d), memory_order_relaxed, memory_order_relaxed) +#define atomic_compare_exchange_strong_relaxed(o, e, d) \ + atomic_compare_exchange_strong_explicit( \ + (o), (e), (d), memory_order_relaxed, memory_order_relaxed) +#define atomic_compare_exchange_strong_acq_rel(o, e, d) \ + atomic_compare_exchange_strong_explicit( \ + (o), (e), (d), memory_order_acq_rel, memory_order_acquire) + +/* Acquire-Release Memory Ordering */ + +#define atomic_store_release(o, v) \ + atomic_store_explicit((o), (v), memory_order_release) +#define atomic_load_acquire(o) atomic_load_explicit((o), memory_order_acquire) +#define atomic_fetch_add_release(o, v) \ + atomic_fetch_add_explicit((o), (v), memory_order_release) +#define atomic_fetch_sub_release(o, v) \ + atomic_fetch_sub_explicit((o), (v), memory_order_release) +#define atomic_fetch_and_release(o, v) \ + atomic_fetch_and_explicit((o), (v), memory_order_release) +#define atomic_fetch_or_release(o, v) \ + atomic_fetch_or_explicit((o), (v), memory_order_release) +#define atomic_exchange_acq_rel(o, v) \ + atomic_exchange_explicit((o), (v), memory_order_acq_rel) +#define atomic_fetch_sub_acq_rel(o, v) \ + atomic_fetch_sub_explicit((o), (v), memory_order_acq_rel) +#define atomic_compare_exchange_weak_acq_rel(o, e, d) \ + atomic_compare_exchange_weak_explicit( \ + (o), (e), (d), memory_order_acq_rel, memory_order_acquire) +#define atomic_compare_exchange_strong_acq_rel(o, e, d) \ + atomic_compare_exchange_strong_explicit( \ + (o), (e), (d), memory_order_acq_rel, memory_order_acquire) diff --git a/lib/isc/include/isc/backtrace.h b/lib/isc/include/isc/backtrace.h index 27ab9da6..7776eddf 100644 --- a/lib/isc/include/isc/backtrace.h +++ b/lib/isc/include/isc/backtrace.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file isc/backtrace.h * \brief provide a back trace of the running process to help debug problems. * @@ -44,13 +43,13 @@ *** Types ***/ struct isc_backtrace_symmap { - void *addr; - const char *symbol; + void * addr; + const char *symbol; }; LIBISC_EXTERNAL_DATA extern const int isc__backtrace_nsymbols; -LIBISC_EXTERNAL_DATA extern const - isc_backtrace_symmap_t isc__backtrace_symtable[]; +LIBISC_EXTERNAL_DATA extern const isc_backtrace_symmap_t + isc__backtrace_symtable[]; /*** *** Functions @@ -123,4 +122,4 @@ isc_backtrace_getsymbol(const void *addr, const char **symbolp, */ ISC_LANG_ENDDECLS -#endif /* ISC_BACKTRACE_H */ +#endif /* ISC_BACKTRACE_H */ diff --git a/lib/isc/include/isc/base32.h b/lib/isc/include/isc/base32.h index 6ac9fcf2..65d79cec 100644 --- a/lib/isc/include/isc/base32.h +++ b/lib/isc/include/isc/base32.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -34,8 +34,8 @@ ISC_LANG_BEGINDECLS ***/ isc_result_t -isc_base32_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target); +isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target); isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); diff --git a/lib/isc/include/isc/base64.h b/lib/isc/include/isc/base64.h index 108bdae0..313329ad 100644 --- a/lib/isc/include/isc/base64.h +++ b/lib/isc/include/isc/base64.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_BASE64_H #define ISC_BASE64_H 1 @@ -25,8 +24,8 @@ ISC_LANG_BEGINDECLS ***/ isc_result_t -isc_base64_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target); +isc_base64_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target); /*!< * \brief Convert data into base64 encoded text. * diff --git a/lib/isc/include/isc/bind9.h b/lib/isc/include/isc/bind9.h index bb5474f2..85c60e7c 100644 --- a/lib/isc/include/isc/bind9.h +++ b/lib/isc/include/isc/bind9.h @@ -3,17 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_BIND9_H #define ISC_BIND9_H 1 #include <stdbool.h> + #include <isc/platform.h> /* diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h index 07d25995..4072f144 100644 --- a/lib/isc/include/isc/buffer.h +++ b/lib/isc/include/isc/buffer.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,15 +13,15 @@ #define ISC_BUFFER_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/buffer.h * - * \brief A buffer is a region of memory, together with a set of related subregions. - * Buffers are used for parsing and I/O operations. + * \brief A buffer is a region of memory, together with a set of related + * subregions. Buffers are used for parsing and I/O operations. * - * The 'used region' and the 'available' region are disjoint, and their + * The 'used region' and the 'available region' are disjoint, and their * union is the buffer's region. The used region extends from the beginning * of the buffer region to the last used byte. The available region * extends from one byte greater than the last used byte to the end of the @@ -32,7 +32,7 @@ * 'consumed region' and the 'remaining region'. The union of these two * regions is the used region. The consumed region extends from the beginning * of the used region to the byte before the 'current' offset (if any). The - * 'remaining' region the current pointer to the end of the used + * 'remaining' region extends from the current offset to the end of the used * region. The size of the consumed region can be changed using various * buffer commands. Initially, the consumed region is empty. * @@ -121,12 +121,12 @@ ISC_LANG_BEGINDECLS /*! *** Magic numbers ***/ -#define ISC_BUFFER_MAGIC 0x42756621U /* Buf!. */ -#define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC) +#define ISC_BUFFER_MAGIC 0x42756621U /* Buf!. */ +#define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC) /*@}*/ /*! - * Size granularity for dynamically resizeable buffers; when reserving + * Size granularity for dynamically resizable buffers; when reserving * space in a buffer, we round the allocated buffer length up to the * nearest * multiple of this value. */ @@ -143,25 +143,25 @@ ISC_LANG_BEGINDECLS /*! * Fundamental buffer elements. (A through E in the introductory comment.) */ -#define isc_buffer_base(b) ((void *)(b)->base) /*a*/ +#define isc_buffer_base(b) ((void *)(b)->base) /*a*/ #define isc_buffer_current(b) \ - ((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/ -#define isc_buffer_active(b) \ - ((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/ -#define isc_buffer_used(b) \ - ((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/ -#define isc_buffer_length(b) ((b)->length) /*e*/ + ((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/ +#define isc_buffer_active(b) \ + ((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/ +#define isc_buffer_used(b) \ + ((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/ +#define isc_buffer_length(b) ((b)->length) /*e*/ /*@}*/ /*@{*/ /*! * Derived lengths. (Described in the introductory comment.) */ -#define isc_buffer_usedlength(b) ((b)->used) /* d-a */ -#define isc_buffer_consumedlength(b) ((b)->current) /* b-a */ -#define isc_buffer_remaininglength(b) ((b)->used - (b)->current) /* d-b */ -#define isc_buffer_activelength(b) ((b)->active - (b)->current) /* c-b */ -#define isc_buffer_availablelength(b) ((b)->length - (b)->used) /* e-d */ +#define isc_buffer_usedlength(b) ((b)->used) /* d-a */ +#define isc_buffer_consumedlength(b) ((b)->current) /* b-a */ +#define isc_buffer_remaininglength(b) ((b)->used - (b)->current) /* d-b */ +#define isc_buffer_activelength(b) ((b)->active - (b)->current) /* c-b */ +#define isc_buffer_availablelength(b) ((b)->length - (b)->used) /* e-d */ /*@}*/ /*! @@ -171,28 +171,28 @@ ISC_LANG_BEGINDECLS */ struct isc_buffer { - unsigned int magic; - void *base; + unsigned int magic; + void * base; /*@{*/ /*! The following integers are byte offsets from 'base'. */ - unsigned int length; - unsigned int used; - unsigned int current; - unsigned int active; + unsigned int length; + unsigned int used; + unsigned int current; + unsigned int active; /*@}*/ /*! linkable */ - ISC_LINK(isc_buffer_t) link; + ISC_LINK(isc_buffer_t) link; /*! private internal elements */ - isc_mem_t *mctx; + isc_mem_t *mctx; /* automatically realloc buffer at put* */ - bool autore; + bool autore; }; /*** *** Functions ***/ -isc_result_t +void isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, unsigned int length); /*!< @@ -204,10 +204,6 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, * *\li "dynbuffer" is non-NULL, and "*dynbuffer" is NULL. * - * Returns: - *\li ISC_R_SUCCESS - success - *\li ISC_R_NOMEMORY - no memory available - * * Note: *\li Changing the buffer's length field is not permitted. */ @@ -500,7 +496,7 @@ isc_buffer_getuint8(isc_buffer_t *b); * *\li 'b' is a valid buffer. * - *\li The length of the available region of 'b' is at least 1. + *\li The length of the remaining region of 'b' is at least 1. * * Ensures: * @@ -519,7 +515,7 @@ isc__buffer_putuint8(isc_buffer_t *b, uint8_t val); * Requires: *\li 'b' is a valid buffer. * - *\li The length of the unused region of 'b' is at least 1 + *\li The length of the available region of 'b' is at least 1 * or the buffer has autoreallocation enabled. * * Ensures: @@ -529,15 +525,14 @@ isc__buffer_putuint8(isc_buffer_t *b, uint8_t val); uint16_t isc_buffer_getuint16(isc_buffer_t *b); /*!< - * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert - * it to host byte order, and return it. + * \brief Read an unsigned 16-bit integer in network byte order from 'b', + * convert it to host byte order, and return it. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the available region of 'b' is at least 2 - * or the buffer has autoreallocation enabled. + *\li The length of the remaining region of 'b' is at least 2. * * Ensures: * @@ -557,7 +552,7 @@ isc__buffer_putuint16(isc_buffer_t *b, uint16_t val); * Requires: *\li 'b' is a valid buffer. * - *\li The length of the unused region of 'b' is at least 2 + *\li The length of the available region of 'b' is at least 2 * or the buffer has autoreallocation enabled. * * Ensures: @@ -567,14 +562,14 @@ isc__buffer_putuint16(isc_buffer_t *b, uint16_t val); uint32_t isc_buffer_getuint32(isc_buffer_t *b); /*!< - * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert - * it to host byte order, and return it. + * \brief Read an unsigned 32-bit integer in network byte order from 'b', + * convert it to host byte order, and return it. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the available region of 'b' is at least 4. + *\li The length of the remaining region of 'b' is at least 4. * * Ensures: * @@ -594,7 +589,7 @@ isc__buffer_putuint32(isc_buffer_t *b, uint32_t val); * Requires: *\li 'b' is a valid buffer. * - *\li The length of the unused region of 'b' is at least 4 + *\li The length of the available region of 'b' is at least 4 * or the buffer has autoreallocation enabled. * * Ensures: @@ -611,7 +606,7 @@ isc_buffer_getuint48(isc_buffer_t *b); * *\li 'b' is a valid buffer. * - *\li The length of the available region of 'b' is at least 6. + *\li The length of the remaining region of 'b' is at least 6. * * Ensures: * @@ -631,7 +626,7 @@ isc__buffer_putuint48(isc_buffer_t *b, uint64_t val); * Requires: *\li 'b' is a valid buffer. * - *\li The length of the unused region of 'b' is at least 6 + *\li The length of the available region of 'b' is at least 6 * or the buffer has autoreallocation enabled. * * Ensures: @@ -647,7 +642,7 @@ isc__buffer_putuint24(isc_buffer_t *b, uint32_t val); * Requires: *\li 'b' is a valid buffer. * - * The length of the unused region of 'b' is at least 3 + *\li The length of the available region of 'b' is at least 3 * or the buffer has autoreallocation enabled. * * Ensures: @@ -661,11 +656,15 @@ isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, * \brief Copy 'length' bytes of memory at 'base' into 'b'. * * Requires: - *\li 'b' is a valid buffer, and it has at least 'length' - * or the buffer has autoreallocation enabled. + *\li 'b' is a valid buffer. * *\li 'base' points to 'length' bytes of valid memory. * + *\li The length of the available region of 'b' is at least 'length' + * or the buffer has autoreallocation enabled. + * + * Ensures: + *\li The used pointer in 'b' is advanced by 'length'. */ void @@ -676,9 +675,13 @@ isc__buffer_putstr(isc_buffer_t *b, const char *source); * Requires: *\li 'b' is a valid buffer. * - *\li 'source' to be a valid NULL terminated string. + *\li 'source' is a valid NULL terminated string. * - *\li strlen(source) <= isc_buffer_available(b) || b->mctx != NULL + *\li The length of the available region of 'b' is at least strlen('source') + * or the buffer has autoreallocation enabled. + * + * Ensures: + *\li The used pointer in 'b' is advanced by strlen('source'). */ void @@ -689,23 +692,28 @@ isc_buffer_putdecint(isc_buffer_t *b, int64_t v); * Requires: *\li 'b' is a valid buffer. * - *\li strlen(dec(v)) <= isc_buffer_available(b) || b->mctx != NULL + *\li The length of the available region of 'b' is at least strlen(dec('v')) + * or the buffer has autoreallocation enabled. + * + * Ensures: + *\li The used pointer in 'b' is advanced by strlen(dec('v')). */ - - isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r); /*!< * \brief Copy the contents of 'r' into 'b'. * + * Notes: + *\li If 'b' has autoreallocation enabled, and the length of 'r' is greater + * than the length of the available region of 'b', 'b' is reallocated. + * * Requires: *\li 'b' is a valid buffer. * *\li 'r' is a valid region. * * Returns: - * *\li ISC_R_SUCCESS *\li ISC_R_NOSPACE The available region of 'b' is not * big enough. @@ -714,17 +722,14 @@ isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r); isc_result_t isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src); /*!< - * \brief Allocate 'dst' and copy used contents of 'src' into it + * \brief Allocate 'dst' and copy used contents of 'src' into it. * * Requires: - *\li 'dstp' is not NULL and *dst is NULL + *\li 'dstp' is not NULL and *dst is NULL. *\li 'src' is a valid buffer. * * Returns: - * *\li ISC_R_SUCCESS - *\li ISC_R_NOSPACE The available region of 'b' is not - * big enough. */ isc_result_t @@ -738,8 +743,9 @@ isc_buffer_printf(isc_buffer_t *b, const char *format, ...) *\li The 'format' argument is a printf(3) string, with additional arguments * as necessary. * - *\li If 'b' has autoreallocation enabled, and the formatted string - * would overrun the buffer, the buffer is reallocated. + *\li If 'b' has autoreallocation enabled, and the length of the formatted + * string is greater than the length of the available region of 'b', 'b' + * is reallocated. * * Requires: * @@ -785,271 +791,275 @@ ISC_LANG_ENDDECLS * true/false, they could at least assert a contractual requirement for * non-const buffers when needed. */ -#define ISC__BUFFER_INIT(_b, _base, _length) \ - do { \ - (_b)->base = _base; \ - (_b)->length = (_length); \ - (_b)->used = 0; \ - (_b)->current = 0; \ - (_b)->active = 0; \ - (_b)->mctx = NULL; \ - ISC_LINK_INIT(_b, link); \ +#define ISC__BUFFER_INIT(_b, _base, _length) \ + do { \ + (_b)->base = _base; \ + (_b)->length = (_length); \ + (_b)->used = 0; \ + (_b)->current = 0; \ + (_b)->active = 0; \ + (_b)->mctx = NULL; \ + ISC_LINK_INIT(_b, link); \ (_b)->magic = ISC_BUFFER_MAGIC; \ - (_b)->autore = false; \ + (_b)->autore = false; \ } while (0) #define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0) #define ISC__BUFFER_INVALIDATE(_b) \ - do { \ - (_b)->magic = 0; \ + do { \ + (_b)->magic = 0; \ (_b)->base = NULL; \ - (_b)->length = 0; \ - (_b)->used = 0; \ + (_b)->length = 0; \ + (_b)->used = 0; \ (_b)->current = 0; \ - (_b)->active = 0; \ + (_b)->active = 0; \ } while (0) -#define ISC__BUFFER_REGION(_b, _r) \ - do { \ - (_r)->base = (_b)->base; \ +#define ISC__BUFFER_REGION(_b, _r) \ + do { \ + (_r)->base = (_b)->base; \ (_r)->length = (_b)->length; \ } while (0) -#define ISC__BUFFER_USEDREGION(_b, _r) \ - do { \ - (_r)->base = (_b)->base; \ +#define ISC__BUFFER_USEDREGION(_b, _r) \ + do { \ + (_r)->base = (_b)->base; \ (_r)->length = (_b)->used; \ } while (0) -#define ISC__BUFFER_AVAILABLEREGION(_b, _r) \ - do { \ - (_r)->base = isc_buffer_used(_b); \ +#define ISC__BUFFER_AVAILABLEREGION(_b, _r) \ + do { \ + (_r)->base = isc_buffer_used(_b); \ (_r)->length = isc_buffer_availablelength(_b); \ } while (0) -#define ISC__BUFFER_ADD(_b, _n) \ - do { \ +#define ISC__BUFFER_ADD(_b, _n) \ + do { \ (_b)->used += (_n); \ } while (0) -#define ISC__BUFFER_SUBTRACT(_b, _n) \ - do { \ - (_b)->used -= (_n); \ - if ((_b)->current > (_b)->used) \ +#define ISC__BUFFER_SUBTRACT(_b, _n) \ + do { \ + (_b)->used -= (_n); \ + if ((_b)->current > (_b)->used) \ (_b)->current = (_b)->used; \ - if ((_b)->active > (_b)->used) \ - (_b)->active = (_b)->used; \ + if ((_b)->active > (_b)->used) \ + (_b)->active = (_b)->used; \ } while (0) -#define ISC__BUFFER_CLEAR(_b) \ - do { \ - (_b)->used = 0; \ +#define ISC__BUFFER_CLEAR(_b) \ + do { \ + (_b)->used = 0; \ (_b)->current = 0; \ - (_b)->active = 0; \ + (_b)->active = 0; \ } while (0) -#define ISC__BUFFER_CONSUMEDREGION(_b, _r) \ - do { \ - (_r)->base = (_b)->base; \ +#define ISC__BUFFER_CONSUMEDREGION(_b, _r) \ + do { \ + (_r)->base = (_b)->base; \ (_r)->length = (_b)->current; \ } while (0) -#define ISC__BUFFER_REMAININGREGION(_b, _r) \ - do { \ - (_r)->base = isc_buffer_current(_b); \ +#define ISC__BUFFER_REMAININGREGION(_b, _r) \ + do { \ + (_r)->base = isc_buffer_current(_b); \ (_r)->length = isc_buffer_remaininglength(_b); \ } while (0) -#define ISC__BUFFER_ACTIVEREGION(_b, _r) \ - do { \ - if ((_b)->current < (_b)->active) { \ - (_r)->base = isc_buffer_current(_b); \ +#define ISC__BUFFER_ACTIVEREGION(_b, _r) \ + do { \ + if ((_b)->current < (_b)->active) { \ + (_r)->base = isc_buffer_current(_b); \ (_r)->length = isc_buffer_activelength(_b); \ - } else { \ - (_r)->base = NULL; \ - (_r)->length = 0; \ - } \ + } else { \ + (_r)->base = NULL; \ + (_r)->length = 0; \ + } \ } while (0) -#define ISC__BUFFER_SETACTIVE(_b, _n) \ - do { \ +#define ISC__BUFFER_SETACTIVE(_b, _n) \ + do { \ (_b)->active = (_b)->current + (_n); \ } while (0) -#define ISC__BUFFER_FIRST(_b) \ - do { \ +#define ISC__BUFFER_FIRST(_b) \ + do { \ (_b)->current = 0; \ } while (0) -#define ISC__BUFFER_FORWARD(_b, _n) \ - do { \ +#define ISC__BUFFER_FORWARD(_b, _n) \ + do { \ (_b)->current += (_n); \ } while (0) -#define ISC__BUFFER_BACK(_b, _n) \ - do { \ +#define ISC__BUFFER_BACK(_b, _n) \ + do { \ (_b)->current -= (_n); \ } while (0) -#define ISC__BUFFER_PUTMEM(_b, _base, _length) \ - do { \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= (unsigned int) _length); \ - if (_length > 0U) { \ +#define ISC__BUFFER_PUTMEM(_b, _base, _length) \ + do { \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= \ + (unsigned int)_length); \ + if (_length > 0U) { \ memmove(isc_buffer_used(_b), (_base), (_length)); \ - (_b)->used += (_length); \ - } \ + (_b)->used += (_length); \ + } \ } while (0) -#define ISC__BUFFER_PUTSTR(_b, _source) \ - do { \ - unsigned int _length; \ - unsigned char *_cp; \ - _length = (unsigned int)strlen(_source); \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= _length); \ - _cp = isc_buffer_used(_b); \ - memmove(_cp, (_source), _length); \ - (_b)->used += (_length); \ +#define ISC__BUFFER_PUTSTR(_b, _source) \ + do { \ + unsigned int _length; \ + unsigned char *_cp; \ + _length = (unsigned int)strlen(_source); \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= _length); \ + _cp = isc_buffer_used(_b); \ + memmove(_cp, (_source), _length); \ + (_b)->used += (_length); \ } while (0) -#define ISC__BUFFER_PUTUINT8(_b, _val) \ - do { \ - unsigned char *_cp; \ - /* evaluate (_val) only once */ \ - uint8_t _val2 = (_val); \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, 1) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= 1U); \ - _cp = isc_buffer_used(_b); \ - (_b)->used++; \ - _cp[0] = _val2; \ +#define ISC__BUFFER_PUTUINT8(_b, _val) \ + do { \ + unsigned char *_cp; \ + /* evaluate (_val) only once */ \ + uint8_t _val2 = (_val); \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, 1) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= 1U); \ + _cp = isc_buffer_used(_b); \ + (_b)->used++; \ + _cp[0] = _val2; \ } while (0) -#define ISC__BUFFER_PUTUINT16(_b, _val) \ - do { \ - unsigned char *_cp; \ - /* evaluate (_val) only once */ \ - uint16_t _val2 = (_val); \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, 2) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= 2U); \ - _cp = isc_buffer_used(_b); \ - (_b)->used += 2; \ - _cp[0] = (unsigned char)(_val2 >> 8); \ - _cp[1] = (unsigned char)_val2; \ +#define ISC__BUFFER_PUTUINT16(_b, _val) \ + do { \ + unsigned char *_cp; \ + /* evaluate (_val) only once */ \ + uint16_t _val2 = (_val); \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, 2) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= 2U); \ + _cp = isc_buffer_used(_b); \ + (_b)->used += 2; \ + _cp[0] = (unsigned char)(_val2 >> 8); \ + _cp[1] = (unsigned char)_val2; \ } while (0) -#define ISC__BUFFER_PUTUINT24(_b, _val) \ - do { \ - unsigned char *_cp; \ - /* evaluate (_val) only once */ \ - uint32_t _val2 = (_val); \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, 3) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= 3U); \ - _cp = isc_buffer_used(_b); \ - (_b)->used += 3; \ - _cp[0] = (unsigned char)(_val2 >> 16); \ - _cp[1] = (unsigned char)(_val2 >> 8); \ - _cp[2] = (unsigned char)_val2; \ +#define ISC__BUFFER_PUTUINT24(_b, _val) \ + do { \ + unsigned char *_cp; \ + /* evaluate (_val) only once */ \ + uint32_t _val2 = (_val); \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, 3) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= 3U); \ + _cp = isc_buffer_used(_b); \ + (_b)->used += 3; \ + _cp[0] = (unsigned char)(_val2 >> 16); \ + _cp[1] = (unsigned char)(_val2 >> 8); \ + _cp[2] = (unsigned char)_val2; \ } while (0) -#define ISC__BUFFER_PUTUINT32(_b, _val) \ - do { \ - unsigned char *_cp; \ - /* evaluate (_val) only once */ \ - uint32_t _val2 = (_val); \ - if (ISC_UNLIKELY((_b)->autore)) { \ - isc_buffer_t *_tmp = _b; \ - ISC_REQUIRE(isc_buffer_reserve(&_tmp, 4) \ - == ISC_R_SUCCESS); \ - } \ - ISC_REQUIRE(isc_buffer_availablelength(_b) >= 4U); \ - _cp = isc_buffer_used(_b); \ - (_b)->used += 4; \ - _cp[0] = (unsigned char)(_val2 >> 24); \ - _cp[1] = (unsigned char)(_val2 >> 16); \ - _cp[2] = (unsigned char)(_val2 >> 8); \ - _cp[3] = (unsigned char)_val2; \ +#define ISC__BUFFER_PUTUINT32(_b, _val) \ + do { \ + unsigned char *_cp; \ + /* evaluate (_val) only once */ \ + uint32_t _val2 = (_val); \ + if (ISC_UNLIKELY((_b)->autore)) { \ + isc_buffer_t *_tmp = _b; \ + ISC_REQUIRE(isc_buffer_reserve(&_tmp, 4) == \ + ISC_R_SUCCESS); \ + } \ + ISC_REQUIRE(isc_buffer_availablelength(_b) >= 4U); \ + _cp = isc_buffer_used(_b); \ + (_b)->used += 4; \ + _cp[0] = (unsigned char)(_val2 >> 24); \ + _cp[1] = (unsigned char)(_val2 >> 16); \ + _cp[2] = (unsigned char)(_val2 >> 8); \ + _cp[3] = (unsigned char)_val2; \ } while (0) #if defined(ISC_BUFFER_USEINLINE) -#define isc_buffer_init ISC__BUFFER_INIT -#define isc_buffer_initnull ISC__BUFFER_INITNULL -#define isc_buffer_invalidate ISC__BUFFER_INVALIDATE -#define isc_buffer_region ISC__BUFFER_REGION -#define isc_buffer_usedregion ISC__BUFFER_USEDREGION -#define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION -#define isc_buffer_add ISC__BUFFER_ADD -#define isc_buffer_subtract ISC__BUFFER_SUBTRACT -#define isc_buffer_clear ISC__BUFFER_CLEAR -#define isc_buffer_consumedregion ISC__BUFFER_CONSUMEDREGION -#define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION -#define isc_buffer_activeregion ISC__BUFFER_ACTIVEREGION -#define isc_buffer_setactive ISC__BUFFER_SETACTIVE -#define isc_buffer_first ISC__BUFFER_FIRST -#define isc_buffer_forward ISC__BUFFER_FORWARD -#define isc_buffer_back ISC__BUFFER_BACK -#define isc_buffer_putmem ISC__BUFFER_PUTMEM -#define isc_buffer_putstr ISC__BUFFER_PUTSTR -#define isc_buffer_putuint8 ISC__BUFFER_PUTUINT8 -#define isc_buffer_putuint16 ISC__BUFFER_PUTUINT16 -#define isc_buffer_putuint24 ISC__BUFFER_PUTUINT24 -#define isc_buffer_putuint32 ISC__BUFFER_PUTUINT32 -#else -#define isc_buffer_init isc__buffer_init -#define isc_buffer_initnull isc__buffer_initnull -#define isc_buffer_invalidate isc__buffer_invalidate -#define isc_buffer_region isc__buffer_region -#define isc_buffer_usedregion isc__buffer_usedregion -#define isc_buffer_availableregion isc__buffer_availableregion -#define isc_buffer_add isc__buffer_add -#define isc_buffer_subtract isc__buffer_subtract -#define isc_buffer_clear isc__buffer_clear -#define isc_buffer_consumedregion isc__buffer_consumedregion -#define isc_buffer_remainingregion isc__buffer_remainingregion -#define isc_buffer_activeregion isc__buffer_activeregion -#define isc_buffer_setactive isc__buffer_setactive -#define isc_buffer_first isc__buffer_first -#define isc_buffer_forward isc__buffer_forward -#define isc_buffer_back isc__buffer_back -#define isc_buffer_putmem isc__buffer_putmem -#define isc_buffer_putstr isc__buffer_putstr -#define isc_buffer_putuint8 isc__buffer_putuint8 -#define isc_buffer_putuint16 isc__buffer_putuint16 -#define isc_buffer_putuint24 isc__buffer_putuint24 -#define isc_buffer_putuint32 isc__buffer_putuint32 -#endif - -#define isc_buffer_constinit(_b, _d, _l) \ - do { \ - union { void *_var; const void *_const; } _deconst; \ - _deconst._const = (_d); \ +#define isc_buffer_init ISC__BUFFER_INIT +#define isc_buffer_initnull ISC__BUFFER_INITNULL +#define isc_buffer_invalidate ISC__BUFFER_INVALIDATE +#define isc_buffer_region ISC__BUFFER_REGION +#define isc_buffer_usedregion ISC__BUFFER_USEDREGION +#define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION +#define isc_buffer_add ISC__BUFFER_ADD +#define isc_buffer_subtract ISC__BUFFER_SUBTRACT +#define isc_buffer_clear ISC__BUFFER_CLEAR +#define isc_buffer_consumedregion ISC__BUFFER_CONSUMEDREGION +#define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION +#define isc_buffer_activeregion ISC__BUFFER_ACTIVEREGION +#define isc_buffer_setactive ISC__BUFFER_SETACTIVE +#define isc_buffer_first ISC__BUFFER_FIRST +#define isc_buffer_forward ISC__BUFFER_FORWARD +#define isc_buffer_back ISC__BUFFER_BACK +#define isc_buffer_putmem ISC__BUFFER_PUTMEM +#define isc_buffer_putstr ISC__BUFFER_PUTSTR +#define isc_buffer_putuint8 ISC__BUFFER_PUTUINT8 +#define isc_buffer_putuint16 ISC__BUFFER_PUTUINT16 +#define isc_buffer_putuint24 ISC__BUFFER_PUTUINT24 +#define isc_buffer_putuint32 ISC__BUFFER_PUTUINT32 +#else /* if defined(ISC_BUFFER_USEINLINE) */ +#define isc_buffer_init isc__buffer_init +#define isc_buffer_initnull isc__buffer_initnull +#define isc_buffer_invalidate isc__buffer_invalidate +#define isc_buffer_region isc__buffer_region +#define isc_buffer_usedregion isc__buffer_usedregion +#define isc_buffer_availableregion isc__buffer_availableregion +#define isc_buffer_add isc__buffer_add +#define isc_buffer_subtract isc__buffer_subtract +#define isc_buffer_clear isc__buffer_clear +#define isc_buffer_consumedregion isc__buffer_consumedregion +#define isc_buffer_remainingregion isc__buffer_remainingregion +#define isc_buffer_activeregion isc__buffer_activeregion +#define isc_buffer_setactive isc__buffer_setactive +#define isc_buffer_first isc__buffer_first +#define isc_buffer_forward isc__buffer_forward +#define isc_buffer_back isc__buffer_back +#define isc_buffer_putmem isc__buffer_putmem +#define isc_buffer_putstr isc__buffer_putstr +#define isc_buffer_putuint8 isc__buffer_putuint8 +#define isc_buffer_putuint16 isc__buffer_putuint16 +#define isc_buffer_putuint24 isc__buffer_putuint24 +#define isc_buffer_putuint32 isc__buffer_putuint32 +#endif /* if defined(ISC_BUFFER_USEINLINE) */ + +#define isc_buffer_constinit(_b, _d, _l) \ + do { \ + union { \ + void * _var; \ + const void *_const; \ + } _deconst; \ + _deconst._const = (_d); \ isc_buffer_init((_b), _deconst._var, (_l)); \ } while (0) /* * No inline method for this one (yet). */ -#define isc_buffer_putuint48 isc__buffer_putuint48 +#define isc_buffer_putuint48 isc__buffer_putuint48 #endif /* ISC_BUFFER_H */ diff --git a/lib/isc/include/isc/bufferlist.h b/lib/isc/include/isc/bufferlist.h index ffb4986f..8fe6e36a 100644 --- a/lib/isc/include/isc/bufferlist.h +++ b/lib/isc/include/isc/bufferlist.h @@ -3,29 +3,28 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_BUFFERLIST_H #define ISC_BUFFERLIST_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/bufferlist.h * * - *\brief Buffer lists have no synchronization. Clients must ensure exclusive - * access. + *\brief Buffer lists have no synchronization. Clients must ensure + * exclusive * access. * * \li Reliability: * No anticipated impact. - + * * \li Security: * No anticipated impact. * @@ -63,8 +62,8 @@ isc_bufferlist_usedcount(isc_bufferlist_t *bl); unsigned int isc_bufferlist_availablecount(isc_bufferlist_t *bl); /*!< - * \brief Return the length of the sum of all available regions of all buffers in - * the buffer list 'bl' + * \brief Return the length of the sum of all available regions of all buffers + * in the buffer list 'bl' * * Requires: * diff --git a/lib/isc/include/isc/cmocka.h b/lib/isc/include/isc/cmocka.h new file mode 100644 index 00000000..aadfcada --- /dev/null +++ b/lib/isc/include/isc/cmocka.h @@ -0,0 +1,53 @@ +/* + * 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. + */ + +/*! \file isc/cmocka.h */ + +#pragma once + +#include <cmocka.h> + +#include <isc/lang.h> + +ISC_LANG_BEGINDECLS + +/* + * Copy the test identified by 'name' from 'tests' to 'selected'. + */ +#define cmocka_add_test_byname(tests, name, selected) \ + _cmocka_add_test_byname(tests, sizeof(tests) / sizeof(tests[0]), name, \ + selected, \ + sizeof(selected) / sizeof(selected[0])) + +static inline bool +_cmocka_add_test_byname(const struct CMUnitTest *tests, size_t ntests, + const char *name, struct CMUnitTest *selected, + size_t nselected) { + size_t i, j; + + for (i = 0; i < ntests && tests[i].name != NULL; i++) { + if (strcmp(tests[i].name, name) != 0) { + continue; + } + for (j = 0; j < nselected && selected[j].name != NULL; j++) { + if (strcmp(tests[j].name, name) == 0) { + break; + } + } + if (j < nselected && selected[j].name == NULL) { + selected[j] = tests[i]; + } + return (true); + } + return (false); +} + +ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/commandline.h b/lib/isc/include/isc/commandline.h index a1a256ed..d9790c25 100644 --- a/lib/isc/include/isc/commandline.h +++ b/lib/isc/include/isc/commandline.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_COMMANDLINE_H #define ISC_COMMANDLINE_H 1 @@ -37,7 +36,7 @@ LIBISC_EXTERNAL_DATA extern bool isc_commandline_reset; ISC_LANG_BEGINDECLS int -isc_commandline_parse(int argc, char * const *argv, const char *options); +isc_commandline_parse(int argc, char *const *argv, const char *options); /*%< * Parse a command line (similar to getopt()) */ diff --git a/lib/isc/include/isc/counter.h b/lib/isc/include/isc/counter.h index 28d9c794..2e54d341 100644 --- a/lib/isc/include/isc/counter.h +++ b/lib/isc/include/isc/counter.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,8 +13,8 @@ #define ISC_COUNTER_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/counter.h * @@ -34,8 +34,8 @@ #include <isc/types.h> /***** - ***** Types. - *****/ +***** Types. +*****/ ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/crc64.h b/lib/isc/include/isc/crc64.h index ed5860b7..3e35f71f 100644 --- a/lib/isc/include/isc/crc64.h +++ b/lib/isc/include/isc/crc64.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/isc/deprecated.h b/lib/isc/include/isc/deprecated.h index d485e20c..8664968e 100644 --- a/lib/isc/include/isc/deprecated.h +++ b/lib/isc/include/isc/deprecated.h @@ -3,20 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_DEPRECATED_H #define ISC_DEPRECATED_H #if (__GNUC__ + 0) > 3 -#define ISC_DEPRECATED __attribute__((deprecated)) -#else -#define ISC_DEPRECATED /* none */ -#endif /* __GNUC__ > 3*/ +#define ISC_DEPRECATED __attribute__((deprecated)) +#else /* if (__GNUC__ + 0) > 3 */ +#define ISC_DEPRECATED /* none */ +#endif /* __GNUC__ > 3*/ -#endif +#endif /* ifndef ISC_DEPRECATED_H */ diff --git a/lib/isc/include/isc/endian.h b/lib/isc/include/isc/endian.h new file mode 100644 index 00000000..dc770f67 --- /dev/null +++ b/lib/isc/include/isc/endian.h @@ -0,0 +1,188 @@ +/* + * 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 + +#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__bsdi__) + +#include <sys/endian.h> + +/* + * Recent BSDs should have [bl]e{16,32,64}toh() defined in <sys/endian.h>. + * Older ones might not, but these should have the alternatively named + * [bl]etoh{16,32,64}() functions defined. + */ +#ifndef be16toh +#define be16toh(x) betoh16(x) +#define le16toh(x) letoh16(x) +#define be32toh(x) betoh32(x) +#define le32toh(x) letoh32(x) +#define be64toh(x) betoh64(x) +#define le64toh(x) letoh64(x) +#endif /* !be16toh */ + +#elif defined(_WIN32) + +/* + * Windows is always little-endian and has its own byte-swapping routines, so + * use these. + */ + +#include <stdlib.h> + +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) + +#elif defined __APPLE__ + +/* + * macOS has its own byte-swapping routines, so use these. + */ + +#include <libkern/OSByteOrder.h> + +#define htobe16(x) OSSwapHostToBigInt16(x) +#define htole16(x) OSSwapHostToLittleInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) + +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) + +#define htobe64(x) OSSwapHostToBigInt64(x) +#define htole64(x) OSSwapHostToLittleInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) + +#elif defined(sun) || defined(__sun) || defined(__SVR4) + +/* + * For Solaris, rely on the fallback definitions below, though use + * Solaris-specific versions of bswap_{16,32,64}(). + */ + +#include <sys/byteorder.h> + +#define bswap_16(x) BSWAP_16(x) +#define bswap_32(x) BSWAP_32(x) +#define bswap_64(x) BSWAP_64(x) + +#elif defined(__ANDROID__) || defined(__CYGWIN__) || defined(__GNUC__) || \ + defined(__GNU__) + +#include <byteswap.h> +#include <endian.h> + +#else /* if defined(__DragonFly__) || defined(__FreeBSD__) || \ + * defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) */ + +#endif /* Specific platform support */ + +/* + * Fallback definitions. + */ + +#include <inttypes.h> + +#ifndef bswap_16 +#define bswap_16(x) \ + ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | \ + (((uint16_t)(x)&0x00ff) << 8))) +#endif /* !bswap_16 */ + +#ifndef bswap_32 +#define bswap_32(x) \ + ((uint32_t)((((uint32_t)(x)&0xff000000) >> 24) | \ + (((uint32_t)(x)&0x00ff0000) >> 8) | \ + (((uint32_t)(x)&0x0000ff00) << 8) | \ + (((uint32_t)(x)&0x000000ff) << 24))) +#endif /* !bswap_32 */ + +#ifndef bswap_64 +#define bswap_64(x) \ + ((uint64_t)((((uint64_t)(x)&0xff00000000000000ULL) >> 56) | \ + (((uint64_t)(x)&0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x)&0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x)&0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x)&0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x)&0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x)&0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x)&0x00000000000000ffULL) << 56))) +#endif /* !bswap_64 */ + +#ifndef htobe16 +#if WORDS_BIGENDIAN + +#define htobe16(x) (x) +#define htole16(x) bswap_16(x) +#define be16toh(x) (x) +#define le16toh(x) bswap_16(x) + +#else /* WORDS_BIGENDIAN */ + +#define htobe16(x) bswap_16(x) +#define htole16(x) (x) +#define be16toh(x) bswap_16(x) +#define le16toh(x) (x) + +#endif /* WORDS_BIGENDIAN */ +#endif /* !htobe16 */ + +#ifndef htobe32 +#if WORDS_BIGENDIAN + +#define htobe32(x) (x) +#define htole32(x) bswap_32(x) +#define be32toh(x) (x) +#define le32toh(x) bswap_32(x) + +#else /* WORDS_BIGENDIAN */ + +#define htobe32(x) bswap_32(x) +#define htole32(x) (x) +#define be32toh(x) bswap_32(x) +#define le32toh(x) (x) + +#endif /* WORDS_BIGENDIAN */ +#endif /* !htobe32 */ + +#ifndef htobe64 +#if WORDS_BIGENDIAN + +#define htobe64(x) (x) +#define htole64(x) bswap_64(x) +#define be64toh(x) (x) +#define le64toh(x) bswap_64(x) + +#else /* WORDS_BIGENDIAN */ + +#define htobe64(x) bswap_64(x) +#define htole64(x) (x) +#define be64toh(x) bswap_64(x) +#define le64toh(x) (x) + +#endif /* WORDS_BIGENDIAN */ +#endif /* !htobe64 */ diff --git a/lib/isc/include/isc/errno.h b/lib/isc/include/isc/errno.h index 7777b8d3..d0584561 100644 --- a/lib/isc/include/isc/errno.h +++ b/lib/isc/include/isc/errno.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/isc/error.h b/lib/isc/include/isc/error.h index 87bb6bae..a888e61a 100644 --- a/lib/isc/include/isc/error.h +++ b/lib/isc/include/isc/error.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_ERROR_H #define ISC_ERROR_H 1 @@ -27,30 +26,29 @@ ISC_LANG_BEGINDECLS typedef void (*isc_errorcallback_t)(const char *, int, const char *, va_list); /*% set unexpected error */ -void -isc_error_setunexpected(isc_errorcallback_t); +void isc_error_setunexpected(isc_errorcallback_t); /*% set fatal error */ -void -isc_error_setfatal(isc_errorcallback_t); +void isc_error_setfatal(isc_errorcallback_t); /*% unexpected error */ void isc_error_unexpected(const char *, int, const char *, ...) - ISC_FORMAT_PRINTF(3, 4); + ISC_FORMAT_PRINTF(3, 4); /*% fatal error */ ISC_PLATFORM_NORETURN_PRE void isc_error_fatal(const char *, int, const char *, ...) -ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST; + ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST; /*% runtimecheck error */ ISC_PLATFORM_NORETURN_PRE void -isc_error_runtimecheck(const char *, int, const char *) ISC_PLATFORM_NORETURN_POST; +isc_error_runtimecheck(const char *, int, + const char *) ISC_PLATFORM_NORETURN_POST; #define ISC_ERROR_RUNTIMECHECK(cond) \ - ((void) (ISC_LIKELY(cond) || \ - ((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0))) + ((void)(ISC_LIKELY(cond) || \ + ((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0))) ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/event.h b/lib/isc/include/isc/event.h index 99d867cd..a28afbba 100644 --- a/lib/isc/include/isc/event.h +++ b/lib/isc/include/isc/event.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_EVENT_H #define ISC_EVENT_H 1 @@ -19,30 +18,30 @@ #include <isc/types.h> /***** - ***** Events. - *****/ +***** Events. +*****/ typedef void (*isc_eventdestructor_t)(isc_event_t *); -#define ISC_EVENT_COMMON(ltype) \ - size_t ev_size; \ - unsigned int ev_attributes; \ - void * ev_tag; \ - isc_eventtype_t ev_type; \ - isc_taskaction_t ev_action; \ - void * ev_arg; \ - void * ev_sender; \ - isc_eventdestructor_t ev_destroy; \ - void * ev_destroy_arg; \ - ISC_LINK(ltype) ev_link; \ - ISC_LINK(ltype) ev_ratelink +#define ISC_EVENT_COMMON(ltype) \ + size_t ev_size; \ + unsigned int ev_attributes; \ + void * ev_tag; \ + isc_eventtype_t ev_type; \ + isc_taskaction_t ev_action; \ + void * ev_arg; \ + void * ev_sender; \ + isc_eventdestructor_t ev_destroy; \ + void * ev_destroy_arg; \ + ISC_LINK(ltype) ev_link; \ + ISC_LINK(ltype) ev_ratelink /*% * Attributes matching a mask of 0x000000ff are reserved for the task library's * definition. Attributes of 0xffffff00 may be used by the application * or non-ISC libraries. */ -#define ISC_EVENTATTR_NOPURGE 0x00000001 +#define ISC_EVENTATTR_NOPURGE 0x00000001 /*% * The ISC_EVENTATTR_CANCELED attribute is intended to indicate @@ -51,22 +50,22 @@ typedef void (*isc_eventdestructor_t)(isc_event_t *); * between the sender and receiver. It is not set or used by * the task system. */ -#define ISC_EVENTATTR_CANCELED 0x00000002 +#define ISC_EVENTATTR_CANCELED 0x00000002 #define ISC_EVENT_INIT(event, sz, at, ta, ty, ac, ar, sn, df, da) \ -do { \ - (event)->ev_size = (sz); \ - (event)->ev_attributes = (at); \ - (event)->ev_tag = (ta); \ - (event)->ev_type = (ty); \ - (event)->ev_action = (ac); \ - (event)->ev_arg = (ar); \ - (event)->ev_sender = (sn); \ - (event)->ev_destroy = (df); \ - (event)->ev_destroy_arg = (da); \ - ISC_LINK_INIT((event), ev_link); \ - ISC_LINK_INIT((event), ev_ratelink); \ -} while (0) + do { \ + (event)->ev_size = (sz); \ + (event)->ev_attributes = (at); \ + (event)->ev_tag = (ta); \ + (event)->ev_type = (ty); \ + (event)->ev_action = (ac); \ + (event)->ev_arg = (ar); \ + (event)->ev_sender = (sn); \ + (event)->ev_destroy = (df); \ + (event)->ev_destroy_arg = (da); \ + ISC_LINK_INIT((event), ev_link); \ + ISC_LINK_INIT((event), ev_ratelink); \ + } while (0) /*% * This structure is public because "subclassing" it may be useful when @@ -76,8 +75,8 @@ struct isc_event { ISC_EVENT_COMMON(struct isc_event); }; -#define ISC_EVENTTYPE_FIRSTEVENT 0x00000000 -#define ISC_EVENTTYPE_LASTEVENT 0xffffffff +#define ISC_EVENTTYPE_FIRSTEVENT 0x00000000 +#define ISC_EVENTTYPE_LASTEVENT 0xffffffff #define ISC_EVENT_PTR(p) ((isc_event_t **)(void *)(p)) diff --git a/lib/isc/include/isc/eventclass.h b/lib/isc/include/isc/eventclass.h index 905181e0..694136cb 100644 --- a/lib/isc/include/isc/eventclass.h +++ b/lib/isc/include/isc/eventclass.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_EVENTCLASS_H #define ISC_EVENTCLASS_H 1 @@ -24,7 +23,7 @@ * */ -#define ISC_EVENTCLASS(eclass) ((eclass) << 16) +#define ISC_EVENTCLASS(eclass) ((eclass) << 16) /*@{*/ /*! @@ -32,16 +31,16 @@ * Event classes >= 1024 and <= 65535 are reserved for application use. */ -#define ISC_EVENTCLASS_TASK ISC_EVENTCLASS(0) -#define ISC_EVENTCLASS_TIMER ISC_EVENTCLASS(1) -#define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2) -#define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3) -#define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4) -#define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5) -#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6) -#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7) -#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8) -#define ISC_EVENTCLASS_NS ISC_EVENTCLASS(9) +#define ISC_EVENTCLASS_TASK ISC_EVENTCLASS(0) +#define ISC_EVENTCLASS_TIMER ISC_EVENTCLASS(1) +#define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2) +#define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3) +#define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4) +#define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5) +#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6) +#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7) +#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8) +#define ISC_EVENTCLASS_NS ISC_EVENTCLASS(9) /*@}*/ #endif /* ISC_EVENTCLASS_H */ diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h index 0797f027..88d9af4d 100644 --- a/lib/isc/include/isc/file.h +++ b/lib/isc/include/isc/file.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_FILE_H #define ISC_FILE_H 1 @@ -66,7 +65,8 @@ isc_file_getmodtime(const char *file, isc_time_t *time); isc_result_t isc_file_mktemplate(const char *path, char *buf, size_t buflen); /*!< - * \brief Generate a template string suitable for use with isc_file_openunique(). + * \brief Generate a template string suitable for use with + * isc_file_openunique(). * * Notes: *\li This function is intended to make creating temporary files @@ -179,9 +179,9 @@ isc_file_rename(const char *oldname, const char *newname); bool isc_file_exists(const char *pathname); /*!< - * \brief Return #true if the calling process can tell that the given file exists. - * Will not return true if the calling process has insufficient privileges - * to search the entire path. + * \brief Return #true if the calling process can tell that the given file + * exists. Will not return true if the calling process has insufficient + * privileges to search the entire path. */ bool @@ -308,8 +308,8 @@ isc_file_safecreate(const char *filename, FILE **fp); */ isc_result_t -isc_file_splitpath(isc_mem_t *mctx, const char *path, - char **dirname, char const **basename); +isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, + char const **basename); /*%< * Split a path into dirname and basename. If 'path' contains no slash * (or, on windows, backslash), then '*dirname' is set to ".". @@ -343,8 +343,8 @@ isc_file_getsizefd(int fd, off_t *size); */ void * -isc_file_mmap(void *addr, size_t len, int prot, - int flags, int fd, off_t offset); +isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, + off_t offset); /*%< * Portable front-end to mmap(). If mmap() is not defined on this * platform, then we simulate it by calling malloc() and read(). diff --git a/lib/isc/include/isc/formatcheck.h b/lib/isc/include/isc/formatcheck.h index 162c16e3..f1313d72 100644 --- a/lib/isc/include/isc/formatcheck.h +++ b/lib/isc/include/isc/formatcheck.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_FORMATCHECK_H #define ISC_FORMATCHECK_H 1 @@ -19,15 +18,17 @@ * ISC_FORMAT_PRINTF(). * * \li fmt is the location of the format string parameter. - * \li args is the location of the first argument (or 0 for no argument checking). + * \li args is the location of the first argument (or 0 for no argument + * checking). * * Note: * \li The first parameter is 1, not 0. */ #ifdef __GNUC__ -#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args))) -#else +#define ISC_FORMAT_PRINTF(fmt, args) \ + __attribute__((__format__(__printf__, fmt, args))) +#else /* ifdef __GNUC__ */ #define ISC_FORMAT_PRINTF(fmt, args) -#endif +#endif /* ifdef __GNUC__ */ #endif /* ISC_FORMATCHECK_H */ diff --git a/lib/isc/include/isc/fsaccess.h b/lib/isc/include/isc/fsaccess.h index d842aaf1..3250799f 100644 --- a/lib/isc/include/isc/fsaccess.h +++ b/lib/isc/include/isc/fsaccess.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_FSACCESS_H #define ISC_FSACCESS_H 1 @@ -94,7 +93,7 @@ * probable that something could be cobbled together in NT 5 with inheritance, * it can't really be done in NT 4 as a single property that you could * set on a directory. You'd need to coordinate something with file creation - * so that every file created had DELETE set for the owner but noone else. + * so that every file created had DELETE set for the owner but no one else. * * On Unix systems, setting #ISC_FSACCESS_LISTDIRECTORY sets READ. * ... setting either #ISC_FSACCESS_CREATECHILD or #ISC_FSACCESS_DELETECHILD @@ -131,21 +130,21 @@ /* * Trustees. */ -#define ISC_FSACCESS_OWNER 0x1 /*%< User account. */ -#define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */ -#define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */ -#define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */ +#define ISC_FSACCESS_OWNER 0x1 /*%< User account. */ +#define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */ +#define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */ +#define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */ /* * Types of permission. */ -#define ISC_FSACCESS_READ 0x00000001 /*%< File only. */ -#define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */ -#define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */ -#define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */ -#define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */ -#define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */ -#define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */ +#define ISC_FSACCESS_READ 0x00000001 /*%< File only. */ +#define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */ +#define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */ +#define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */ +#define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */ +#define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */ +#define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */ /*% * Adding any permission bits beyond 0x200 would mean typedef'ing diff --git a/lib/isc/include/isc/fuzz.h b/lib/isc/include/isc/fuzz.h index 48dabe94..a16845c6 100644 --- a/lib/isc/include/isc/fuzz.h +++ b/lib/isc/include/isc/fuzz.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h index 5b4336e6..fcdbb3cc 100644 --- a/lib/isc/include/isc/hash.h +++ b/lib/isc/include/isc/hash.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -29,14 +29,12 @@ isc_hash_get_initializer(void); void isc_hash_set_initializer(const void *initializer); +#define isc_hash_function isc_hash64 + uint32_t -isc_hash_function(const void *data, size_t length, - bool case_sensitive, - const uint32_t *previous_hashp); -uint32_t -isc_hash_function_reverse(const void *data, size_t length, - bool case_sensitive, - const uint32_t *previous_hashp); +isc_hash32(const void *data, const size_t length, const bool case_sensitive); +uint64_t +isc_hash64(const void *data, const size_t length, const bool case_sensitive); /*!< * \brief Calculate a hash over data. * @@ -46,11 +44,8 @@ isc_hash_function_reverse(const void *data, size_t length, * process using this library is run, but will have uniform * distribution. * - * isc_hash_function() calculates the hash from start to end over the - * input data. isc_hash_function_reverse() calculates the hash from the - * end to the start over the input data. The difference in order is - * useful in incremental hashing; for example, a previously hashed - * value for 'com' can be used as input when hashing 'example.com'. + * isc_hash_32/64() calculates the hash from start to end over the + * input data. * * 'data' is the data to be hashed. * @@ -60,9 +55,8 @@ isc_hash_function_reverse(const void *data, size_t length, * case_sensitive values. It should typically be false if the hash key * is a DNS name. * - * 'previous_hashp' is a pointer to a previous hash value returned by - * this function. It can be used to perform incremental hashing. NULL - * must be passed during first calls. + * Returns: + * \li 32 or 64-bit hash value */ ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h index 747287b3..b9a5e261 100644 --- a/lib/isc/include/isc/heap.h +++ b/lib/isc/include/isc/heap.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_HEAP_H #define ISC_HEAP_H 1 diff --git a/lib/isc/include/isc/hex.h b/lib/isc/include/isc/hex.h index b021e051..9db99315 100644 --- a/lib/isc/include/isc/hex.h +++ b/lib/isc/include/isc/hex.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_HEX_H #define ISC_HEX_H 1 @@ -25,8 +24,8 @@ ISC_LANG_BEGINDECLS ***/ isc_result_t -isc_hex_totext(isc_region_t *source, int wordlength, - const char *wordbreak, isc_buffer_t *target); +isc_hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, + isc_buffer_t *target); /*!< * \brief Convert data into hex encoded text. * diff --git a/lib/isc/include/isc/hmac.h b/lib/isc/include/isc/hmac.h index aca85b49..f41b07d6 100644 --- a/lib/isc/include/isc/hmac.h +++ b/lib/isc/include/isc/hmac.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -19,12 +19,10 @@ #include <isc/lang.h> #include <isc/md.h> #include <isc/platform.h> -#include <isc/types.h> #include <isc/result.h> +#include <isc/types.h> -#include <openssl/hmac.h> - -typedef HMAC_CTX isc_hmac_t; +typedef void isc_hmac_t; /** * isc_hmac: @@ -44,9 +42,9 @@ typedef HMAC_CTX isc_hmac_t; * (i.e. the length of the digest) will be written to the @digestlen. */ isc_result_t -isc_hmac(isc_md_type_t type, const void *key, const int keylen, - const unsigned char *buf, const size_t len, - unsigned char *digest, unsigned int *digestlen); +isc_hmac(const isc_md_type_t *type, const void *key, const int keylen, + const unsigned char *buf, const size_t len, unsigned char *digest, + unsigned int *digestlen); /** * isc_hmac_new: @@ -77,8 +75,8 @@ isc_hmac_free(isc_hmac_t *hmac); */ isc_result_t -isc_hmac_init(isc_hmac_t *hmac, const void *key, - size_t keylen, isc_md_type_t type); +isc_hmac_init(isc_hmac_t *hmac, const void *key, size_t keylen, + const isc_md_type_t *type); /** * isc_hmac_reset: @@ -106,7 +104,7 @@ isc_hmac_update(isc_hmac_t *hmac, const unsigned char *buf, const size_t len); * isc_hmac_final: * @hmac: HMAC context * @digest: the output buffer - * @digestlen: the lenth of the data written to @digest + * @digestlen: the length of the data written to @digest * * This function retrieves the message authentication code from @hmac and places * it in @digest, which must have space for the hash function output. If the @@ -125,7 +123,7 @@ isc_hmac_final(isc_hmac_t *hmac, unsigned char *digest, * This function return the isc_md_type_t previously set for the supplied * HMAC context or NULL if no isc_md_type_t has been set. */ -isc_md_type_t +const isc_md_type_t * isc_hmac_get_md_type(isc_hmac_t *hmac); /** diff --git a/lib/isc/include/isc/hp.h b/lib/isc/include/isc/hp.h new file mode 100644 index 00000000..44155e62 --- /dev/null +++ b/lib/isc/include/isc/hp.h @@ -0,0 +1,138 @@ +/* + * 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. + */ + +/* + * Hazard Pointer implementation. + * + * This work is based on C++ code available from: + * https://github.com/pramalhe/ConcurrencyFreaks/ + * + * Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Concurrency Freaks nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <isc/atomic.h> +#include <isc/mem.h> +#include <isc/string.h> +#include <isc/types.h> +#include <isc/util.h> + +/*% + * Hazard pointers are a mechanism for protecting objects in memory + * from being deleted by other threads while in use. This allows + * safe lock-free data structures. + * + * This is an adaptation of the ConcurrencyFreaks implementation in C. + * More details available at https://github.com/pramalhe/ConcurrencyFreaks, + * in the file HazardPointers.hpp. + */ + +typedef void(isc_hp_deletefunc_t)(void *); + +void +isc_hp_init(int max_threads); +/*%< + * Initialize hazard pointer constants - isc__hp_max_threads. If more threads + * will try to access hp it will assert. + */ + +isc_hp_t * +isc_hp_new(isc_mem_t *mctx, size_t max_hps, isc_hp_deletefunc_t *deletefunc); +/*%< + * Create a new hazard pointer array of size 'max_hps' (or a reasonable + * default value if 'max_hps' is 0). The function 'deletefunc' will be + * used to delete objects protected by hazard pointers when it becomes + * safe to retire them. + */ + +void +isc_hp_destroy(isc_hp_t *hp); +/*%< + * Destroy a hazard pointer array and clean up all objects protected + * by hazard pointers. + */ + +void +isc_hp_clear(isc_hp_t *hp); +/*%< + * Clear all hazard pointers in the array for the current thread. + * + * Progress condition: wait-free bounded (by max_hps) + */ + +void +isc_hp_clear_one(isc_hp_t *hp, int ihp); +/*%< + * Clear a specified hazard pointer in the array for the current thread. + * + * Progress condition: wait-free population oblivious. + */ + +uintptr_t +isc_hp_protect(isc_hp_t *hp, int ihp, atomic_uintptr_t *atom); +/*%< + * Protect an object referenced by 'atom' with a hazard pointer for the + * current thread. + * + * Progress condition: lock-free. + */ + +uintptr_t +isc_hp_protect_ptr(isc_hp_t *hp, int ihp, atomic_uintptr_t ptr); +/*%< + * This returns the same value that is passed as ptr, which is sometimes + * useful. + * + * Progress condition: wait-free population oblivious. + */ + +uintptr_t +isc_hp_protect_release(isc_hp_t *hp, int ihp, atomic_uintptr_t ptr); +/*%< + * Same as isc_hp_protect_ptr(), but explicitly uses memory_order_release. + * + * Progress condition: wait-free population oblivious. + */ + +void +isc_hp_retire(isc_hp_t *hp, uintptr_t ptr); +/*%< + * Retire an object that is no longer in use by any thread, calling + * the delete function that was specified in isc_hp_new(). + * + * Progress condition: wait-free bounded (by the number of threads squared) + */ diff --git a/lib/isc/include/isc/ht.h b/lib/isc/include/isc/ht.h index 3a44e150..9d5ab82e 100644 --- a/lib/isc/include/isc/ht.h +++ b/lib/isc/include/isc/ht.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -17,10 +17,10 @@ #include <inttypes.h> #include <string.h> -#include <isc/types.h> #include <isc/result.h> +#include <isc/types.h> -typedef struct isc_ht isc_ht_t; +typedef struct isc_ht isc_ht_t; typedef struct isc_ht_iter isc_ht_iter_t; /*% @@ -61,7 +61,7 @@ isc_ht_destroy(isc_ht_t **htp); */ isc_result_t isc_ht_add(isc_ht_t *ht, const unsigned char *key, uint32_t keysize, - void *value); + void *value); /*% * Find a node matching 'key'/'keysize' in hashtable 'ht'; @@ -77,8 +77,8 @@ isc_ht_add(isc_ht_t *ht, const unsigned char *key, uint32_t keysize, * \li #ISC_R_NOTFOUND -- key not found */ isc_result_t -isc_ht_find(const isc_ht_t *ht, const unsigned char *key, - uint32_t keysize, void **valuep); +isc_ht_find(const isc_ht_t *ht, const unsigned char *key, uint32_t keysize, + void **valuep); /*% * Delete node from hashtable @@ -151,7 +151,6 @@ isc_ht_iter_next(isc_ht_iter_t *it); isc_result_t isc_ht_iter_delcurrent_next(isc_ht_iter_t *it); - /*% * Set 'value' to the current value under the iterator * @@ -182,4 +181,4 @@ isc_ht_iter_currentkey(isc_ht_iter_t *it, unsigned char **key, size_t *keysize); */ unsigned int isc_ht_count(isc_ht_t *ht); -#endif +#endif /* ifndef ISC_HT_H */ diff --git a/lib/isc/include/isc/httpd.h b/lib/isc/include/isc/httpd.h index b02b33e8..85376f84 100644 --- a/lib/isc/include/isc/httpd.h +++ b/lib/isc/include/isc/httpd.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_HTTPD_H #define ISC_HTTPD_H 1 @@ -19,10 +18,10 @@ #include <isc/event.h> #include <isc/eventclass.h> -#include <isc/types.h> #include <isc/mutex.h> #include <isc/task.h> #include <isc/time.h> +#include <isc/types.h> /*% * HTTP urls. These are the URLs we manage, and the function to call to @@ -32,18 +31,18 @@ * the data cleanup function. */ struct isc_httpdurl { - char *url; - isc_httpdaction_t *action; - void *action_arg; - bool isstatic; - isc_time_t loadtime; - ISC_LINK(isc_httpdurl_t) link; + char * url; + isc_httpdaction_t *action; + void * action_arg; + bool isstatic; + isc_time_t loadtime; + ISC_LINK(isc_httpdurl_t) link; }; -#define HTTPD_EVENTCLASS ISC_EVENTCLASS(4300) -#define HTTPD_SHUTDOWN (HTTPD_EVENTCLASS + 0x0001) +#define HTTPD_EVENTCLASS ISC_EVENTCLASS(4300) +#define HTTPD_SHUTDOWN (HTTPD_EVENTCLASS + 0x0001) -#define ISC_HTTPDMGR_FLAGSHUTTINGDOWN 0x00000001 +#define ISC_HTTPDMGR_FLAGSHUTTINGDOWN 0x00000001 /* * Create a new http daemon which will send, once every time period, @@ -51,7 +50,7 @@ struct isc_httpdurl { */ isc_result_t isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, - isc_httpdclientok_t *client_ok, + isc_httpdclientok_t * client_ok, isc_httpdondestroy_t *ondestory, void *cb_arg, isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp); @@ -63,21 +62,20 @@ isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url, isc_httpdaction_t *func, void *arg); isc_result_t -isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, - bool isstatic, +isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, bool isstatic, isc_httpdaction_t *func, void *arg); isc_result_t isc_httpd_response(isc_httpd_t *httpd); isc_result_t -isc_httpd_addheader(isc_httpd_t *httpd, const char *name, - const char *val); +isc_httpd_addheader(isc_httpd_t *httpd, const char *name, const char *val); isc_result_t isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val); -isc_result_t isc_httpd_endheaders(isc_httpd_t *httpd); +isc_result_t +isc_httpd_endheaders(isc_httpd_t *httpd); void isc_httpd_setfinishhook(void (*fn)(void)); diff --git a/lib/isc/include/isc/interfaceiter.h b/lib/isc/include/isc/interfaceiter.h index 2ef82a3f..b7e59cb2 100644 --- a/lib/isc/include/isc/interfaceiter.h +++ b/lib/isc/include/isc/interfaceiter.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_INTERFACEITER_H #define ISC_INTERFACEITER_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/interfaceiter.h * \brief Iterates over the list of network interfaces. @@ -44,20 +43,22 @@ */ struct isc_interface { - char name[32]; /*%< Interface name, null-terminated. */ - unsigned int af; /*%< Address family. */ - isc_netaddr_t address; /*%< Local address. */ - isc_netaddr_t netmask; /*%< Network mask. */ - isc_netaddr_t dstaddress; /*%< Destination address (point-to-point only). */ - uint32_t flags; /*%< Flags; see INTERFACE flags. */ + char name[32]; /*%< Interface name, null-terminated. */ + unsigned int af; /*%< Address family. */ + isc_netaddr_t address; /*%< Local address. */ + isc_netaddr_t netmask; /*%< Network mask. */ + isc_netaddr_t dstaddress; /*%< Destination address + * (point-to-point + * only). */ + uint32_t flags; /*%< Flags; see INTERFACE flags. */ }; /*@{*/ /*! Interface flags. */ -#define INTERFACE_F_UP 0x00000001U -#define INTERFACE_F_POINTTOPOINT 0x00000002U -#define INTERFACE_F_LOOPBACK 0x00000004U +#define INTERFACE_F_UP 0x00000001U +#define INTERFACE_F_POINTTOPOINT 0x00000002U +#define INTERFACE_F_LOOPBACK 0x00000004U /*@}*/ /*** @@ -89,8 +90,7 @@ isc_interfaceiter_first(isc_interfaceiter_t *iter); */ isc_result_t -isc_interfaceiter_current(isc_interfaceiter_t *iter, - isc_interface_t *ifdata); +isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata); /*!< * \brief Get information about the interface the iterator is currently * positioned at and store it at *ifdata. diff --git a/lib/isc/include/isc/iterated_hash.h b/lib/isc/include/isc/iterated_hash.h index 0848b803..7f6fa88b 100644 --- a/lib/isc/include/isc/iterated_hash.h +++ b/lib/isc/include/isc/iterated_hash.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -28,9 +28,9 @@ ISC_LANG_BEGINDECLS int -isc_iterated_hash(unsigned char *out, - const unsigned int hashalg, const int iterations, - const unsigned char *salt, const int saltlength, - const unsigned char *in, const int inlength); +isc_iterated_hash(unsigned char *out, const unsigned int hashalg, + const int iterations, const unsigned char *salt, + const int saltlength, const unsigned char *in, + const int inlength); ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/json.h b/lib/isc/include/isc/json.h deleted file mode 100644 index 52295e61..00000000 --- a/lib/isc/include/isc/json.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef ISC_JSON_H -#define ISC_JSON_H 1 - -#ifdef HAVE_JSON -/* - * This file is here mostly to make it easy to add additional libjson header - * files as needed across all the users of this file. Rather than place - * these libjson includes in each file, one include makes it easy to handle - * the ifdef as well as adding the ability to add additional functions - * which may be useful. - */ -#ifdef HAVE_JSON_C -/* - * We don't include <json-c/json.h> as the subsequent includes do not - * prefix the header file names with "json-c/" and using - * -I <prefix>/include/json-c results in too many filename collisions. - */ -#include <json-c/linkhash.h> -#include <json-c/json_util.h> -#include <json-c/json_object.h> -#include <json-c/json_tokener.h> -#include <json-c/json_object_iterator.h> -#include <json-c/json_c_version.h> -#else -#include <json/json.h> -#endif -#endif - -#define ISC_JSON_RENDERCONFIG 0x00000001 /* render config data */ -#define ISC_JSON_RENDERSTATS 0x00000002 /* render stats */ -#define ISC_JSON_RENDERALL 0x000000ff /* render everything */ - -#endif /* ISC_JSON_H */ diff --git a/lib/isc/include/isc/lang.h b/lib/isc/include/isc/lang.h index bffcbac0..2e0a6c73 100644 --- a/lib/isc/include/isc/lang.h +++ b/lib/isc/include/isc/lang.h @@ -3,24 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LANG_H #define ISC_LANG_H 1 /*! \file isc/lang.h */ #ifdef __cplusplus -#define ISC_LANG_BEGINDECLS extern "C" { -#define ISC_LANG_ENDDECLS } -#else +#define ISC_LANG_BEGINDECLS extern "C" { +#define ISC_LANG_ENDDECLS } +#else /* ifdef __cplusplus */ #define ISC_LANG_BEGINDECLS #define ISC_LANG_ENDDECLS -#endif +#endif /* ifdef __cplusplus */ #endif /* ISC_LANG_H */ diff --git a/lib/isc/include/isc/lex.h b/lib/isc/include/isc/lex.h index d1e36c0a..fdbe10b9 100644 --- a/lib/isc/include/isc/lex.h +++ b/lib/isc/include/isc/lex.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LEX_H #define ISC_LEX_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/lex.h * \brief The "lex" module provides a lightweight tokenizer. It can operate @@ -62,11 +61,11 @@ ISC_LANG_BEGINDECLS * Various options for isc_lex_gettoken(). */ -#define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */ -#define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */ -#define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */ -#define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */ -#define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */ +#define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */ +#define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */ +#define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */ +#define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */ +#define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */ /*@}*/ /*@{*/ @@ -77,14 +76,14 @@ ISC_LANG_BEGINDECLS * the paren count is > 0. To use this option, '(' and ')' must be special * characters. */ -#define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */ -#define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */ - -#define ISC_LEXOPT_CNUMBER 0x80 /*%< Recognize octal and hex. */ -#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */ -#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */ -#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */ -#define ISC_LEXOPT_BTEXT 0x800 /*%< Bracketed text. */ +#define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */ +#define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */ + +#define ISC_LEXOPT_CNUMBER 0x80 /*%< Recognize octal and hex. */ +#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */ +#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */ +#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */ +#define ISC_LEXOPT_BTEXT 0x800 /*%< Bracketed text. */ /*@}*/ /*@{*/ /*! @@ -92,10 +91,10 @@ ISC_LANG_BEGINDECLS * isc_lex_setcomments(). */ -#define ISC_LEXCOMMENT_C 0x01 -#define ISC_LEXCOMMENT_CPLUSPLUS 0x02 -#define ISC_LEXCOMMENT_SHELL 0x04 -#define ISC_LEXCOMMENT_DNSMASTERFILE 0x08 +#define ISC_LEXCOMMENT_C 0x01 +#define ISC_LEXCOMMENT_CPLUSPLUS 0x02 +#define ISC_LEXCOMMENT_SHELL 0x04 +#define ISC_LEXCOMMENT_DNSMASTERFILE 0x08 /*@}*/ /*** @@ -122,16 +121,16 @@ typedef enum { } isc_tokentype_t; typedef union { - char as_char; - unsigned long as_ulong; - isc_region_t as_region; - isc_textregion_t as_textregion; - void * as_pointer; + char as_char; + unsigned long as_ulong; + isc_region_t as_region; + isc_textregion_t as_textregion; + void * as_pointer; } isc_tokenvalue_t; typedef struct isc_token { - isc_tokentype_t type; - isc_tokenvalue_t value; + isc_tokentype_t type; + isc_tokenvalue_t value; } isc_token_t; /*** @@ -177,7 +176,7 @@ isc_lex_getcomments(isc_lex_t *lex); *\li 'lex' is a valid lexer. * * Returns: - *\li The commenting sytles which are currently allowed. + *\li The commenting styles which are currently allowed. */ void @@ -380,7 +379,6 @@ isc_lex_getsourcename(isc_lex_t *lex); *\li result valid while current input source exists. */ - unsigned long isc_lex_getsourceline(isc_lex_t *lex); /*%< @@ -438,7 +436,6 @@ isc_lex_isfile(isc_lex_t *lex); *\li #false otherwise. */ - ISC_LANG_ENDDECLS #endif /* ISC_LEX_H */ diff --git a/lib/isc/include/isc/lfsr.h b/lib/isc/include/isc/lfsr.h index 3f2cfb4b..2a8555c1 100644 --- a/lib/isc/include/isc/lfsr.h +++ b/lib/isc/include/isc/lfsr.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LFSR_H #define ISC_LFSR_H 1 @@ -38,21 +37,19 @@ typedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *); * needs to be taken to not change state once the lfsr is in operation. */ struct isc_lfsr { - uint32_t state; /*%< previous state */ - unsigned int bits; /*%< length */ - uint32_t tap; /*%< bit taps */ - unsigned int count; /*%< reseed count (in BITS!) */ - isc_lfsrreseed_t reseed; /*%< reseed function */ - void *arg; /*%< reseed function argument */ + uint32_t state; /*%< previous state */ + unsigned int bits; /*%< length */ + uint32_t tap; /*%< bit taps */ + unsigned int count; /*%< reseed count (in BITS!) */ + isc_lfsrreseed_t reseed; /*%< reseed function */ + void * arg; /*%< reseed function argument */ }; ISC_LANG_BEGINDECLS - void -isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, - uint32_t tap, unsigned int count, - isc_lfsrreseed_t reseed, void *arg); +isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, uint32_t tap, + unsigned int count, isc_lfsrreseed_t reseed, void *arg); /*%< * Initialize an LFSR. * diff --git a/lib/isc/include/isc/lib.h b/lib/isc/include/isc/lib.h index 6ff8914f..4a77293c 100644 --- a/lib/isc/include/isc/lib.h +++ b/lib/isc/include/isc/lib.h @@ -3,20 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LIB_H #define ISC_LIB_H 1 /*! \file isc/lib.h */ -#include <isc/types.h> #include <isc/lang.h> +#include <isc/types.h> ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/likely.h b/lib/isc/include/isc/likely.h index 8cc5b2eb..300e8be4 100644 --- a/lib/isc/include/isc/likely.h +++ b/lib/isc/include/isc/likely.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -15,12 +15,17 @@ /*% * Performance */ +#ifdef CPPCHECK +#define ISC_LIKELY(x) (x) +#define ISC_UNLIKELY(x) (x) +#else /* ifdef CPPCHECK */ #ifdef HAVE_BUILTIN_EXPECT -#define ISC_LIKELY(x) __builtin_expect(!!(x), 1) -#define ISC_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define ISC_LIKELY(x) (x) -#define ISC_UNLIKELY(x) (x) -#endif +#define ISC_LIKELY(x) __builtin_expect(!!(x), 1) +#define ISC_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else /* ifdef HAVE_BUILTIN_EXPECT */ +#define ISC_LIKELY(x) (x) +#define ISC_UNLIKELY(x) (x) +#endif /* ifdef HAVE_BUILTIN_EXPECT */ +#endif /* ifdef CPPCHECK */ #endif /* ISC_LIKELY_H */ diff --git a/lib/isc/include/isc/list.h b/lib/isc/include/isc/list.h index bc90bb97..4ed1f3ca 100644 --- a/lib/isc/include/isc/list.h +++ b/lib/isc/include/isc/list.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LIST_H #define ISC_LIST_H 1 @@ -17,94 +16,104 @@ #ifdef ISC_LIST_CHECKINIT #define ISC_LINK_INSIST(x) ISC_INSIST(x) -#else +#else /* ifdef ISC_LIST_CHECKINIT */ #define ISC_LINK_INSIST(x) -#endif - -#define ISC_LIST(type) struct { type *head, *tail; } -#define ISC_LIST_INIT(list) \ - do { (list).head = NULL; (list).tail = NULL; } while (0) +#endif /* ifdef ISC_LIST_CHECKINIT */ + +#define ISC_LIST(type) \ + struct { \ + type *head, *tail; \ + } +#define ISC_LIST_INIT(list) \ + do { \ + (list).head = NULL; \ + (list).tail = NULL; \ + } while (0) -#define ISC_LINK(type) struct { type *prev, *next; } -#define ISC_LINK_INIT_TYPE(elt, link, type) \ - do { \ +#define ISC_LINK(type) \ + struct { \ + type *prev, *next; \ + } +#define ISC_LINK_INIT_TYPE(elt, link, type) \ + do { \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ } while (0) -#define ISC_LINK_INIT(elt, link) \ - ISC_LINK_INIT_TYPE(elt, link, void) +#define ISC_LINK_INIT(elt, link) ISC_LINK_INIT_TYPE(elt, link, void) #define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) -#define ISC_LIST_HEAD(list) ((list).head) -#define ISC_LIST_TAIL(list) ((list).tail) +#define ISC_LIST_HEAD(list) ((list).head) +#define ISC_LIST_TAIL(list) ((list).tail) #define ISC_LIST_EMPTY(list) ((list).head == NULL) -#define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \ - do { \ - if ((list).head != NULL) \ +#define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \ + do { \ + if ((list).head != NULL) { \ (list).head->link.prev = (elt); \ - else \ - (list).tail = (elt); \ - (elt)->link.prev = NULL; \ - (elt)->link.next = (list).head; \ - (list).head = (elt); \ + } else { \ + (list).tail = (elt); \ + } \ + (elt)->link.prev = NULL; \ + (elt)->link.next = (list).head; \ + (list).head = (elt); \ } while (0) -#define ISC_LIST_PREPEND(list, elt, link) \ - do { \ +#define ISC_LIST_PREPEND(list, elt, link) \ + do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ - __ISC_LIST_PREPENDUNSAFE(list, elt, link); \ + __ISC_LIST_PREPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDPREPEND(list, elt, link) \ - __ISC_LIST_PREPENDUNSAFE(list, elt, link) + __ISC_LIST_PREPENDUNSAFE(list, elt, link) -#define __ISC_LIST_APPENDUNSAFE(list, elt, link) \ - do { \ - if ((list).tail != NULL) \ +#define __ISC_LIST_APPENDUNSAFE(list, elt, link) \ + do { \ + if ((list).tail != NULL) { \ (list).tail->link.next = (elt); \ - else \ - (list).head = (elt); \ - (elt)->link.prev = (list).tail; \ - (elt)->link.next = NULL; \ - (list).tail = (elt); \ + } else { \ + (list).head = (elt); \ + } \ + (elt)->link.prev = (list).tail; \ + (elt)->link.next = NULL; \ + (list).tail = (elt); \ } while (0) -#define ISC_LIST_APPEND(list, elt, link) \ - do { \ +#define ISC_LIST_APPEND(list, elt, link) \ + do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ - __ISC_LIST_APPENDUNSAFE(list, elt, link); \ + __ISC_LIST_APPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDAPPEND(list, elt, link) \ - __ISC_LIST_APPENDUNSAFE(list, elt, link) + __ISC_LIST_APPENDUNSAFE(list, elt, link) -#define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \ - do { \ - if ((elt)->link.next != NULL) \ +#define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \ + do { \ + if ((elt)->link.next != NULL) { \ (elt)->link.next->link.prev = (elt)->link.prev; \ - else { \ - ISC_INSIST((list).tail == (elt)); \ - (list).tail = (elt)->link.prev; \ - } \ - if ((elt)->link.prev != NULL) \ + } else { \ + ISC_INSIST((list).tail == (elt)); \ + (list).tail = (elt)->link.prev; \ + } \ + if ((elt)->link.prev != NULL) { \ (elt)->link.prev->link.next = (elt)->link.next; \ - else { \ - ISC_INSIST((list).head == (elt)); \ - (list).head = (elt)->link.next; \ - } \ - (elt)->link.prev = (type *)(-1); \ - (elt)->link.next = (type *)(-1); \ - ISC_INSIST((list).head != (elt)); \ - ISC_INSIST((list).tail != (elt)); \ + } else { \ + ISC_INSIST((list).head == (elt)); \ + (list).head = (elt)->link.next; \ + } \ + (elt)->link.prev = (type *)(-1); \ + (elt)->link.next = (type *)(-1); \ + ISC_INSIST((list).head != (elt)); \ + ISC_INSIST((list).tail != (elt)); \ } while (0) #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) -#define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \ - do { \ - ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \ +#define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \ + do { \ + ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \ } while (0) #define ISC_LIST_UNLINK(list, elt, link) \ @@ -113,77 +122,77 @@ #define ISC_LIST_PREV(elt, link) ((elt)->link.prev) #define ISC_LIST_NEXT(elt, link) ((elt)->link.next) -#define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \ - do { \ - if ((before)->link.prev == NULL) \ - ISC_LIST_PREPEND(list, elt, link); \ - else { \ +#define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \ + do { \ + if ((before)->link.prev == NULL) { \ + ISC_LIST_PREPEND(list, elt, link); \ + } else { \ (elt)->link.prev = (before)->link.prev; \ - (before)->link.prev = (elt); \ - (elt)->link.prev->link.next = (elt); \ - (elt)->link.next = (before); \ - } \ + (before)->link.prev = (elt); \ + (elt)->link.prev->link.next = (elt); \ + (elt)->link.next = (before); \ + } \ } while (0) -#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \ - do { \ - ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \ - ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ +#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \ + do { \ + ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \ + ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \ } while (0) -#define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \ - do { \ - if ((after)->link.next == NULL) \ - ISC_LIST_APPEND(list, elt, link); \ - else { \ +#define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \ + do { \ + if ((after)->link.next == NULL) { \ + ISC_LIST_APPEND(list, elt, link); \ + } else { \ (elt)->link.next = (after)->link.next; \ - (after)->link.next = (elt); \ - (elt)->link.next->link.prev = (elt); \ - (elt)->link.prev = (after); \ - } \ + (after)->link.next = (elt); \ + (elt)->link.next->link.prev = (elt); \ + (elt)->link.prev = (after); \ + } \ } while (0) -#define ISC_LIST_INSERTAFTER(list, after, elt, link) \ - do { \ - ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \ - ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ +#define ISC_LIST_INSERTAFTER(list, after, elt, link) \ + do { \ + ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \ + ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \ } while (0) -#define ISC_LIST_APPENDLIST(list1, list2, link) \ - do { \ - if (ISC_LIST_EMPTY(list1)) \ - (list1) = (list2); \ - else if (!ISC_LIST_EMPTY(list2)) { \ +#define ISC_LIST_APPENDLIST(list1, list2, link) \ + do { \ + if (ISC_LIST_EMPTY(list1)) { \ + (list1) = (list2); \ + } else if (!ISC_LIST_EMPTY(list2)) { \ (list1).tail->link.next = (list2).head; \ (list2).head->link.prev = (list1).tail; \ - (list1).tail = (list2).tail; \ - } \ - (list2).head = NULL; \ - (list2).tail = NULL; \ + (list1).tail = (list2).tail; \ + } \ + (list2).head = NULL; \ + (list2).tail = NULL; \ } while (0) -#define ISC_LIST_PREPENDLIST(list1, list2, link) \ - do { \ - if (ISC_LIST_EMPTY(list1)) \ - (list1) = (list2); \ - else if (!ISC_LIST_EMPTY(list2)) { \ +#define ISC_LIST_PREPENDLIST(list1, list2, link) \ + do { \ + if (ISC_LIST_EMPTY(list1)) { \ + (list1) = (list2); \ + } else if (!ISC_LIST_EMPTY(list2)) { \ (list2).tail->link.next = (list1).head; \ (list1).head->link.prev = (list2).tail; \ - (list1).head = (list2).head; \ - } \ - (list2).head = NULL; \ - (list2).tail = NULL; \ + (list1).head = (list2).head; \ + } \ + (list2).head = NULL; \ + (list2).tail = NULL; \ } while (0) #define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) #define ISC_LIST_DEQUEUE(list, elt, link) \ - ISC_LIST_UNLINK_TYPE(list, elt, link, void) + ISC_LIST_UNLINK_TYPE(list, elt, link, void) #define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \ - ISC_LIST_UNLINK_TYPE(list, elt, link, type) + ISC_LIST_UNLINK_TYPE(list, elt, link, type) #define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) #define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \ diff --git a/lib/isc/include/isc/log.h b/lib/isc/include/isc/log.h index d2d28861..30bc57b1 100644 --- a/lib/isc/include/isc/log.h +++ b/lib/isc/include/isc/log.h @@ -3,21 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_LOG_H #define ISC_LOG_H 1 /*! \file isc/log.h */ +#include <stdarg.h> #include <stdbool.h> #include <stdio.h> -#include <stdarg.h> #include <syslog.h> /* XXXDCL NT */ #include <isc/formatcheck.h> @@ -30,45 +29,45 @@ * \brief Severity levels, patterned after Unix's syslog levels. * */ -#define ISC_LOG_DEBUG(level) (level) +#define ISC_LOG_DEBUG(level) (level) /*! * #ISC_LOG_DYNAMIC can only be used for defining channels with * isc_log_createchannel(), not to specify a level in isc_log_write(). */ -#define ISC_LOG_DYNAMIC 0 -#define ISC_LOG_INFO (-1) -#define ISC_LOG_NOTICE (-2) -#define ISC_LOG_WARNING (-3) -#define ISC_LOG_ERROR (-4) -#define ISC_LOG_CRITICAL (-5) +#define ISC_LOG_DYNAMIC 0 +#define ISC_LOG_INFO (-1) +#define ISC_LOG_NOTICE (-2) +#define ISC_LOG_WARNING (-3) +#define ISC_LOG_ERROR (-4) +#define ISC_LOG_CRITICAL (-5) /*@}*/ /*@{*/ /*! * \brief Destinations. */ -#define ISC_LOG_TONULL 1 -#define ISC_LOG_TOSYSLOG 2 -#define ISC_LOG_TOFILE 3 -#define ISC_LOG_TOFILEDESC 4 +#define ISC_LOG_TONULL 1 +#define ISC_LOG_TOSYSLOG 2 +#define ISC_LOG_TOFILE 3 +#define ISC_LOG_TOFILEDESC 4 /*@}*/ /*@{*/ /*% * Channel flags. */ -#define ISC_LOG_PRINTTIME 0x00001 -#define ISC_LOG_PRINTLEVEL 0x00002 -#define ISC_LOG_PRINTCATEGORY 0x00004 -#define ISC_LOG_PRINTMODULE 0x00008 -#define ISC_LOG_PRINTTAG 0x00010 /* tag and ":" */ -#define ISC_LOG_PRINTPREFIX 0x00020 /* tag only, no colon */ -#define ISC_LOG_PRINTALL 0x0003F -#define ISC_LOG_BUFFERED 0x00040 -#define ISC_LOG_DEBUGONLY 0x01000 -#define ISC_LOG_OPENERR 0x08000 /* internal */ -#define ISC_LOG_ISO8601 0x10000 /* if PRINTTIME, use ISO8601 */ -#define ISC_LOG_UTC 0x20000 /* if PRINTTIME, use UTC */ +#define ISC_LOG_PRINTTIME 0x00001 +#define ISC_LOG_PRINTLEVEL 0x00002 +#define ISC_LOG_PRINTCATEGORY 0x00004 +#define ISC_LOG_PRINTMODULE 0x00008 +#define ISC_LOG_PRINTTAG 0x00010 /* tag and ":" */ +#define ISC_LOG_PRINTPREFIX 0x00020 /* tag only, no colon */ +#define ISC_LOG_PRINTALL 0x0003F +#define ISC_LOG_BUFFERED 0x00040 +#define ISC_LOG_DEBUGONLY 0x01000 +#define ISC_LOG_OPENERR 0x08000 /* internal */ +#define ISC_LOG_ISO8601 0x10000 /* if PRINTTIME, use ISO8601 */ +#define ISC_LOG_UTC 0x20000 /* if PRINTTIME, use UTC */ /*@}*/ /*@{*/ @@ -79,9 +78,9 @@ * since I am intend to make large number of versions work efficiently, * INFINITE is going to be trivial to add to that. */ -#define ISC_LOG_ROLLINFINITE (-1) -#define ISC_LOG_ROLLNEVER (-2) -#define ISC_LOG_MAX_VERSIONS 256 +#define ISC_LOG_ROLLINFINITE (-1) +#define ISC_LOG_ROLLNEVER (-2) +#define ISC_LOG_MAX_VERSIONS 256 /*@}*/ /*@{*/ @@ -102,7 +101,7 @@ typedef enum { * isc_log_registercategories. */ struct isc_logcategory { - const char *name; + const char * name; unsigned int id; }; @@ -110,7 +109,7 @@ struct isc_logcategory { * Similar to isc_logcategory, but for all the modules a library defines. */ struct isc_logmodule { - const char *name; + const char * name; unsigned int id; }; @@ -126,9 +125,11 @@ struct isc_logmodule { * Setting maximum_size to zero implies no maximum. */ typedef struct isc_logfile { - FILE *stream; /*%< Initialized to NULL for #ISC_LOG_TOFILE. */ - const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */ - int versions; /* >= 0, #ISC_LOG_ROLLNEVER, #ISC_LOG_ROLLINFINITE. */ + FILE *stream; /*%< Initialized to NULL for + * #ISC_LOG_TOFILE. */ + const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */ + int versions; /* >= 0, #ISC_LOG_ROLLNEVER, + * #ISC_LOG_ROLLINFINITE. */ isc_log_rollsuffix_t suffix; /*% * stdio's ftell is standardized to return a long, which may well not @@ -138,7 +139,7 @@ typedef struct isc_logfile { * to a size large enough for the largest possible file on a system. */ isc_offset_t maximum_size; - bool maximum_reached; /*%< Private. */ + bool maximum_reached; /*%< Private. */ } isc_logfile_t; /*% @@ -147,7 +148,7 @@ typedef struct isc_logfile { */ typedef union isc_logdestination { isc_logfile_t file; - int facility; /* XXXDCL NT */ + int facility; /* XXXDCL NT */ } isc_logdestination_t; /*@{*/ @@ -159,8 +160,8 @@ typedef union isc_logdestination { * the order of the names. */ LIBISC_EXTERNAL_DATA extern isc_logcategory_t isc_categories[]; -LIBISC_EXTERNAL_DATA extern isc_log_t *isc_lctx; -LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[]; +LIBISC_EXTERNAL_DATA extern isc_log_t * isc_lctx; +LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[]; /*@}*/ /*@{*/ @@ -168,20 +169,21 @@ LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[]; * Do not log directly to DEFAULT. Use another category. When in doubt, * use GENERAL. */ -#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0]) -#define ISC_LOGCATEGORY_GENERAL (&isc_categories[1]) +#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0]) +#define ISC_LOGCATEGORY_GENERAL (&isc_categories[1]) /*@}*/ -#define ISC_LOGMODULE_SOCKET (&isc_modules[0]) -#define ISC_LOGMODULE_TIME (&isc_modules[1]) +#define ISC_LOGMODULE_SOCKET (&isc_modules[0]) +#define ISC_LOGMODULE_TIME (&isc_modules[1]) #define ISC_LOGMODULE_INTERFACE (&isc_modules[2]) -#define ISC_LOGMODULE_TIMER (&isc_modules[3]) -#define ISC_LOGMODULE_FILE (&isc_modules[4]) -#define ISC_LOGMODULE_OTHER (&isc_modules[5]) +#define ISC_LOGMODULE_TIMER (&isc_modules[3]) +#define ISC_LOGMODULE_FILE (&isc_modules[4]) +#define ISC_LOGMODULE_NETMGR (&isc_modules[5]) +#define ISC_LOGMODULE_OTHER (&isc_modules[6]) ISC_LANG_BEGINDECLS -isc_result_t +void isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp); /*%< * Establish a new logging context, with default channels. @@ -201,13 +203,9 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp); *\li *lcfgp will point to a valid logging configuration if all of the * necessary memory was allocated, or NULL otherwise. *\li On failure, no additional memory is allocated. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ -isc_result_t +void isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp); /*%< * Create the data structure that holds all of the configurable information @@ -247,28 +245,9 @@ isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp); *\li *lcfgp will point to a valid logging context if all of the necessary * memory was allocated, or NULL otherwise. *\li On failure, no additional memory is allocated. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource limit: Out of memory - */ - -isc_logconfig_t * -isc_logconfig_get(isc_log_t *lctx); -/*%< - * Returns a pointer to the configuration currently in use by the log context. - * - * Requires: - *\li lctx is a valid context. - * - * Ensures: - *\li The configuration pointer is non-null. - * - * Returns: - *\li The configuration pointer. */ -isc_result_t +void isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg); /*%< * Associate a new configuration with a logging context. @@ -287,10 +266,6 @@ isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg); * * Ensures: *\li Future calls to isc_log_write will use the new configuration. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ void @@ -315,11 +290,6 @@ isc_logconfig_destroy(isc_logconfig_t **lcfgp); /*%< * Destroy a logging configuration. * - * Notes: - *\li This function cannot be used directly with the return value of - * isc_logconfig_get, because a logging context must always have - * a valid configuration associated with it. - * * Requires: *\li lcfgp is not null and *lcfgp is a valid logging configuration. *\li The logging configuration is not in use by an existing logging context. @@ -406,11 +376,11 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]); * used with isc_log_usechannel() and isc_log_write(). */ -isc_result_t +void isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, unsigned int type, int level, const isc_logdestination_t *destination, - unsigned int flags); + unsigned int flags); /*%< * Specify the parameters of a logging channel. * @@ -467,18 +437,12 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, * No additional memory is being used by the logging context. * Any channel that previously existed with the given name * is not redefined. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource limit: Out of memory - *\li #ISC_R_UNEXPECTED type was out of range and REQUIRE() - * was disabled. */ isc_result_t isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, const isc_logcategory_t *category, - const isc_logmodule_t *module); + const isc_logmodule_t * module); /*%< * Associate a named logging channel with a category and module that * will use it. @@ -538,7 +502,7 @@ isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ -/* Attention: next four comments PRECEED code */ +/* Attention: next four comments PRECEDE code */ /*! * \brief * Write a message to the log channels. @@ -574,10 +538,9 @@ isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, */ void isc_log_write(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *format, ...) + isc_logmodule_t *module, int level, const char *format, ...) -ISC_FORMAT_PRINTF(5, 6); + ISC_FORMAT_PRINTF(5, 6); /*% * Write a message to the log channels. @@ -613,10 +576,10 @@ ISC_FORMAT_PRINTF(5, 6); */ void isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *format, va_list args) + isc_logmodule_t *module, int level, const char *format, + va_list args) -ISC_FORMAT_PRINTF(5, 0); + ISC_FORMAT_PRINTF(5, 0); /*% * Write a message to the log channels, pruning duplicates that occur within @@ -627,7 +590,7 @@ void isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, ...) -ISC_FORMAT_PRINTF(5, 6); + ISC_FORMAT_PRINTF(5, 6); /*% * Write a message to the log channels, pruning duplicates that occur within @@ -639,7 +602,7 @@ isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, va_list args) -ISC_FORMAT_PRINTF(5, 0); + ISC_FORMAT_PRINTF(5, 0); void isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level); @@ -718,7 +681,7 @@ isc_log_getduplicateinterval(isc_logconfig_t *lcfg); *\li The current duplicate filtering interval. */ -isc_result_t +void isc_log_settag(isc_logconfig_t *lcfg, const char *tag); /*%< * Set the program name or other identifier for #ISC_LOG_PRINTTAG. @@ -737,10 +700,6 @@ isc_log_settag(isc_logconfig_t *lcfg, const char *tag); * #ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the * empty string, calls to isc_log_gettag will return NULL. * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource Limit: Out of memory - * * XXXDCL when creating a new isc_logconfig_t, it might be nice if the tag * of the currently active isc_logconfig_t was inherited. this does not * currently happen. diff --git a/lib/isc/include/isc/magic.h b/lib/isc/include/isc/magic.h index c342d0cd..a2fbe931 100644 --- a/lib/isc/include/isc/magic.h +++ b/lib/isc/include/isc/magic.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_MAGIC_H #define ISC_MAGIC_H 1 @@ -21,16 +20,16 @@ typedef struct { unsigned int magic; } isc__magic_t; - /*% * To use this macro the magic number MUST be the first thing in the * structure, and MUST be of type "unsigned int". * The intent of this is to allow magic numbers to be checked even though * the object is otherwise opaque. */ -#define ISC_MAGIC_VALID(a,b) (ISC_LIKELY((a) != NULL) && \ - ISC_LIKELY(((const isc__magic_t *)(a))->magic == (b))) +#define ISC_MAGIC_VALID(a, b) \ + (ISC_LIKELY((a) != NULL) && \ + ISC_LIKELY(((const isc__magic_t *)(a))->magic == (b))) -#define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d)) +#define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d)) #endif /* ISC_MAGIC_H */ diff --git a/lib/isc/include/isc/md.h b/lib/isc/include/isc/md.h index 1645d416..163484fb 100644 --- a/lib/isc/include/isc/md.h +++ b/lib/isc/include/isc/md.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -18,12 +18,10 @@ #include <isc/lang.h> #include <isc/platform.h> -#include <isc/types.h> #include <isc/result.h> +#include <isc/types.h> -#include <openssl/evp.h> - -typedef EVP_MD_CTX isc_md_t; +typedef void isc_md_t; /** * isc_md_type_t: @@ -36,19 +34,32 @@ typedef EVP_MD_CTX isc_md_t; * * Enumeration of supported message digest algorithms. */ -typedef const EVP_MD * isc_md_type_t; - -#define ISC_MD_MD5 EVP_md5() -#define ISC_MD_SHA1 EVP_sha1() -#define ISC_MD_SHA224 EVP_sha224() -#define ISC_MD_SHA256 EVP_sha256() -#define ISC_MD_SHA384 EVP_sha384() -#define ISC_MD_SHA512 EVP_sha512() - -#define ISC_MD5_DIGESTLENGTH isc_md_type_get_size(ISC_MD_MD5) -#define ISC_MD5_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_MD5) -#define ISC_SHA1_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA1) -#define ISC_SHA1_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA1) +typedef void isc_md_type_t; + +#define ISC_MD_MD5 isc__md_md5() +#define ISC_MD_SHA1 isc__md_sha1() +#define ISC_MD_SHA224 isc__md_sha224() +#define ISC_MD_SHA256 isc__md_sha256() +#define ISC_MD_SHA384 isc__md_sha384() +#define ISC_MD_SHA512 isc__md_sha512() + +const isc_md_type_t * +isc__md_md5(void); +const isc_md_type_t * +isc__md_sha1(void); +const isc_md_type_t * +isc__md_sha224(void); +const isc_md_type_t * +isc__md_sha256(void); +const isc_md_type_t * +isc__md_sha384(void); +const isc_md_type_t * +isc__md_sha512(void); + +#define ISC_MD5_DIGESTLENGTH isc_md_type_get_size(ISC_MD_MD5) +#define ISC_MD5_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_MD5) +#define ISC_SHA1_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA1) +#define ISC_SHA1_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA1) #define ISC_SHA224_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA224) #define ISC_SHA224_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA224) #define ISC_SHA256_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA256) @@ -58,7 +69,7 @@ typedef const EVP_MD * isc_md_type_t; #define ISC_SHA512_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA512) #define ISC_SHA512_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA512) -#define ISC_MAX_MD_SIZE EVP_MAX_MD_SIZE +#define ISC_MAX_MD_SIZE 64U /* EVP_MAX_MD_SIZE */ #define ISC_MAX_BLOCK_SIZE 128U /* ISC_SHA512_BLOCK_LENGTH */ /** @@ -75,7 +86,7 @@ typedef const EVP_MD * isc_md_type_t; * at @digestlen, at most ISC_MAX_MD_SIZE bytes will be written. */ isc_result_t -isc_md(isc_md_type_t type, const unsigned char *buf, const size_t len, +isc_md(const isc_md_type_t *type, const unsigned char *buf, const size_t len, unsigned char *digest, unsigned int *digestlen); /** @@ -105,7 +116,7 @@ isc_md_free(isc_md_t *); * initialized before calling this function. */ isc_result_t -isc_md_init(isc_md_t *, const isc_md_type_t md_type); +isc_md_init(isc_md_t *, const isc_md_type_t *md_type); /** * isc_md_reset: @@ -152,7 +163,7 @@ isc_md_final(isc_md_t *md, unsigned char *digest, unsigned int *digestlen); * This function return the isc_md_type_t previously set for the supplied * message digest context or NULL if no isc_md_type_t has been set. */ -isc_md_type_t +const isc_md_type_t * isc_md_get_md_type(isc_md_t *md); /** @@ -180,7 +191,7 @@ isc_md_get_block_size(isc_md_t *md); * isc_md_type_t , i.e. the size of the hash. */ size_t -isc_md_type_get_size(isc_md_type_t md_type); +isc_md_type_get_size(const isc_md_type_t *md_type); /** * isc_md_block_size: @@ -189,4 +200,4 @@ isc_md_type_get_size(isc_md_type_t md_type); * isc_md_type_t. */ size_t -isc_md_type_get_block_size(isc_md_type_t md_type); +isc_md_type_get_block_size(const isc_md_type_t *md_type); diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index 6f61c175..97b249cc 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -17,12 +17,10 @@ #include <stdbool.h> #include <stdio.h> -#include <isc/json.h> #include <isc/lang.h> #include <isc/mutex.h> #include <isc/platform.h> #include <isc/types.h> -#include <isc/xml.h> ISC_LANG_BEGINDECLS @@ -30,16 +28,13 @@ ISC_LANG_BEGINDECLS #define ISC_MEM_HIWATER 1 typedef void (*isc_mem_water_t)(void *, int); -typedef void * (*isc_memalloc_t)(void *, size_t); -typedef void (*isc_memfree_t)(void *, void *); - /*% * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory * allocation and freeing by file and line number. */ #ifndef ISC_MEM_TRACKLINES #define ISC_MEM_TRACKLINES 1 -#endif +#endif /* ifndef ISC_MEM_TRACKLINES */ /*% * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside @@ -51,10 +46,10 @@ typedef void (*isc_memfree_t)(void *, void *); #ifdef __COVERITY__ #undef ISC_MEM_CHECKOVERRUN #define ISC_MEM_CHECKOVERRUN 0 -#endif +#endif /* ifdef __COVERITY__ */ #ifndef ISC_MEM_CHECKOVERRUN #define ISC_MEM_CHECKOVERRUN 1 -#endif +#endif /* ifndef ISC_MEM_CHECKOVERRUN */ /*% * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic @@ -63,18 +58,18 @@ typedef void (*isc_memfree_t)(void *, void *); */ #ifndef ISC_MEMPOOL_NAMES #define ISC_MEMPOOL_NAMES 1 -#endif +#endif /* ifndef ISC_MEMPOOL_NAMES */ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_defaultflags; /*@{*/ -#define ISC_MEM_DEBUGTRACE 0x00000001U -#define ISC_MEM_DEBUGRECORD 0x00000002U -#define ISC_MEM_DEBUGUSAGE 0x00000004U -#define ISC_MEM_DEBUGSIZE 0x00000008U -#define ISC_MEM_DEBUGCTX 0x00000010U -#define ISC_MEM_DEBUGALL 0x0000001FU +#define ISC_MEM_DEBUGTRACE 0x00000001U +#define ISC_MEM_DEBUGRECORD 0x00000002U +#define ISC_MEM_DEBUGUSAGE 0x00000004U +#define ISC_MEM_DEBUGSIZE 0x00000008U +#define ISC_MEM_DEBUGCTX 0x00000010U +#define ISC_MEM_DEBUGALL 0x0000001FU /*!< * The variable isc_mem_debugging holds a set of flags for * turning certain memory debugging options on or off at @@ -104,12 +99,12 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_defaultflags; /*@}*/ #if ISC_MEM_TRACKLINES -#define _ISC_MEM_FILELINE , __FILE__, __LINE__ -#define _ISC_MEM_FLARG , const char *, unsigned int -#else +#define _ISC_MEM_FILELINE , __FILE__, __LINE__ +#define _ISC_MEM_FLARG , const char *, unsigned int +#else /* if ISC_MEM_TRACKLINES */ #define _ISC_MEM_FILELINE #define _ISC_MEM_FLARG -#endif +#endif /* if ISC_MEM_TRACKLINES */ /*! * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc() @@ -122,20 +117,21 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_defaultflags; #ifndef ISC_MEM_USE_INTERNAL_MALLOC #define ISC_MEM_USE_INTERNAL_MALLOC 1 -#endif +#endif /* ifndef ISC_MEM_USE_INTERNAL_MALLOC */ /* - * Flags for isc_mem_createx() calls. + * Flags for isc_mem_create() calls. */ -#define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */ -#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */ -#define ISC_MEMFLAG_FILL 0x00000004 /* fill with pattern after alloc and frees */ +#define ISC_MEMFLAG_RESERVED 0x00000001 /* reserved, obsoleted, don't use */ +#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */ +#define ISC_MEMFLAG_FILL \ + 0x00000004 /* fill with pattern after alloc and frees */ #if !ISC_MEM_USE_INTERNAL_MALLOC -#define ISC_MEMFLAG_DEFAULT 0 -#else -#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL|ISC_MEMFLAG_FILL -#endif +#define ISC_MEMFLAG_DEFAULT 0 +#else /* if !ISC_MEM_USE_INTERNAL_MALLOC */ +#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL | ISC_MEMFLAG_FILL +#endif /* if !ISC_MEM_USE_INTERNAL_MALLOC */ /*% * isc_mem_putanddetach() is a convenience function for use where you @@ -189,27 +185,26 @@ typedef struct isc_memmethods { * invariants. */ struct isc_mem { - unsigned int impmagic; - unsigned int magic; - isc_memmethods_t *methods; + unsigned int impmagic; + unsigned int magic; + isc_memmethods_t *methods; }; -#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x') -#define ISCAPI_MCTX_VALID(m) ((m) != NULL && \ - (m)->magic == ISCAPI_MCTX_MAGIC) +#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A', 'm', 'c', 'x') +#define ISCAPI_MCTX_VALID(m) ((m) != NULL && (m)->magic == ISCAPI_MCTX_MAGIC) /*% * This is the common prefix of a memory pool context. The same note as * that for the mem structure applies. */ struct isc_mempool { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A','m','p','l') -#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \ - (mp)->magic == ISCAPI_MPOOL_MAGIC) +#define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A', 'm', 'p', 'l') +#define ISCAPI_MPOOL_VALID(mp) \ + ((mp) != NULL && (mp)->magic == ISCAPI_MPOOL_MAGIC) /*% * These functions are actually implemented in isc__mem_<function> @@ -223,73 +218,44 @@ struct isc_mempool { * loaded modules can use them even if named is statically linked. */ -#define ISCMEMFUNC(sfx) isc__mem_ ## sfx -#define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx +#define ISCMEMFUNC(sfx) isc__mem_##sfx +#define ISCMEMPOOLFUNC(sfx) isc__mempool_##sfx -#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE) -#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE) -#define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE) -#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE) +#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s)_ISC_MEM_FILELINE) +#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s)_ISC_MEM_FILELINE) +#define isc_mem_reallocate(c, p, s) \ + ISCMEMFUNC(reallocate)((c), (p), (s)_ISC_MEM_FILELINE) +#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p)_ISC_MEM_FILELINE) +#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c)_ISC_MEM_FILELINE) -#define isc_mem_put(c, p, s) \ - do { \ - ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \ - (p) = NULL; \ +#define isc_mem_put(c, p, s) \ + do { \ + ISCMEMFUNC(put)((c), (p), (s)_ISC_MEM_FILELINE); \ + (p) = NULL; \ } while (0) -#define isc_mem_putanddetach(c, p, s) \ - do { \ - ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \ - (p) = NULL; \ +#define isc_mem_putanddetach(c, p, s) \ + do { \ + ISCMEMFUNC(putanddetach)((c), (p), (s)_ISC_MEM_FILELINE); \ + (p) = NULL; \ } while (0) -#define isc_mem_free(c, p) \ - do { \ - ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE); \ - (p) = NULL; \ +#define isc_mem_free(c, p) \ + do { \ + ISCMEMFUNC(free)((c), (p)_ISC_MEM_FILELINE); \ + (p) = NULL; \ } while (0) -#define isc_mempool_put(c, p) \ - do { \ - ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \ - (p) = NULL; \ +#define isc_mempool_put(c, p) \ + do { \ + ISCMEMPOOLFUNC(put)((c), (p)_ISC_MEM_FILELINE); \ + (p) = NULL; \ } while (0) /*@{*/ -isc_result_t -isc_mem_create(size_t max_size, size_t target_size, - isc_mem_t **mctxp); - -isc_result_t -isc_mem_createx(size_t max_size, size_t target_size, - isc_memalloc_t memalloc, isc_memfree_t memfree, - void *arg, isc_mem_t **mctxp, unsigned int flags); +void +isc_mem_create(isc_mem_t **mctxp); /*!< * \brief Create a memory context. * - * 'max_size' and 'target_size' are tuning parameters. When - * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size' - * will be satisfied by getting blocks of size 'target_size' from the - * system allocator and breaking them up into pieces; larger allocations - * will use the system allocator directly. If 'max_size' and/or - * 'target_size' are zero, default values will be * used. When - * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored. - * - * 'max_size' is also used to size the statistics arrays and the array - * used to record active memory when ISC_MEM_DEBUGRECORD is set. Setting - * 'max_size' too low can have detrimental effects on performance. - * - * A memory context created using isc_mem_createx() will obtain - * memory from the system by calling 'memalloc' and 'memfree', - * passing them the argument 'arg'. A memory context created - * using isc_mem_create() will use the standard library malloc() - * and free(). - * - * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context - * will be accessed without locking. The user who creates the context must - * ensure there be no race. Since this can be a source of bug, it is generally - * inadvisable to use this flag unless the user is very sure about the race - * condition and the access to the object is highly performance sensitive. - * * Requires: * mctxp != NULL && *mctxp == NULL */ /*@}*/ @@ -326,8 +292,7 @@ isc_mem_stats(isc_mem_t *mctx, FILE *out); */ void -isc_mem_setdestroycheck(isc_mem_t *mctx, - bool on); +isc_mem_setdestroycheck(isc_mem_t *mctx, bool on); /*%< * If 'on' is true, 'mctx' will check for memory leaks when * destroyed and abort the program if any are present. @@ -467,26 +432,25 @@ isc_mem_gettag(isc_mem_t *ctx); #ifdef HAVE_LIBXML2 int -isc_mem_renderxml(xmlTextWriterPtr writer); +isc_mem_renderxml(void *writer0); /*%< * Render all contexts' statistics and status in XML for writer. */ #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C isc_result_t -isc_mem_renderjson(json_object *memobj); +isc_mem_renderjson(void *memobj0); /*%< * Render all contexts' statistics and status in JSON. */ -#endif /* HAVE_JSON */ - +#endif /* HAVE_JSON_C */ /* * Memory pools */ -isc_result_t +void isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); /*%< * Create a memory pool. @@ -622,28 +586,18 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit); *\li limit > 0 */ - /* * Pseudo-private functions for use via macros. Do not call directly. */ -void * -ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG); -void -ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG); -void -ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); -void * -ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG); -void * -ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); -void -ISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG); -char * -ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG); -void * -ISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG); -void -ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG); +void *ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG); +void ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG); +void ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); +void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG); +void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); +void ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG); +char *ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG); +void *ISCMEMPOOLFUNC(get)(isc_mempool_t *_ISC_MEM_FLARG); +void ISCMEMPOOLFUNC(put)(isc_mempool_t *, void *_ISC_MEM_FLARG); ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/meminfo.h b/lib/isc/include/isc/meminfo.h index c2c7e57b..a241b1d0 100644 --- a/lib/isc/include/isc/meminfo.h +++ b/lib/isc/include/isc/meminfo.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -14,9 +14,8 @@ #include <inttypes.h> -#include <isc/types.h> - #include <isc/lang.h> +#include <isc/types.h> ISC_LANG_BEGINDECLS @@ -25,7 +24,7 @@ isc_meminfo_totalphys(void); /*%< * Return total available physical memory in bytes, or 0 if this cannot * be determined -*/ + */ ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/mutexatomic.h b/lib/isc/include/isc/mutexatomic.h new file mode 100644 index 00000000..1f4cd49c --- /dev/null +++ b/lib/isc/include/isc/mutexatomic.h @@ -0,0 +1,251 @@ +/* + * 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 + +#include <inttypes.h> +#include <stdbool.h> +#if HAVE_UCHAR_H +#include <uchar.h> +#endif /* HAVE_UCHAR_H */ + +#include <isc/mutex.h> + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif /* if !defined(__has_feature) */ + +#if !defined(__has_extension) +#define __has_extension(x) __has_feature(x) +#endif /* if !defined(__has_extension) */ + +#if !defined(__GNUC_PREREQ__) +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define __GNUC_PREREQ__(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ +#define __GNUC_PREREQ__(maj, min) 0 +#endif /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ +#endif /* if !defined(__GNUC_PREREQ__) */ + +#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) +#if __has_extension(c_atomic) || __has_extension(cxx_atomic) +#define __CLANG_ATOMICS +#elif __GNUC_PREREQ__(4, 7) +#define __GNUC_ATOMICS +#elif !defined(__GNUC__) +#error "isc/stdatomic.h does not support your compiler" +#endif /* if __has_extension(c_atomic) || __has_extension(cxx_atomic) */ +#endif /* if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) */ + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#endif /* ifndef __ATOMIC_RELAXED */ +#ifndef __ATOMIC_CONSUME +#define __ATOMIC_CONSUME 1 +#endif /* ifndef __ATOMIC_CONSUME */ +#ifndef __ATOMIC_ACQUIRE +#define __ATOMIC_ACQUIRE 2 +#endif /* ifndef __ATOMIC_ACQUIRE */ +#ifndef __ATOMIC_RELEASE +#define __ATOMIC_RELEASE 3 +#endif /* ifndef __ATOMIC_RELEASE */ +#ifndef __ATOMIC_ACQ_REL +#define __ATOMIC_ACQ_REL 4 +#endif /* ifndef __ATOMIC_ACQ_REL */ +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST 5 +#endif /* ifndef __ATOMIC_SEQ_CST */ + +enum memory_order { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST +}; + +typedef enum memory_order memory_order; + +#define ___TYPEDEF(type, name, orig) \ + typedef struct name { \ + isc_mutex_t m; \ + orig v; \ + } type; + +#define _TYPEDEF_S(type) ___TYPEDEF(atomic_##type, atomic_##type##_s, type) +#define _TYPEDEF_O(type, orig) \ + ___TYPEDEF(atomic_##type, atomic_##type##_s, orig) +#define _TYPEDEF_T(type) \ + ___TYPEDEF(atomic_##type##_t, atomic_##type##_s, type##_t) + +#ifndef HAVE_UCHAR_H +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +#endif /* HAVE_UCHAR_H */ + +_TYPEDEF_S(bool); +_TYPEDEF_S(char); +_TYPEDEF_O(schar, signed char); +_TYPEDEF_O(uchar, unsigned char); +_TYPEDEF_S(short); +_TYPEDEF_O(ushort, unsigned short); +_TYPEDEF_S(int); +_TYPEDEF_O(uint, unsigned int); +_TYPEDEF_S(long); +_TYPEDEF_O(ulong, unsigned long); +_TYPEDEF_O(llong, long long); +_TYPEDEF_O(ullong, unsigned long long); +_TYPEDEF_T(char16); +_TYPEDEF_T(char32); +_TYPEDEF_T(wchar); +_TYPEDEF_T(int_least8); +_TYPEDEF_T(uint_least8); +_TYPEDEF_T(int_least16); +_TYPEDEF_T(uint_least16); +_TYPEDEF_T(int_least32); +_TYPEDEF_T(uint_least32); +_TYPEDEF_T(int_least64); +_TYPEDEF_T(uint_least64); +_TYPEDEF_T(int_fast8); +_TYPEDEF_T(uint_fast8); +_TYPEDEF_T(int_fast16); +_TYPEDEF_T(uint_fast16); +_TYPEDEF_T(int_fast32); +_TYPEDEF_T(uint_fast32); +_TYPEDEF_T(int_fast64); +_TYPEDEF_T(uint_fast64); +_TYPEDEF_T(intptr); +_TYPEDEF_T(uintptr); +_TYPEDEF_T(size); +_TYPEDEF_T(ptrdiff); +_TYPEDEF_T(intmax); +_TYPEDEF_T(uintmax); + +#undef ___TYPEDEF +#undef _TYPEDEF_S +#undef _TYPEDEF_T +#undef _TYPEDEF_O + +#define ATOMIC_VAR_INIT(arg) \ + { \ + .m = PTHREAD_MUTEX_INITIALIZER, .v = arg \ + } + +#define atomic_init(obj, desired) \ + { \ + isc_mutex_init(&(obj)->m); \ + (obj)->v = desired; \ + } +#define atomic_load_explicit(obj, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_store_explicit(obj, desired, order) \ + { \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + (obj)->v = desired; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + } +#define atomic_fetch_add_explicit(obj, arg, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v += arg; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_fetch_sub_explicit(obj, arg, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v -= arg; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_fetch_and_explicit(obj, arg, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v &= arg; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_fetch_or_explicit(obj, arg, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v |= arg; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) \ + ({ \ + bool ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = ((obj)->v == *expected); \ + *expected = (obj)->v; \ + (obj)->v = ___v ? desired : (obj)->v; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ + fail) \ + ({ \ + bool ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = ((obj)->v == *expected); \ + *expected = (obj)->v; \ + (obj)->v = ___v ? desired : (obj)->v; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) + +#define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) +#define atomic_store(obj, arg) \ + atomic_store_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_add(obj, arg) \ + atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_sub(obj, arg) \ + atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_and(obj, arg) \ + atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_or(obj, arg) \ + atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst) +#define atomic_compare_exchange_strong(obj, expected, desired) \ + atomic_compare_exchange_strong_explicit(obj, expected, desired, \ + memory_order_seq_cst, \ + memory_order_seq_cst) +#define atomic_compare_exchange_weak(obj, expected, desired) \ + atomic_compare_exchange_weak_explicit(obj, expected, desired, \ + memory_order_seq_cst, \ + memory_order_seq_cst) +#define atomic_exchange_explicit(obj, desired, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v = desired; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) diff --git a/lib/isc/include/isc/mutexblock.h b/lib/isc/include/isc/mutexblock.h index e4019699..de20bb5b 100644 --- a/lib/isc/include/isc/mutexblock.h +++ b/lib/isc/include/isc/mutexblock.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_MUTEXBLOCK_H #define ISC_MUTEXBLOCK_H 1 diff --git a/lib/isc/include/isc/netaddr.h b/lib/isc/include/isc/netaddr.h index cd045af5..4d316419 100644 --- a/lib/isc/include/isc/netaddr.h +++ b/lib/isc/include/isc/netaddr.h @@ -3,20 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NETADDR_H #define ISC_NETADDR_H 1 /*! \file isc/netaddr.h */ -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> #include <isc/lang.h> #include <isc/net.h> @@ -25,18 +24,18 @@ #ifdef ISC_PLATFORM_HAVESYSUNH #include <sys/types.h> #include <sys/un.h> -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ ISC_LANG_BEGINDECLS struct isc_netaddr { unsigned int family; union { - struct in_addr in; + struct in_addr in; struct in6_addr in6; #ifdef ISC_PLATFORM_HAVESYSUNH char un[sizeof(((struct sockaddr_un *)0)->sun_path)]; -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ } type; uint32_t zone; }; @@ -172,7 +171,7 @@ isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s); isc_result_t isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen); /* - * Test whether the netaddr 'na' and 'prefixlen' are consistant. + * Test whether the netaddr 'na' and 'prefixlen' are consistent. * e.g. prefixlen within range. * na does not have bits set which are not covered by the prefixlen. * diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h new file mode 100644 index 00000000..dc4f977e --- /dev/null +++ b/lib/isc/include/isc/netmgr.h @@ -0,0 +1,392 @@ +/* + * 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 + +#include <isc/mem.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/types.h> + +/* + * Replacement for isc_sockettype_t provided by socket.h. + */ +typedef enum { + isc_socktype_tcp = 1, + isc_socktype_udp = 2, + isc_socktype_unix = 3, + isc_socktype_raw = 4 +} isc_socktype_t; + +typedef void (*isc_nm_recv_cb_t)(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *cbarg); +/*%< + * Callback function to be used when receiving a packet. + * + * 'handle' the handle that can be used to send back the answer. + * 'eresult' the result of the event. + * 'region' contains the received data, if any. It will be freed + * after return by caller. + * 'cbarg' the callback argument passed to isc_nm_listenudp(), + * isc_nm_listentcpdns(), or isc_nm_read(). + */ +typedef isc_result_t (*isc_nm_accept_cb_t)(isc_nmhandle_t *handle, + isc_result_t result, void *cbarg); +/*%< + * Callback function to be used when accepting a connection. (This differs + * from isc_nm_cb_t below in that it returns a result code.) + * + * 'handle' the handle that can be used to send back the answer. + * 'eresult' the result of the event. + * 'cbarg' the callback argument passed to isc_nm_listentcp() or + * isc_nm_listentcpdns(). + */ + +typedef void (*isc_nm_cb_t)(isc_nmhandle_t *handle, isc_result_t result, + void *cbarg); +/*%< + * Callback function for other network completion events (send, connect). + * + * 'handle' the handle on which the event took place. + * 'eresult' the result of the event. + * 'cbarg' the callback argument passed to isc_nm_send(), + * isc_nm_tcp_connect(), or isc_nm_listentcp() + */ + +typedef void (*isc_nm_opaquecb_t)(void *arg); +/*%< + * Opaque callback function, used for isc_nmhandle 'reset' and 'free' + * callbacks. + */ + +isc_nm_t * +isc_nm_start(isc_mem_t *mctx, uint32_t workers); +/*%< + * Creates a new network manager with 'workers' worker threads, + * and starts it running. + */ + +void +isc_nm_attach(isc_nm_t *mgr, isc_nm_t **dst); +void +isc_nm_detach(isc_nm_t **mgr0); +void +isc_nm_destroy(isc_nm_t **mgr0); +/*%< + * Attach/detach a network manager. When all references have been + * released, the network manager is shut down, freeing all resources. + * Destroy is working the same way as detach, but it actively waits + * for all other references to be gone. + */ + +void +isc_nm_closedown(isc_nm_t *mgr); +/*%< + * Close down all active connections, freeing associated resources; + * prevent new connections from being established. This can optionally + * be called prior to shutting down the netmgr, to stop all processing + * before shutting down the task manager. + */ + +/* Return thread ID of current thread, or ISC_NETMGR_TID_UNKNOWN */ +int +isc_nm_tid(void); + +void +isc_nmsocket_close(isc_nmsocket_t **sockp); +/*%< + * isc_nmsocket_close() detaches a listening socket that was + * created by isc_nm_listenudp(), isc_nm_listentcp(), or + * isc_nm_listentcpdns(). Once there are no remaining child + * sockets with active handles, the socket will be closed. + */ + +void +isc_nmhandle_attach(isc_nmhandle_t *handle, isc_nmhandle_t **dest); +void +isc_nmhandle_detach(isc_nmhandle_t **handlep); +/*%< + * Increment/decrement the reference counter in a netmgr handle, + * but (unlike the attach/detach functions) do not change the pointer + * value. If reference counters drop to zero, the handle can be + * marked inactive, possibly triggering deletion of its associated + * socket. + * + * (This will be used to prevent a client from being cleaned up when + * it's passed to an isc_task event handler. The libuv code would not + * otherwise know that the handle was in use and might free it, along + * with the client.) + */ + +void * +isc_nmhandle_getdata(isc_nmhandle_t *handle); + +void * +isc_nmhandle_getextra(isc_nmhandle_t *handle); + +bool +isc_nmhandle_is_stream(isc_nmhandle_t *handle); + +/* + * isc_nmhandle_t has a void * opaque field (usually - ns_client_t). + * We reuse handle and `opaque` can also be reused between calls. + * This function sets this field and two callbacks: + * - doreset resets the `opaque` to initial state + * - dofree frees everything associated with `opaque` + */ +void +isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg, + isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree); + +isc_sockaddr_t +isc_nmhandle_peeraddr(isc_nmhandle_t *handle); +/*%< + * Return the peer address for the given handle. + */ +isc_sockaddr_t +isc_nmhandle_localaddr(isc_nmhandle_t *handle); +/*%< + * Return the local address for the given handle. + */ + +isc_nm_t * +isc_nmhandle_netmgr(isc_nmhandle_t *handle); +/*%< + * Return a pointer to the netmgr object for the given handle. + */ + +isc_result_t +isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, + void *cbarg, size_t extrasize, isc_nmsocket_t **sockp); +/*%< + * Start listening for UDP packets on interface 'iface' using net manager + * 'mgr'. + * + * On success, 'sockp' will be updated to contain a new listening UDP socket. + * + * When a packet is received on the socket, 'cb' will be called with 'cbarg' + * as its argument. + * + * When handles are allocated for the socket, 'extrasize' additional bytes + * can be allocated along with the handle for an associated object, which + * can then be freed automatically when the handle is destroyed. + */ + +void +isc_nm_stoplistening(isc_nmsocket_t *sock); +/*%< + * Stop listening on socket 'sock'. + */ + +void +isc_nm_pause(isc_nm_t *mgr); +/*%< + * Pause all processing, equivalent to taskmgr exclusive tasks. + * It won't return until all workers have been paused. + */ + +void +isc_nm_resume(isc_nm_t *mgr); +/*%< + * Resume paused processing. It will return immediately after signalling + * workers to resume. + */ + +isc_result_t +isc_nm_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg); +/* + * Begin (or continue) reading on the socket associated with 'handle', and + * update its recv callback to 'cb', which will be called as soon as there + * is data to process. + */ + +isc_result_t +isc_nm_pauseread(isc_nmhandle_t *handle); +/*%< + * Pause reading on this handle's socket, but remember the callback. + * + * Requires: + * \li 'handle' is a valid netmgr handle. + */ + +void +isc_nm_cancelread(isc_nmhandle_t *handle); +/*%< + * Cancel reading on a connected socket. Calls the read/recv callback on + * active handles with a result code of ISC_R_CANCELED. + * + * Requires: + * \li 'sock' is a valid netmgr socket + * \li ...for which a read/recv callback has been defined. + */ + +isc_result_t +isc_nm_resumeread(isc_nmhandle_t *handle); +/*%< + * Resume reading on the handle's socket. + * + * Requires: + * \li 'handle' is a valid netmgr handle. + * \li ...for a socket with a defined read/recv callback. + */ + +isc_result_t +isc_nm_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg); +/*%< + * Send the data in 'region' via 'handle'. Afterward, the callback 'cb' is + * called with the argument 'cbarg'. + * + * 'region' is not copied; it has to be allocated beforehand and freed + * in 'cb'. + */ + +isc_result_t +isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface, + isc_nm_accept_cb_t accept_cb, void *accept_cbarg, + size_t extrahandlesize, int backlog, isc_quota_t *quota, + isc_nmsocket_t **sockp); +/*%< + * Start listening for raw messages over the TCP interface 'iface', using + * net manager 'mgr'. + * + * On success, 'sockp' will be updated to contain a new listening TCP + * socket. + * + * When connection is accepted on the socket, 'accept_cb' will be called with + * 'accept_cbarg' as its argument. The callback is expected to start a read. + * + * When handles are allocated for the socket, 'extrasize' additional bytes + * will be allocated along with the handle for an associated object. + * + * If 'quota' is not NULL, then the socket is attached to the specified + * quota. This allows us to enforce TCP client quota limits. + * + * NOTE: This is currently only called inside isc_nm_listentcpdns(), which + * creates a 'wrapper' socket that sends and receives DNS messages + * prepended with a two-byte length field, and handles buffering. + */ + +isc_result_t +isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer, + isc_nm_cb_t cb, void *cbarg, size_t extrahandlesize); +/*%< + * Create a socket using netmgr 'mgr', bind it to the address 'local', + * and connect it to the address 'peer'. + * + * When the connection is complete, call 'cb' with argument 'cbarg'. + * Allocate 'extrahandlesize' additional bytes along with the handle to use + * for an associated object. + * + * The connected socket can only be accessed via the handle passed to + * 'cb'. + */ + +isc_result_t +isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, + void *cbarg, isc_nm_accept_cb_t accept_cb, + void *accept_cbarg, size_t extrahandlesize, int backlog, + isc_quota_t *quota, isc_nmsocket_t **sockp); +/*%< + * Start listening for DNS messages over the TCP interface 'iface', using + * net manager 'mgr'. + * + * On success, 'sockp' will be updated to contain a new listening TCPDNS + * socket. This is a wrapper around a raw TCP socket, which sends and + * receives DNS messages via that socket. It handles message buffering + * and pipelining, and automatically prepends messages with a two-byte + * length field. + * + * When a complete DNS message is received on the socket, 'cb' will be + * called with 'cbarg' as its argument. + * + * When a new TCPDNS connection is accepted, 'accept_cb' will be called + * with 'accept_cbarg' as its argument. + * + * When handles are allocated for the socket, 'extrasize' additional bytes + * will be allocated along with the handle for an associated object + * (typically ns_client). + * + * 'quota' is passed to isc_nm_listentcp() when opening the raw TCP socket. + */ + +void +isc_nm_tcpdns_sequential(isc_nmhandle_t *handle); +/*%< + * Disable pipelining on this connection. Each DNS packet will be only + * processed after the previous completes. + * + * The socket must be unpaused after the query is processed. This is done + * the response is sent, or if we're dropping the query, it will be done + * when a handle is fully dereferenced by calling the socket's + * closehandle_cb callback. + * + * Note: This can only be run while a message is being processed; if it is + * run before any messages are read, no messages will be read. + * + * Also note: once this has been set, it cannot be reversed for a given + * connection. + */ + +void +isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle); +/*%< + * Enable keepalive on this connection. + * + * When keepalive is active, we switch to using the keepalive timeout + * to determine when to close a connection, rather than the idle timeout. + */ + +void +isc_nm_tcp_settimeouts(isc_nm_t *mgr, uint32_t init, uint32_t idle, + uint32_t keepalive, uint32_t advertised); +/*%< + * Sets the initial, idle, and keepalive timeout values to use for + * TCP connections, and the timeout value to advertise in responses using + * the EDNS TCP Keepalive option (which should ordinarily be the same + * as 'keepalive'), in tenths of seconds. + * + * Requires: + * \li 'mgr' is a valid netmgr. + */ + +void +isc_nm_tcp_gettimeouts(isc_nm_t *mgr, uint32_t *initial, uint32_t *idle, + uint32_t *keepalive, uint32_t *advertised); +/*%< + * Gets the initial, idle, keepalive, or advertised timeout values, + * in tenths of seconds. + * + * Any integer pointer parameter not set to NULL will be updated to + * contain the corresponding timeout value. + * + * Requires: + * \li 'mgr' is a valid netmgr. + */ + +void +isc_nm_maxudp(isc_nm_t *mgr, uint32_t maxudp); +/*%< + * Simulate a broken firewall that blocks UDP messages larger than a given + * size. + */ + +void +isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats); +/*%< + * Set a socket statistics counter set 'stats' for 'mgr'. + * + * Requires: + *\li 'mgr' is valid and doesn't have stats already set. + * + *\li stats is a valid set of statistics counters supporting the + * full range of socket-related stats counter numbers. + */ diff --git a/lib/isc/include/isc/netscope.h b/lib/isc/include/isc/netscope.h index 22224a15..4c413f3e 100644 --- a/lib/isc/include/isc/netscope.h +++ b/lib/isc/include/isc/netscope.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NETSCOPE_H #define ISC_NETSCOPE_H 1 diff --git a/lib/isc/include/isc/nonce.h b/lib/isc/include/isc/nonce.h index 48c3ebf0..15ac0ce1 100644 --- a/lib/isc/include/isc/nonce.h +++ b/lib/isc/include/isc/nonce.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/isc/os.h b/lib/isc/include/isc/os.h index eb8223e9..ce7615a0 100644 --- a/lib/isc/include/isc/os.h +++ b/lib/isc/include/isc/os.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_OS_H #define ISC_OS_H 1 diff --git a/lib/isc/include/isc/parseint.h b/lib/isc/include/isc/parseint.h index 41e8a6ce..3be4cef9 100644 --- a/lib/isc/include/isc/parseint.h +++ b/lib/isc/include/isc/parseint.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_PARSEINT_H #define ISC_PARSEINT_H 1 diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in index 90b9a2ee..bd86c3f2 100644 --- a/lib/isc/include/isc/platform.h.in +++ b/lib/isc/include/isc/platform.h.in @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -19,18 +19,28 @@ *****/ /*** - *** Thread-Local Storage + *** Default strerror_r buffer size ***/ -#ifdef HAVE___THREAD -#define thread_local __thread -#endif +#define ISC_STRERRORSIZE 128 /*** - *** Default strerror_r buffer size + *** System limitations ***/ -#define ISC_STRERRORSIZE 128 +#include <limits.h> + +#ifndef NAME_MAX +#define NAME_MAX 256 +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#ifndef IOV_MAX +#define IOV_MAX 1024 +#endif /*** *** Miscellaneous. diff --git a/lib/isc/include/isc/pool.h b/lib/isc/include/isc/pool.h index a648312a..1eae9685 100644 --- a/lib/isc/include/isc/pool.h +++ b/lib/isc/include/isc/pool.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,8 +13,8 @@ #define ISC_OBJPOOL_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/pool.h * \brief An object pool is a mechanism for sharing a small pool of @@ -26,7 +26,6 @@ * independent task or memory context. */ - /*** *** Imports. ***/ @@ -38,26 +37,22 @@ ISC_LANG_BEGINDECLS /***** - ***** Types. - *****/ +***** Types. +*****/ -typedef void -(*isc_pooldeallocator_t)(void **object); +typedef void (*isc_pooldeallocator_t)(void **object); -typedef isc_result_t -(*isc_poolinitializer_t)(void **target, void *arg); +typedef isc_result_t (*isc_poolinitializer_t)(void **target, void *arg); typedef struct isc_pool isc_pool_t; /***** - ***** Functions. - *****/ +***** Functions. +*****/ isc_result_t -isc_pool_create(isc_mem_t *mctx, unsigned int count, - isc_pooldeallocator_t free, - isc_poolinitializer_t init, void *initarg, - isc_pool_t **poolp); +isc_pool_create(isc_mem_t *mctx, unsigned int count, isc_pooldeallocator_t free, + isc_poolinitializer_t init, void *initarg, isc_pool_t **poolp); /*%< * Create a pool of "count" object pointers. If 'free' is not NULL, * it points to a function that will detach the objects. 'init' diff --git a/lib/isc/include/isc/portset.h b/lib/isc/include/isc/portset.h index 1f0d928c..a12432e7 100644 --- a/lib/isc/include/isc/portset.h +++ b/lib/isc/include/isc/portset.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file isc/portset.h * \brief Transport Protocol Port Manipulation Module * @@ -134,4 +133,4 @@ isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo, ISC_LANG_ENDDECLS -#endif /* ISC_PORTSET_H */ +#endif /* ISC_PORTSET_H */ diff --git a/lib/isc/include/isc/print.h b/lib/isc/include/isc/print.h index 928d708b..96bdcd63 100644 --- a/lib/isc/include/isc/print.h +++ b/lib/isc/include/isc/print.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -18,7 +18,7 @@ *** Imports ***/ -#include <isc/formatcheck.h> /* Required for ISC_FORMAT_PRINTF() macro. */ +#include <isc/formatcheck.h> /* Required for ISC_FORMAT_PRINTF() macro. */ #include <isc/lang.h> #include <isc/platform.h> diff --git a/lib/isc/include/isc/queue.h b/lib/isc/include/isc/queue.h index 43080a81..a48af888 100644 --- a/lib/isc/include/isc/queue.h +++ b/lib/isc/include/isc/queue.h @@ -3,159 +3,52 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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 +#include <isc/mem.h> -/* - * This is a generic implementation of a two-lock concurrent queue. - * There are built-in mutex locks for the head and tail of the queue, - * allowing elements to be safely added and removed at the same time. +typedef struct isc_queue isc_queue_t; + +isc_queue_t * +isc_queue_new(isc_mem_t *mctx, int max_threads); +/*%< + * Create a new fetch-and-add array queue. * - * NULL is "end of list" - * -1 is "not linked" + * 'max_threads' is currently unused. In the future it can be used + * to pass a maximum threads parameter when creating hazard pointers, + * but currently `isc_hp_t` uses a hard-coded value. */ -#ifndef ISC_QUEUE_H -#define ISC_QUEUE_H 1 - -#include <stdbool.h> - -#include <isc/assertions.h> -#include <isc/mutex.h> - -#ifdef ISC_QUEUE_CHECKINIT -#define ISC_QLINK_INSIST(x) ISC_INSIST(x) -#else -#define ISC_QLINK_INSIST(x) (void)0 -#endif - -#define ISC_QLINK(type) struct { type *prev, *next; } - -#define ISC_QLINK_INIT(elt, link) \ - do { \ - (elt)->link.next = (elt)->link.prev = (void *)(-1); \ - } while(0) - -#define ISC_QLINK_LINKED(elt, link) ((void*)(elt)->link.next != (void*)(-1)) - -#define ISC_QUEUE(type) struct { \ - type *head, *tail; \ - isc_mutex_t headlock, taillock; \ -} - -#define ISC_QUEUE_INIT(queue, link) \ - do { \ - isc_mutex_init(&(queue).taillock); \ - isc_mutex_init(&(queue).headlock); \ - (queue).tail = (queue).head = NULL; \ - } while (0) - -#define ISC_QUEUE_EMPTY(queue) ((queue).head == NULL) - -#define ISC_QUEUE_DESTROY(queue) \ - do { \ - ISC_QLINK_INSIST(ISC_QUEUE_EMPTY(queue)); \ - isc_mutex_destroy(&(queue).taillock); \ - isc_mutex_destroy(&(queue).headlock); \ - } while (0) - -/* - * queues are meant to separate the locks at either end. For best effect, that - * means keeping the ends separate - i.e. non-empty queues work best. - * - * a push to an empty queue has to take the pop lock to update - * the pop side of the queue. - * Popping the last entry has to take the push lock to update - * the push side of the queue. - * - * The order is (pop, push), because a pop is presumably in the - * latency path and a push is when we're done. - * - * We do an MT hot test in push to see if we need both locks, so we can - * acquire them in order. Hopefully that makes the case where we get - * the push lock and find we need the pop lock (and have to release it) rare. - * - * > 1 entry - no collision, push works on one end, pop on the other - * 0 entry - headlock race - * pop wins - return(NULL), push adds new as both head/tail - * push wins - updates head/tail, becomes 1 entry case. - * 1 entry - taillock race - * pop wins - return(pop) sets head/tail NULL, becomes 0 entry case - * push wins - updates {head,tail}->link.next, pop updates head - * with new ->link.next and doesn't update tail +void +isc_queue_enqueue(isc_queue_t *queue, uintptr_t item); +/*%< + * Enqueue an object pointer 'item' at the tail of the queue. * + * Requires: + * \li 'item' is not null. */ -#define ISC_QUEUE_PUSH(queue, elt, link) \ - do { \ - bool headlocked = false; \ - ISC_QLINK_INSIST(!ISC_QLINK_LINKED(elt, link)); \ - if ((queue).head == NULL) { \ - LOCK(&(queue).headlock); \ - headlocked = true; \ - } \ - LOCK(&(queue).taillock); \ - if ((queue).tail == NULL && !headlocked) { \ - UNLOCK(&(queue).taillock); \ - LOCK(&(queue).headlock); \ - LOCK(&(queue).taillock); \ - headlocked = true; \ - } \ - (elt)->link.prev = (queue).tail; \ - (elt)->link.next = NULL; \ - if ((queue).tail != NULL) \ - (queue).tail->link.next = (elt); \ - (queue).tail = (elt); \ - UNLOCK(&(queue).taillock); \ - if (headlocked) { \ - if ((queue).head == NULL) \ - (queue).head = (elt); \ - UNLOCK(&(queue).headlock); \ - } \ - } while (0) -#define ISC_QUEUE_POP(queue, link, ret) \ - do { \ - LOCK(&(queue).headlock); \ - ret = (queue).head; \ - while (ret != NULL) { \ - if (ret->link.next == NULL) { \ - LOCK(&(queue).taillock); \ - if (ret->link.next == NULL) { \ - (queue).head = (queue).tail = NULL; \ - UNLOCK(&(queue).taillock); \ - break; \ - }\ - UNLOCK(&(queue).taillock); \ - } \ - (queue).head = ret->link.next; \ - (queue).head->link.prev = NULL; \ - break; \ - } \ - UNLOCK(&(queue).headlock); \ - if (ret != NULL) \ - (ret)->link.next = (ret)->link.prev = (void *)(-1); \ - } while(0) - -#define ISC_QUEUE_UNLINK(queue, elt, link) \ - do { \ - ISC_QLINK_INSIST(ISC_QLINK_LINKED(elt, link)); \ - LOCK(&(queue).headlock); \ - LOCK(&(queue).taillock); \ - if ((elt)->link.prev == NULL) \ - (queue).head = (elt)->link.next; \ - else \ - (elt)->link.prev->link.next = (elt)->link.next; \ - if ((elt)->link.next == NULL) \ - (queue).tail = (elt)->link.prev; \ - else \ - (elt)->link.next->link.prev = (elt)->link.prev; \ - UNLOCK(&(queue).taillock); \ - UNLOCK(&(queue).headlock); \ - (elt)->link.next = (elt)->link.prev = (void *)(-1); \ - } while(0) +uintptr_t +isc_queue_dequeue(isc_queue_t *queue); +/*%< + * Remove an object pointer from the head of the queue and return the + * pointer. If the queue is empty, return `nulluintptr` (the uintptr_t + * representation of NULL). + * + * Requires: + * \li 'queue' is not null. + */ -#endif /* ISC_QUEUE_H */ +void +isc_queue_destroy(isc_queue_t *queue); +/*%< + * Destroy a queue. + * + * Requires: + * \li 'queue' is not null. + */ diff --git a/lib/isc/include/isc/quota.h b/lib/isc/include/isc/quota.h index 16f6181c..98d349e4 100644 --- a/lib/isc/include/isc/quota.h +++ b/lib/isc/include/isc/quota.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_QUOTA_H #define ISC_QUOTA_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/quota.h * @@ -36,19 +35,30 @@ #include <isc/types.h> /***** - ***** Types. - *****/ +***** Types. +*****/ ISC_LANG_BEGINDECLS +/*% isc_quota_cb - quota callback structure */ +typedef struct isc_quota_cb isc_quota_cb_t; +typedef void (*isc_quota_cb_func_t)(isc_quota_t *quota, void *data); +struct isc_quota_cb { + isc_quota_cb_func_t cb_func; + void * data; + ISC_LINK(isc_quota_cb_t) link; +}; + /*% isc_quota structure */ struct isc_quota { - atomic_uint_fast32_t max; - atomic_uint_fast32_t used; - atomic_uint_fast32_t soft; + atomic_uint_fast32_t max; + atomic_uint_fast32_t used; + atomic_uint_fast32_t soft; + atomic_uint_fast32_t waiting; + isc_mutex_t cblock; + ISC_LIST(isc_quota_cb_t) cbs; }; - void isc_quota_init(isc_quota_t *quota, unsigned int max); /*%< @@ -92,41 +102,48 @@ isc_quota_getused(isc_quota_t *quota); */ isc_result_t -isc_quota_reserve(isc_quota_t *quota); +isc_quota_attach(isc_quota_t *quota, isc_quota_t **p); /*%< - * Attempt to reserve one unit of 'quota'. + * + * Attempt to reserve one unit of 'quota', and also attaches '*p' to the quota + * if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA). * * Returns: - * \li #ISC_R_SUCCESS Success + * \li #ISC_R_SUCCESS Success * \li #ISC_R_SOFTQUOTA Success soft quota reached * \li #ISC_R_QUOTA Quota is full */ -void -isc_quota_release(isc_quota_t *quota); -/*%< - * Release one unit of quota. - */ - isc_result_t -isc_quota_attach(isc_quota_t *quota, isc_quota_t **p); +isc_quota_attach_cb(isc_quota_t *quota, isc_quota_t **p, isc_quota_cb_t *cb); /*%< - * Like isc_quota_reserve, and also attaches '*p' to the - * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA). + * + * Like isc_quota_attach(), but if there's no quota left then cb->cb_func will + * be called when we are attached to quota. + * + * Note: It's the caller's responsibility to make sure that we don't end up + * with a huge number of callbacks waiting, making it easy to create a + * resource exhaustion attack. For example, in the case of TCP listening, + * we simply don't accept new connections when the quota is exceeded, so + * the number of callbacks waiting in the queue will be limited by the + * listen() backlog. + * + * Returns: + * \li #ISC_R_SUCCESS Success + * \li #ISC_R_SOFTQUOTA Success soft quota reached + * \li #ISC_R_QUOTA Quota is full */ -isc_result_t -isc_quota_force(isc_quota_t *quota, isc_quota_t **p); +void +isc_quota_cb_init(isc_quota_cb_t *cb, isc_quota_cb_func_t cb_func, void *data); /*%< - * Like isc_quota_attach, but will attach '*p' to the quota - * even if the hard quota has been exceeded. + * Initialize isc_quota_cb_t - setup the list, set the callback and data. */ void isc_quota_detach(isc_quota_t **p); /*%< - * Like isc_quota_release, and also detaches '*p' from the - * quota. + * Release one unit of quota, and also detaches '*p' from the quota. */ ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/radix.h b/lib/isc/include/isc/radix.h index feaf2e31..50cdf6be 100644 --- a/lib/isc/include/isc/radix.h +++ b/lib/isc/include/isc/radix.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,42 +13,42 @@ #define _RADIX_H #include <inttypes.h> +#include <string.h> #include <isc/magic.h> -#include <isc/types.h> #include <isc/mutex.h> #include <isc/net.h> #include <isc/refcount.h> +#include <isc/types.h> -#include <string.h> - -#define NETADDR_TO_PREFIX_T(na,pt,bits) \ - do { \ - const void *p = na; \ - memset(&(pt), 0, sizeof(pt)); \ - if (p != NULL) { \ - (pt).family = (na)->family; \ - (pt).bitlen = (bits); \ - if ((pt).family == AF_INET6) { \ +#define NETADDR_TO_PREFIX_T(na, pt, bits) \ + do { \ + const void *p = na; \ + memset(&(pt), 0, sizeof(pt)); \ + if (p != NULL) { \ + (pt).family = (na)->family; \ + (pt).bitlen = (bits); \ + if ((pt).family == AF_INET6) { \ memmove(&(pt).add.sin6, &(na)->type.in6, \ - ((bits)+7)/8); \ - } else \ - memmove(&(pt).add.sin, &(na)->type.in, \ - ((bits)+7)/8); \ - } else { \ - (pt).family = AF_UNSPEC; \ - (pt).bitlen = 0; \ - } \ - isc_refcount_init(&(pt).refcount, 0); \ - } while(0) + ((bits) + 7) / 8); \ + } else \ + memmove(&(pt).add.sin, &(na)->type.in, \ + ((bits) + 7) / 8); \ + } else { \ + (pt).family = AF_UNSPEC; \ + (pt).bitlen = 0; \ + } \ + isc_refcount_init(&(pt).refcount, 0); \ + } while (0) typedef struct isc_prefix { - isc_mem_t *mctx; - unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */ - unsigned int bitlen; /* 0 for "any" */ + isc_mem_t * mctx; + unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for + * "any" */ + unsigned int bitlen; /* 0 for "any" */ isc_refcount_t refcount; union { - struct in_addr sin; + struct in_addr sin; struct in6_addr sin6; } add; } isc_prefix_t; @@ -56,7 +56,7 @@ typedef struct isc_prefix { typedef void (*isc_radix_destroyfunc_t)(void *); typedef void (*isc_radix_processfunc_t)(isc_prefix_t *, void **); -#define isc_prefix_tochar(prefix) ((char *)&(prefix)->add.sin) +#define isc_prefix_tochar(prefix) ((char *)&(prefix)->add.sin) #define isc_prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) /* @@ -78,33 +78,37 @@ typedef void (*isc_radix_processfunc_t)(isc_prefix_t *, void **); * but matches all IPv6 addresses too. */ -#define RADIX_V4 0 -#define RADIX_V6 1 +#define RADIX_V4 0 +#define RADIX_V6 1 #define RADIX_FAMILIES 2 #define ISC_RADIX_FAMILY(p) (((p)->family == AF_INET6) ? RADIX_V6 : RADIX_V4) typedef struct isc_radix_node { - isc_mem_t *mctx; - uint32_t bit; /* bit length of the prefix */ - isc_prefix_t *prefix; /* who we are in radix tree */ - struct isc_radix_node *l, *r; /* left and right children */ - struct isc_radix_node *parent; /* may be used */ - void *data[RADIX_FAMILIES]; /* pointers to IPv4 and IPV6 data */ - int node_num[RADIX_FAMILIES]; /* which node this was in the tree, - or -1 for glue nodes */ + isc_mem_t * mctx; + uint32_t bit; /* bit length of the prefix */ + isc_prefix_t * prefix; /* who we are in radix tree */ + struct isc_radix_node *l, *r; /* left and right children */ + struct isc_radix_node *parent; /* may be used */ + void * data[RADIX_FAMILIES]; /* pointers to IPv4 + * and IPV6 data */ + int node_num[RADIX_FAMILIES]; /* which node + * this was in + * the tree, + * or -1 for glue + * nodes */ } isc_radix_node_t; -#define RADIX_TREE_MAGIC ISC_MAGIC('R','d','x','T'); -#define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC); +#define RADIX_TREE_MAGIC ISC_MAGIC('R', 'd', 'x', 'T'); +#define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC); typedef struct isc_radix_tree { - unsigned int magic; - isc_mem_t *mctx; + unsigned int magic; + isc_mem_t * mctx; isc_radix_node_t *head; - uint32_t maxbits; /* for IP, 32 bit addresses */ - int num_active_node; /* for debugging purposes */ - int num_added_node; /* total number of nodes */ + uint32_t maxbits; /* for IP, 32 bit addresses */ + int num_active_node; /* for debugging purposes */ + int num_added_node; /* total number of nodes */ } isc_radix_tree_t; isc_result_t @@ -186,32 +190,33 @@ isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func); * \li 'func' to point to a function. */ -#define RADIX_MAXBITS 128 -#define RADIX_NBIT(x) (0x80 >> ((x) & 0x7f)) -#define RADIX_NBYTE(x) ((x) >> 3) - -#define RADIX_WALK(Xhead, Xnode) \ - do { \ - isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; \ - isc_radix_node_t **Xsp = Xstack; \ - isc_radix_node_t *Xrn = (Xhead); \ - while ((Xnode = Xrn)) { \ - if (Xnode->prefix) - -#define RADIX_WALK_END \ - if (Xrn->l) { \ - if (Xrn->r) { \ - *Xsp++ = Xrn->r; \ - } \ - Xrn = Xrn->l; \ - } else if (Xrn->r) { \ - Xrn = Xrn->r; \ - } else if (Xsp != Xstack) { \ - Xrn = *(--Xsp); \ - } else { \ - Xrn = (isc_radix_node_t *) 0; \ - } \ - } \ - } while (0) +#define RADIX_MAXBITS 128 +#define RADIX_NBIT(x) (0x80 >> ((x)&0x7f)) +#define RADIX_NBYTE(x) ((x) >> 3) + +#define RADIX_WALK(Xhead, Xnode) \ + do { \ + isc_radix_node_t * Xstack[RADIX_MAXBITS + 1]; \ + isc_radix_node_t **Xsp = Xstack; \ + isc_radix_node_t * Xrn = (Xhead); \ + while ((Xnode = Xrn)) { \ + if (Xnode->prefix) + +#define RADIX_WALK_END \ + if (Xrn->l) { \ + if (Xrn->r) { \ + *Xsp++ = Xrn->r; \ + } \ + Xrn = Xrn->l; \ + } else if (Xrn->r) { \ + Xrn = Xrn->r; \ + } else if (Xsp != Xstack) { \ + Xrn = *(--Xsp); \ + } else { \ + Xrn = (isc_radix_node_t *)0; \ + } \ + } \ + } \ + while (0) #endif /* _RADIX_H */ diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h index cdeaa3e4..556e7475 100644 --- a/lib/isc/include/isc/random.h +++ b/lib/isc/include/isc/random.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h index f6320b20..3598078c 100644 --- a/lib/isc/include/isc/ratelimiter.h +++ b/lib/isc/include/isc/ratelimiter.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_RATELIMITER_H #define ISC_RATELIMITER_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/ratelimiter.h * \brief A rate limiter is a mechanism for dispatching events at a limited @@ -36,8 +35,8 @@ ISC_LANG_BEGINDECLS /***** - ***** Functions. - *****/ +***** Functions. +*****/ isc_result_t isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h index 4e7f4d43..26f962b2 100644 --- a/lib/isc/include/isc/refcount.h +++ b/lib/isc/include/isc/refcount.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -40,27 +40,25 @@ typedef atomic_uint_fast32_t isc_refcount_t; * * \warning No memory barrier are being imposed here. */ -#define isc_refcount_init(target, value) \ - atomic_init(target, value) +#define isc_refcount_init(target, value) atomic_init(target, value) /** \def isc_refcount_current(ref) * \brief Returns current number of references. * \param[in] ref pointer to reference counter. * \returns current value of reference counter. * - * Undo implict promotion to 64 bits in our Windows implementation of + * Undo implicit promotion to 64 bits in our Windows implementation of * atomic_load_explicit() by casting to uint_fast32_t. */ -#define isc_refcount_current(target) \ - (uint_fast32_t)atomic_load_explicit(target, memory_order_acquire) +#define isc_refcount_current(target) (uint_fast32_t) atomic_load_acquire(target) /** \def isc_refcount_destroy(ref) * \brief a destructor that makes sure that all references were cleared. * \param[in] ref pointer to reference counter. * \returns nothing. */ -#define isc_refcount_destroy(target) \ +#define isc_refcount_destroy(target) \ ISC_REQUIRE(isc_refcount_current(target) == 0) /** \def isc_refcount_increment0(ref) @@ -68,23 +66,89 @@ typedef atomic_uint_fast32_t isc_refcount_t; * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment0(target) \ - isc_refcount_increment(target) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_increment0(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_add_relaxed(target, 1); + INSIST(__v < UINT32_MAX); + return (__v); +} +#else /* _MSC_VER */ +#define isc_refcount_increment0(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v < UINT32_MAX); \ + __v; \ + }) +#endif /* _MSC_VER */ /** \def isc_refcount_increment(ref) * \brief increases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment(target) \ - atomic_fetch_add_explicit(target, 1, memory_order_relaxed) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_increment(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_add_relaxed(target, 1); + INSIST(__v > 0 && __v < UINT32_MAX); + return (__v); +} +#else /* _MSC_VER */ +#define isc_refcount_increment(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v > 0 && __v < UINT32_MAX); \ + __v; \ + }) +#endif /* _MSC_VER */ /** \def isc_refcount_decrement(ref) * \brief decreases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_decrement(target) \ - atomic_fetch_sub_explicit(target, 1, memory_order_release) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_decrement(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_sub_acq_rel(target, 1); + INSIST(__v > 0); + return (__v); +} +#else /* _MSC_VER */ +#define isc_refcount_decrement(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_sub_acq_rel(target, 1); \ + INSIST(__v > 0); \ + __v; \ + }) +#endif /* _MSC_VER */ + +#define isc_refcount_decrementz(target) \ + do { \ + uint_fast32_t _refs = isc_refcount_decrement(target); \ + ISC_INSIST(_refs == 1); \ + } while (0) + +#define isc_refcount_decrement1(target) \ + do { \ + uint_fast32_t _refs = isc_refcount_decrement(target); \ + ISC_INSIST(_refs > 1); \ + } while (0) + +#define isc_refcount_decrement0(target) \ + do { \ + uint_fast32_t _refs = isc_refcount_decrement(target); \ + ISC_INSIST(_refs > 0); \ + } while (0) ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/regex.h b/lib/isc/include/isc/regex.h index cab10c1f..f6dcf3f8 100644 --- a/lib/isc/include/isc/regex.h +++ b/lib/isc/include/isc/regex.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -14,8 +14,8 @@ /*! \file isc/regex.h */ -#include <isc/types.h> #include <isc/lang.h> +#include <isc/types.h> ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/region.h b/lib/isc/include/isc/region.h index ee013547..b6c932f4 100644 --- a/lib/isc/include/isc/region.h +++ b/lib/isc/include/isc/region.h @@ -3,42 +3,41 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_REGION_H #define ISC_REGION_H 1 /*! \file isc/region.h */ -#include <isc/types.h> #include <isc/lang.h> +#include <isc/types.h> struct isc_region { - unsigned char * base; - unsigned int length; + unsigned char *base; + unsigned int length; }; struct isc_textregion { - char * base; - unsigned int length; + char * base; + unsigned int length; }; /* XXXDCL questionable ... bears discussion. we have been putting off * discussing the region api. */ struct isc_constregion { - const void * base; - unsigned int length; + const void * base; + unsigned int length; }; struct isc_consttextregion { - const char * base; - unsigned int length; + const char * base; + unsigned int length; }; /*@{*/ @@ -47,31 +46,31 @@ struct isc_consttextregion { * Some macros are defined below for convenience. */ -#define isc_region_consume(r,l) \ - do { \ - isc_region_t *_r = (r); \ - unsigned int _l = (l); \ +#define isc_region_consume(r, l) \ + do { \ + isc_region_t *_r = (r); \ + unsigned int _l = (l); \ INSIST(_r->length >= _l); \ - _r->base += _l; \ - _r->length -= _l; \ + _r->base += _l; \ + _r->length -= _l; \ } while (0) -#define isc_textregion_consume(r,l) \ - do { \ +#define isc_textregion_consume(r, l) \ + do { \ isc_textregion_t *_r = (r); \ - unsigned int _l = (l); \ - INSIST(_r->length >= _l); \ - _r->base += _l; \ - _r->length -= _l; \ + unsigned int _l = (l); \ + INSIST(_r->length >= _l); \ + _r->base += _l; \ + _r->length -= _l; \ } while (0) -#define isc_constregion_consume(r,l) \ - do { \ +#define isc_constregion_consume(r, l) \ + do { \ isc_constregion_t *_r = (r); \ - unsigned int _l = (l); \ - INSIST(_r->length >= _l); \ - _r->base += _l; \ - _r->length -= _l; \ + unsigned int _l = (l); \ + INSIST(_r->length >= _l); \ + _r->base += _l; \ + _r->length -= _l; \ } while (0) /*@}*/ diff --git a/lib/isc/include/isc/resource.h b/lib/isc/include/isc/resource.h index 01792345..0a331312 100644 --- a/lib/isc/include/isc/resource.h +++ b/lib/isc/include/isc/resource.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_RESOURCE_H #define ISC_RESOURCE_H 1 @@ -87,4 +86,3 @@ isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value); ISC_LANG_ENDDECLS #endif /* ISC_RESOURCE_H */ - diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h index 36792fa0..99c55a32 100644 --- a/lib/isc/include/isc/result.h +++ b/lib/isc/include/isc/result.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_RESULT_H #define ISC_RESULT_H 1 @@ -18,97 +17,97 @@ #include <isc/lang.h> #include <isc/types.h> -#define ISC_R_SUCCESS 0 /*%< success */ -#define ISC_R_NOMEMORY 1 /*%< out of memory */ -#define ISC_R_TIMEDOUT 2 /*%< timed out */ -#define ISC_R_NOTHREADS 3 /*%< no available threads */ -#define ISC_R_ADDRNOTAVAIL 4 /*%< address not available */ -#define ISC_R_ADDRINUSE 5 /*%< address in use */ -#define ISC_R_NOPERM 6 /*%< permission denied */ -#define ISC_R_NOCONN 7 /*%< no pending connections */ -#define ISC_R_NETUNREACH 8 /*%< network unreachable */ -#define ISC_R_HOSTUNREACH 9 /*%< host unreachable */ -#define ISC_R_NETDOWN 10 /*%< network down */ -#define ISC_R_HOSTDOWN 11 /*%< host down */ -#define ISC_R_CONNREFUSED 12 /*%< connection refused */ -#define ISC_R_NORESOURCES 13 /*%< not enough free resources */ -#define ISC_R_EOF 14 /*%< end of file */ -#define ISC_R_BOUND 15 /*%< socket already bound */ -#define ISC_R_RELOAD 16 /*%< reload */ -#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */ -#define ISC_R_LOCKBUSY 17 /*%< lock busy */ -#define ISC_R_EXISTS 18 /*%< already exists */ -#define ISC_R_NOSPACE 19 /*%< ran out of space */ -#define ISC_R_CANCELED 20 /*%< operation canceled */ -#define ISC_R_NOTBOUND 21 /*%< socket is not bound */ -#define ISC_R_SHUTTINGDOWN 22 /*%< shutting down */ -#define ISC_R_NOTFOUND 23 /*%< not found */ -#define ISC_R_UNEXPECTEDEND 24 /*%< unexpected end of input */ -#define ISC_R_FAILURE 25 /*%< generic failure */ -#define ISC_R_IOERROR 26 /*%< I/O error */ -#define ISC_R_NOTIMPLEMENTED 27 /*%< not implemented */ -#define ISC_R_UNBALANCED 28 /*%< unbalanced parentheses */ -#define ISC_R_NOMORE 29 /*%< no more */ -#define ISC_R_INVALIDFILE 30 /*%< invalid file */ -#define ISC_R_BADBASE64 31 /*%< bad base64 encoding */ -#define ISC_R_UNEXPECTEDTOKEN 32 /*%< unexpected token */ -#define ISC_R_QUOTA 33 /*%< quota reached */ -#define ISC_R_UNEXPECTED 34 /*%< unexpected error */ -#define ISC_R_ALREADYRUNNING 35 /*%< already running */ -#define ISC_R_IGNORE 36 /*%< ignore */ -#define ISC_R_MASKNONCONTIG 37 /*%< addr mask not contiguous */ -#define ISC_R_FILENOTFOUND 38 /*%< file not found */ -#define ISC_R_FILEEXISTS 39 /*%< file already exists */ -#define ISC_R_NOTCONNECTED 40 /*%< socket is not connected */ -#define ISC_R_RANGE 41 /*%< out of range */ -#define ISC_R_NOENTROPY 42 /*%< out of entropy */ -#define ISC_R_MULTICAST 43 /*%< invalid use of multicast */ -#define ISC_R_NOTFILE 44 /*%< not a file */ -#define ISC_R_NOTDIRECTORY 45 /*%< not a directory */ -#define ISC_R_QUEUEFULL 46 /*%< queue is full */ -#define ISC_R_FAMILYMISMATCH 47 /*%< address family mismatch */ -#define ISC_R_FAMILYNOSUPPORT 48 /*%< AF not supported */ -#define ISC_R_BADHEX 49 /*%< bad hex encoding */ -#define ISC_R_TOOMANYOPENFILES 50 /*%< too many open files */ -#define ISC_R_NOTBLOCKING 51 /*%< not blocking */ -#define ISC_R_UNBALANCEDQUOTES 52 /*%< unbalanced quotes */ -#define ISC_R_INPROGRESS 53 /*%< operation in progress */ -#define ISC_R_CONNECTIONRESET 54 /*%< connection reset */ -#define ISC_R_SOFTQUOTA 55 /*%< soft quota reached */ -#define ISC_R_BADNUMBER 56 /*%< not a valid number */ -#define ISC_R_DISABLED 57 /*%< disabled */ -#define ISC_R_MAXSIZE 58 /*%< max size */ -#define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */ -#define ISC_R_BADBASE32 60 /*%< bad base32 encoding */ -#define ISC_R_UNSET 61 /*%< unset */ -#define ISC_R_MULTIPLE 62 /*%< multiple */ -#define ISC_R_WOULDBLOCK 63 /*%< would block */ -#define ISC_R_COMPLETE 64 /*%< complete */ -#define ISC_R_CRYPTOFAILURE 65 /*%< cryptography library failure */ -#define ISC_R_DISCQUOTA 66 /*%< disc quota */ -#define ISC_R_DISCFULL 67 /*%< disc full */ +#define ISC_R_SUCCESS 0 /*%< success */ +#define ISC_R_NOMEMORY 1 /*%< out of memory */ +#define ISC_R_TIMEDOUT 2 /*%< timed out */ +#define ISC_R_NOTHREADS 3 /*%< no available threads */ +#define ISC_R_ADDRNOTAVAIL 4 /*%< address not available */ +#define ISC_R_ADDRINUSE 5 /*%< address in use */ +#define ISC_R_NOPERM 6 /*%< permission denied */ +#define ISC_R_NOCONN 7 /*%< no pending connections */ +#define ISC_R_NETUNREACH 8 /*%< network unreachable */ +#define ISC_R_HOSTUNREACH 9 /*%< host unreachable */ +#define ISC_R_NETDOWN 10 /*%< network down */ +#define ISC_R_HOSTDOWN 11 /*%< host down */ +#define ISC_R_CONNREFUSED 12 /*%< connection refused */ +#define ISC_R_NORESOURCES 13 /*%< not enough free resources */ +#define ISC_R_EOF 14 /*%< end of file */ +#define ISC_R_BOUND 15 /*%< socket already bound */ +#define ISC_R_RELOAD 16 /*%< reload */ +#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */ +#define ISC_R_LOCKBUSY 17 /*%< lock busy */ +#define ISC_R_EXISTS 18 /*%< already exists */ +#define ISC_R_NOSPACE 19 /*%< ran out of space */ +#define ISC_R_CANCELED 20 /*%< operation canceled */ +#define ISC_R_NOTBOUND 21 /*%< socket is not bound */ +#define ISC_R_SHUTTINGDOWN 22 /*%< shutting down */ +#define ISC_R_NOTFOUND 23 /*%< not found */ +#define ISC_R_UNEXPECTEDEND 24 /*%< unexpected end of input */ +#define ISC_R_FAILURE 25 /*%< generic failure */ +#define ISC_R_IOERROR 26 /*%< I/O error */ +#define ISC_R_NOTIMPLEMENTED 27 /*%< not implemented */ +#define ISC_R_UNBALANCED 28 /*%< unbalanced parentheses */ +#define ISC_R_NOMORE 29 /*%< no more */ +#define ISC_R_INVALIDFILE 30 /*%< invalid file */ +#define ISC_R_BADBASE64 31 /*%< bad base64 encoding */ +#define ISC_R_UNEXPECTEDTOKEN 32 /*%< unexpected token */ +#define ISC_R_QUOTA 33 /*%< quota reached */ +#define ISC_R_UNEXPECTED 34 /*%< unexpected error */ +#define ISC_R_ALREADYRUNNING 35 /*%< already running */ +#define ISC_R_IGNORE 36 /*%< ignore */ +#define ISC_R_MASKNONCONTIG 37 /*%< addr mask not contiguous */ +#define ISC_R_FILENOTFOUND 38 /*%< file not found */ +#define ISC_R_FILEEXISTS 39 /*%< file already exists */ +#define ISC_R_NOTCONNECTED 40 /*%< socket is not connected */ +#define ISC_R_RANGE 41 /*%< out of range */ +#define ISC_R_NOENTROPY 42 /*%< out of entropy */ +#define ISC_R_MULTICAST 43 /*%< invalid use of multicast */ +#define ISC_R_NOTFILE 44 /*%< not a file */ +#define ISC_R_NOTDIRECTORY 45 /*%< not a directory */ +#define ISC_R_QUEUEFULL 46 /*%< queue is full */ +#define ISC_R_FAMILYMISMATCH 47 /*%< address family mismatch */ +#define ISC_R_FAMILYNOSUPPORT 48 /*%< AF not supported */ +#define ISC_R_BADHEX 49 /*%< bad hex encoding */ +#define ISC_R_TOOMANYOPENFILES 50 /*%< too many open files */ +#define ISC_R_NOTBLOCKING 51 /*%< not blocking */ +#define ISC_R_UNBALANCEDQUOTES 52 /*%< unbalanced quotes */ +#define ISC_R_INPROGRESS 53 /*%< operation in progress */ +#define ISC_R_CONNECTIONRESET 54 /*%< connection reset */ +#define ISC_R_SOFTQUOTA 55 /*%< soft quota reached */ +#define ISC_R_BADNUMBER 56 /*%< not a valid number */ +#define ISC_R_DISABLED 57 /*%< disabled */ +#define ISC_R_MAXSIZE 58 /*%< max size */ +#define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */ +#define ISC_R_BADBASE32 60 /*%< bad base32 encoding */ +#define ISC_R_UNSET 61 /*%< unset */ +#define ISC_R_MULTIPLE 62 /*%< multiple */ +#define ISC_R_WOULDBLOCK 63 /*%< would block */ +#define ISC_R_COMPLETE 64 /*%< complete */ +#define ISC_R_CRYPTOFAILURE 65 /*%< cryptography library failure */ +#define ISC_R_DISCQUOTA 66 /*%< disc quota */ +#define ISC_R_DISCFULL 67 /*%< disc full */ +#define ISC_R_DEFAULT 68 /*%< default */ +#define ISC_R_IPV4PREFIX 69 /*%< IPv4 prefix */ /*% Not a result code: the number of results. */ -#define ISC_R_NRESULTS 68 +#define ISC_R_NRESULTS 70 ISC_LANG_BEGINDECLS -const char * -isc_result_totext(isc_result_t); +const char *isc_result_totext(isc_result_t); /*%< * Convert an isc_result_t into a string message describing the result. */ -const char * -isc_result_toid(isc_result_t); +const char *isc_result_toid(isc_result_t); /*%< * Convert an isc_result_t into a string identifier such as * "ISC_R_SUCCESS". */ isc_result_t -isc_result_register(unsigned int base, unsigned int nresults, - const char **text, int set); +isc_result_register(unsigned int base, unsigned int nresults, const char **text, + int set); isc_result_t isc_result_registerids(unsigned int base, unsigned int nresults, diff --git a/lib/isc/include/isc/resultclass.h b/lib/isc/include/isc/resultclass.h index 08135f41..4953622e 100644 --- a/lib/isc/include/isc/resultclass.h +++ b/lib/isc/include/isc/resultclass.h @@ -3,17 +3,15 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_RESULTCLASS_H #define ISC_RESULTCLASS_H 1 - /*! \file isc/resultclass.h * \brief Registry of Predefined Result Type Classes * @@ -25,20 +23,19 @@ * Result classes >= 1024 and <= 65535 are reserved for application use. */ -#define ISC_RESULTCLASS_FROMNUM(num) ((num) << 16) -#define ISC_RESULTCLASS_TONUM(rclass) ((rclass) >> 16) -#define ISC_RESULTCLASS_SIZE 65536 +#define ISC_RESULTCLASS_FROMNUM(num) ((num) << 16) +#define ISC_RESULTCLASS_TONUM(rclass) ((rclass) >> 16) +#define ISC_RESULTCLASS_SIZE 65536 #define ISC_RESULTCLASS_INCLASS(rclass, result) \ - ((rclass) == ((result) & 0xFFFF0000)) - - -#define ISC_RESULTCLASS_ISC ISC_RESULTCLASS_FROMNUM(0) -#define ISC_RESULTCLASS_DNS ISC_RESULTCLASS_FROMNUM(1) -#define ISC_RESULTCLASS_DST ISC_RESULTCLASS_FROMNUM(2) -#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3) -#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4) -#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5) -#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6) -#define ISC_RESULTCLASS_PK11 ISC_RESULTCLASS_FROMNUM(7) + ((rclass) == ((result)&0xFFFF0000)) + +#define ISC_RESULTCLASS_ISC ISC_RESULTCLASS_FROMNUM(0) +#define ISC_RESULTCLASS_DNS ISC_RESULTCLASS_FROMNUM(1) +#define ISC_RESULTCLASS_DST ISC_RESULTCLASS_FROMNUM(2) +#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3) +#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4) +#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5) +#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6) +#define ISC_RESULTCLASS_PK11 ISC_RESULTCLASS_FROMNUM(7) #endif /* ISC_RESULTCLASS_H */ diff --git a/lib/isc/include/isc/rwlock.h b/lib/isc/include/isc/rwlock.h index ed1ff663..2347c7b0 100644 --- a/lib/isc/include/isc/rwlock.h +++ b/lib/isc/include/isc/rwlock.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_RWLOCK_H #define ISC_RWLOCK_H 1 @@ -31,11 +30,21 @@ typedef enum { isc_rwlocktype_write } isc_rwlocktype_t; +#if USE_PTHREAD_RWLOCK +#include <pthread.h> + +struct isc_rwlock { + pthread_rwlock_t rwlock; + atomic_bool downgrade; +}; + +#else /* USE_PTHREAD_RWLOCK */ + struct isc_rwlock { /* Unlocked. */ - unsigned int magic; - isc_mutex_t lock; - int32_t spins; + unsigned int magic; + isc_mutex_t lock; + atomic_int_fast32_t spins; /* * When some atomic instructions with hardware assistance are @@ -51,23 +60,24 @@ struct isc_rwlock { */ /* Read or modified atomically. */ - atomic_int_fast32_t write_requests; - atomic_int_fast32_t write_completions; - atomic_int_fast32_t cnt_and_flag; + atomic_int_fast32_t write_requests; + atomic_int_fast32_t write_completions; + atomic_int_fast32_t cnt_and_flag; /* Locked by lock. */ - isc_condition_t readable; - isc_condition_t writeable; - unsigned int readers_waiting; + isc_condition_t readable; + isc_condition_t writeable; + unsigned int readers_waiting; /* Locked by rwlock itself. */ - unsigned int write_granted; + atomic_uint_fast32_t write_granted; /* Unlocked. */ - unsigned int write_quota; - + unsigned int write_quota; }; +#endif /* USE_PTHREAD_RWLOCK */ + isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, unsigned int write_quota); diff --git a/lib/isc/include/isc/safe.h b/lib/isc/include/isc/safe.h index eb6ac91f..434d0edd 100644 --- a/lib/isc/include/isc/safe.h +++ b/lib/isc/include/isc/safe.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SAFE_H #define ISC_SAFE_H 1 @@ -17,11 +16,10 @@ #include <isc/lang.h> -#include <openssl/crypto.h> - ISC_LANG_BEGINDECLS -#define isc_safe_memequal(s1, s2, n) !CRYPTO_memcmp(s1, s2, n) +int +isc_safe_memequal(const void *, const void *, size_t); /*%< * Returns true iff. two blocks of memory are equal, otherwise @@ -29,7 +27,9 @@ ISC_LANG_BEGINDECLS * */ -#define isc_safe_memwipe(ptr, len) OPENSSL_cleanse(ptr, len) +void +isc_safe_memwipe(void *, size_t); + /*%< * Clear the memory of length `len` pointed to by `ptr`. * diff --git a/lib/isc/include/isc/serial.h b/lib/isc/include/isc/serial.h index 4c6d155e..fe7b59a2 100644 --- a/lib/isc/include/isc/serial.h +++ b/lib/isc/include/isc/serial.h @@ -3,18 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SERIAL_H #define ISC_SERIAL_H 1 -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> #include <isc/lang.h> #include <isc/types.h> diff --git a/lib/isc/include/isc/siphash.h b/lib/isc/include/isc/siphash.h new file mode 100644 index 00000000..10957a9f --- /dev/null +++ b/lib/isc/include/isc/siphash.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +/*! \file isc/siphash.h */ + +#pragma once + +#include <isc/lang.h> +#include <isc/platform.h> +#include <isc/types.h> + +#define ISC_SIPHASH24_KEY_LENGTH 128 / 8 +#define ISC_SIPHASH24_TAG_LENGTH 64 / 8 + +#define ISC_HALFSIPHASH24_KEY_LENGTH 64 / 8 +#define ISC_HALFSIPHASH24_TAG_LENGTH 32 / 8 + +ISC_LANG_BEGINDECLS + +void +isc_siphash24(const uint8_t *key, const uint8_t *in, const size_t inlen, + uint8_t *out); +void +isc_halfsiphash24(const uint8_t *key, const uint8_t *in, const size_t inlen, + uint8_t *out); + +ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 478e77c7..c28219d8 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SOCKADDR_H #define ISC_SOCKADDR_H 1 @@ -22,7 +21,7 @@ #include <isc/types.h> #ifdef ISC_PLATFORM_HAVESYSUNH #include <sys/un.h> -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ struct isc_sockaddr { union { @@ -31,21 +30,25 @@ struct isc_sockaddr { struct sockaddr_in6 sin6; struct sockaddr_storage ss; #ifdef ISC_PLATFORM_HAVESYSUNH - struct sockaddr_un sunix; -#endif - } type; - unsigned int length; /* XXXRTH beginning? */ - ISC_LINK(struct isc_sockaddr) link; + struct sockaddr_un sunix; +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ + } type; + unsigned int length; /* XXXRTH beginning? */ + ISC_LINK(struct isc_sockaddr) link; }; -#define ISC_SOCKADDR_CMPADDR 0x0001 /*%< compare the address - * sin_addr/sin6_addr */ -#define ISC_SOCKADDR_CMPPORT 0x0002 /*%< compare the port - * sin_port/sin6_port */ -#define ISC_SOCKADDR_CMPSCOPE 0x0004 /*%< compare the scope - * sin6_scope */ -#define ISC_SOCKADDR_CMPSCOPEZERO 0x0008 /*%< when comparing scopes - * zero scopes always match */ +#define ISC_SOCKADDR_CMPADDR \ + 0x0001 /*%< compare the address \ + * sin_addr/sin6_addr */ +#define ISC_SOCKADDR_CMPPORT \ + 0x0002 /*%< compare the port \ + * sin_port/sin6_port */ +#define ISC_SOCKADDR_CMPSCOPE \ + 0x0004 /*%< compare the scope \ + * sin6_scope */ +#define ISC_SOCKADDR_CMPSCOPEZERO \ + 0x0008 /*%< when comparing scopes \ + * zero scopes always match */ ISC_LANG_BEGINDECLS @@ -230,8 +233,12 @@ isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path); * \li ISC_R_SUCCESS */ -#define ISC_SOCKADDR_FORMATSIZE \ - sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#YYYYY") +isc_result_t +isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa); + +#define ISC_SOCKADDR_FORMATSIZE \ + sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#" \ + "YYYYY") /*%< * Minimum size of array to pass to isc_sockaddr_format(). */ diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 98fa51bf..0888ca6f 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,8 +13,8 @@ #define ISC_SOCKET_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/socket.h * \brief Provides TCP and UDP sockets for network I/O. The sockets are event @@ -55,12 +55,10 @@ #include <isc/event.h> #include <isc/eventclass.h> #include <isc/lang.h> -#include <isc/json.h> #include <isc/region.h> #include <isc/sockaddr.h> #include <isc/time.h> #include <isc/types.h> -#include <isc/xml.h> ISC_LANG_BEGINDECLS @@ -72,7 +70,7 @@ ISC_LANG_BEGINDECLS * Maximum number of buffers in a scatter/gather read/write. The operating * system in use must support at least this number (plus one on some.) */ -#define ISC_SOCKET_MAXSCATTERGATHER 8 +#define ISC_SOCKET_MAXSCATTERGATHER 8 /*@{*/ /*! @@ -83,91 +81,10 @@ ISC_LANG_BEGINDECLS * AF_INET and AF_INET6). */ typedef enum { - ISC_SOCKET_REUSEADDRESS = 0x01U, + ISC_SOCKET_REUSEADDRESS = 0x01U, } isc_socket_options_t; /*@}*/ -/*% - * Statistics counters. Used as isc_statscounter_t values. - */ -enum { - isc_sockstatscounter_udp4open = 0, - isc_sockstatscounter_udp6open = 1, - isc_sockstatscounter_tcp4open = 2, - isc_sockstatscounter_tcp6open = 3, - isc_sockstatscounter_unixopen = 4, - - isc_sockstatscounter_udp4openfail = 5, - isc_sockstatscounter_udp6openfail = 6, - isc_sockstatscounter_tcp4openfail = 7, - isc_sockstatscounter_tcp6openfail = 8, - isc_sockstatscounter_unixopenfail = 9, - - isc_sockstatscounter_udp4close = 10, - isc_sockstatscounter_udp6close = 11, - isc_sockstatscounter_tcp4close = 12, - isc_sockstatscounter_tcp6close = 13, - isc_sockstatscounter_unixclose = 14, - isc_sockstatscounter_fdwatchclose = 15, - - isc_sockstatscounter_udp4bindfail = 16, - isc_sockstatscounter_udp6bindfail = 17, - isc_sockstatscounter_tcp4bindfail = 18, - isc_sockstatscounter_tcp6bindfail = 19, - isc_sockstatscounter_unixbindfail = 20, - isc_sockstatscounter_fdwatchbindfail = 21, - - isc_sockstatscounter_udp4connect = 22, - isc_sockstatscounter_udp6connect = 23, - isc_sockstatscounter_tcp4connect = 24, - isc_sockstatscounter_tcp6connect = 25, - isc_sockstatscounter_unixconnect = 26, - isc_sockstatscounter_fdwatchconnect = 27, - - isc_sockstatscounter_udp4connectfail = 28, - isc_sockstatscounter_udp6connectfail = 29, - isc_sockstatscounter_tcp4connectfail = 30, - isc_sockstatscounter_tcp6connectfail = 31, - isc_sockstatscounter_unixconnectfail = 32, - isc_sockstatscounter_fdwatchconnectfail = 33, - - isc_sockstatscounter_tcp4accept = 34, - isc_sockstatscounter_tcp6accept = 35, - isc_sockstatscounter_unixaccept = 36, - - isc_sockstatscounter_tcp4acceptfail = 37, - isc_sockstatscounter_tcp6acceptfail = 38, - isc_sockstatscounter_unixacceptfail = 39, - - isc_sockstatscounter_udp4sendfail = 40, - isc_sockstatscounter_udp6sendfail = 41, - isc_sockstatscounter_tcp4sendfail = 42, - isc_sockstatscounter_tcp6sendfail = 43, - isc_sockstatscounter_unixsendfail = 44, - isc_sockstatscounter_fdwatchsendfail = 45, - - isc_sockstatscounter_udp4recvfail = 46, - isc_sockstatscounter_udp6recvfail = 47, - isc_sockstatscounter_tcp4recvfail = 48, - isc_sockstatscounter_tcp6recvfail = 49, - isc_sockstatscounter_unixrecvfail = 50, - isc_sockstatscounter_fdwatchrecvfail = 51, - - isc_sockstatscounter_udp4active = 52, - isc_sockstatscounter_udp6active = 53, - isc_sockstatscounter_tcp4active = 54, - isc_sockstatscounter_tcp6active = 55, - isc_sockstatscounter_unixactive = 56, - - isc_sockstatscounter_rawopen = 57, - isc_sockstatscounter_rawopenfail = 58, - isc_sockstatscounter_rawclose = 59, - isc_sockstatscounter_rawrecvfail = 60, - isc_sockstatscounter_rawactive = 61, - - isc_sockstatscounter_max = 62 -}; - /*@{*/ /*! * _ATTACHED: Internal use only. @@ -182,14 +99,14 @@ enum { * _USEMINMTU: Set the per packet IPV6_USE_MIN_MTU flag. */ typedef enum { - ISC_SOCKEVENTATTR_ATTACHED = 0x10000000U, /* internal */ - ISC_SOCKEVENTATTR_TRUNC = 0x00800000U, /* public */ - ISC_SOCKEVENTATTR_CTRUNC = 0x00400000U, /* public */ - ISC_SOCKEVENTATTR_TIMESTAMP = 0x00200000U, /* public */ - ISC_SOCKEVENTATTR_PKTINFO = 0x00100000U, /* public */ - ISC_SOCKEVENTATTR_MULTICAST = 0x00080000U, /* public */ - ISC_SOCKEVENTATTR_DSCP = 0x00040000U, /* public */ - ISC_SOCKEVENTATTR_USEMINMTU = 0x00020000U /* public */ + ISC_SOCKEVENTATTR_ATTACHED = 0x10000000U, /* internal */ + ISC_SOCKEVENTATTR_TRUNC = 0x00800000U, /* public */ + ISC_SOCKEVENTATTR_CTRUNC = 0x00400000U, /* public */ + ISC_SOCKEVENTATTR_TIMESTAMP = 0x00200000U, /* public */ + ISC_SOCKEVENTATTR_PKTINFO = 0x00100000U, /* public */ + ISC_SOCKEVENTATTR_MULTICAST = 0x00080000U, /* public */ + ISC_SOCKEVENTATTR_DSCP = 0x00040000U, /* public */ + ISC_SOCKEVENTATTR_USEMINMTU = 0x00020000U /* public */ } isc_sockeventattr_t; /*@}*/ @@ -199,45 +116,45 @@ typedef enum { struct isc_socketevent { ISC_EVENT_COMMON(isc_socketevent_t); - isc_result_t result; /*%< OK, EOF, whatever else */ - unsigned int minimum; /*%< minimum i/o for event */ - unsigned int n; /*%< bytes read or written */ - unsigned int offset; /*%< offset into buffer list */ - isc_region_t region; /*%< for single-buffer i/o */ - isc_sockaddr_t address; /*%< source address */ - isc_time_t timestamp; /*%< timestamp of packet recv */ - struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */ - isc_sockeventattr_t attributes; /*%< see isc_sockeventattr_t - enum */ - isc_eventdestructor_t destroy; /*%< original destructor */ - unsigned int dscp; /*%< UDP dscp value */ + isc_result_t result; /*%< OK, EOF, whatever else */ + unsigned int minimum; /*%< minimum i/o for event */ + unsigned int n; /*%< bytes read or written */ + unsigned int offset; /*%< offset into buffer list */ + isc_region_t region; /*%< for single-buffer i/o */ + isc_sockaddr_t address; /*%< source address */ + isc_time_t timestamp; /*%< timestamp of packet recv */ + struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */ + isc_sockeventattr_t attributes; /*%< see isc_sockeventattr_t + * enum */ + isc_eventdestructor_t destroy; /*%< original destructor */ + unsigned int dscp; /*%< UDP dscp value */ }; typedef struct isc_socket_newconnev isc_socket_newconnev_t; struct isc_socket_newconnev { ISC_EVENT_COMMON(isc_socket_newconnev_t); - isc_socket_t * newsocket; - isc_result_t result; /*%< OK, EOF, whatever else */ - isc_sockaddr_t address; /*%< source address */ + isc_socket_t * newsocket; + isc_result_t result; /*%< OK, EOF, whatever else */ + isc_sockaddr_t address; /*%< source address */ }; typedef struct isc_socket_connev isc_socket_connev_t; struct isc_socket_connev { ISC_EVENT_COMMON(isc_socket_connev_t); - isc_result_t result; /*%< OK, EOF, whatever else */ + isc_result_t result; /*%< OK, EOF, whatever else */ }; -#define ISC_SOCKEVENT_ANYEVENT (0) -#define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1) -#define ISC_SOCKEVENT_SENDDONE (ISC_EVENTCLASS_SOCKET + 2) -#define ISC_SOCKEVENT_NEWCONN (ISC_EVENTCLASS_SOCKET + 3) -#define ISC_SOCKEVENT_CONNECT (ISC_EVENTCLASS_SOCKET + 4) +#define ISC_SOCKEVENT_ANYEVENT (0) +#define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1) +#define ISC_SOCKEVENT_SENDDONE (ISC_EVENTCLASS_SOCKET + 2) +#define ISC_SOCKEVENT_NEWCONN (ISC_EVENTCLASS_SOCKET + 3) +#define ISC_SOCKEVENT_CONNECT (ISC_EVENTCLASS_SOCKET + 4) /* * Internal events. */ -#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256) -#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257) +#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256) +#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257) typedef enum { isc_sockettype_udp = 1, @@ -250,28 +167,28 @@ typedef enum { /*! * How a socket should be shutdown in isc_socket_shutdown() calls. */ -#define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */ -#define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */ -#define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */ +#define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */ +#define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */ +#define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */ /*@}*/ /*@{*/ /*! * What I/O events to cancel in isc_socket_cancel() calls. */ -#define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */ -#define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */ -#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */ -#define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */ -#define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */ +#define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */ +#define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */ +#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */ +#define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */ +#define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */ /*@}*/ /*@{*/ /*! * Flags for isc_socket_send() and isc_socket_recv() calls. */ -#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */ -#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */ +#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */ +#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */ /*@}*/ /*% @@ -289,14 +206,14 @@ typedef enum { */ #ifndef WIN32 struct isc_socketmgr { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#endif +#endif /* ifndef WIN32 */ -#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g') -#define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \ - (m)->magic == ISCAPI_SOCKETMGR_MAGIC) +#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A', 's', 'm', 'g') +#define ISCAPI_SOCKETMGR_VALID(m) \ + ((m) != NULL && (m)->magic == ISCAPI_SOCKETMGR_MAGIC) /*% * This is the common prefix of a socket object. The same note as @@ -304,14 +221,14 @@ struct isc_socketmgr { */ #ifndef WIN32 struct isc_socket { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#endif +#endif /* ifndef WIN32 */ -#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t') -#define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \ - (s)->magic == ISCAPI_SOCKET_MAGIC) +#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A', 's', 'c', 't') +#define ISCAPI_SOCKET_VALID(s) \ + ((s) != NULL && (s)->magic == ISCAPI_SOCKET_MAGIC) /*** *** Socket and Socket Manager Functions @@ -321,9 +238,7 @@ struct isc_socket { ***/ isc_result_t -isc_socket_create(isc_socketmgr_t *manager, - int pf, - isc_sockettype_t type, +isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp); /*%< * Create a new 'type' socket managed by 'manager'. @@ -357,8 +272,7 @@ isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp); */ void -isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, - unsigned int how); +isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); /*%< * Cancel pending I/O of the type specified by "how". * @@ -371,7 +285,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, * * \li "task" is NULL or a valid task * - * "how" is a bitmask describing the type of cancelation to perform. + * "how" is a bitmask describing the type of cancellation to perform. * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this * socket. * @@ -526,7 +440,7 @@ isc_result_t isc_socket_filter(isc_socket_t *sock, const char *filter); /*%< * Inform the kernel that it should perform accept filtering. - * If filter is NULL the current filter will be removed.:w + * If filter is NULL the current filter will be removed. */ isc_result_t @@ -554,8 +468,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog); */ isc_result_t -isc_socket_accept(isc_socket_t *sock, - isc_task_t *task, isc_taskaction_t action, void *arg); +isc_socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, + void *arg); /*%< * Queue accept event. When a new connection is received, the task will * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen @@ -578,8 +492,7 @@ isc_socket_accept(isc_socket_t *sock, isc_result_t isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addressp, - isc_task_t *task, isc_taskaction_t action, - void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Connect 'socket' to peer with address *saddr. When the connection * succeeds, or when an error occurs, a CONNECT event with action 'action' @@ -644,14 +557,13 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp); /*@{*/ isc_result_t -isc_socket_recv(isc_socket_t *sock, isc_region_t *region, - unsigned int minimum, +isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t -isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, - unsigned int minimum, isc_task_t *task, - isc_socketevent_t *event, unsigned int flags); +isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, + isc_task_t *task, isc_socketevent_t *event, + unsigned int flags); /*! * Receive from 'socket', storing the results in region. @@ -723,15 +635,14 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, /*@{*/ isc_result_t -isc_socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg); +isc_socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg); isc_result_t -isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg, +isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg, const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t -isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, +isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags); @@ -805,8 +716,7 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, /*@}*/ isc_result_t -isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - isc_socketmgr_t **managerp); +isc_socketmgr_createinctx(isc_mem_t *mctx, isc_socketmgr_t **managerp); isc_result_t isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp); @@ -933,9 +843,8 @@ isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp); */ isc_socketevent_t * -isc_socket_socketevent(isc_mem_t *mctx, void *sender, - isc_eventtype_t eventtype, isc_taskaction_t action, - void *arg); +isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, + isc_taskaction_t action, void *arg); /*%< * Get a isc_socketevent_t to be used with isc_socket_sendto2(), etc. */ @@ -976,24 +885,28 @@ isc_socket_permunix(const isc_sockaddr_t *sockaddr, uint32_t perm, * \li #ISC_R_FAILURE */ -void isc_socket_setname(isc_socket_t *socket, const char *name, void *tag); +void +isc_socket_setname(isc_socket_t *socket, const char *name, void *tag); /*%< * Set the name and optional tag for a socket. This allows tracking of the * owner or purpose for this socket, and is useful for tracing and statistics * reporting. */ -const char *isc_socket_getname(isc_socket_t *socket); +const char * +isc_socket_getname(isc_socket_t *socket); /*%< * Get the name associated with a socket, if any. */ -void *isc_socket_gettag(isc_socket_t *socket); +void * +isc_socket_gettag(isc_socket_t *socket); /*%< * Get the tag associated with a socket, if any. */ -int isc_socket_getfd(isc_socket_t *socket); +int +isc_socket_getfd(isc_socket_t *socket); /*%< * Get the file descriptor associated with a socket */ @@ -1005,7 +918,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *mgr, uint32_t); */ void -isc_socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp); +isc_socketmgr_maxudp(isc_socketmgr_t *mgr, unsigned int maxudp); /*%< * Test interface. Drop UDP packet > 'maxudp'. */ @@ -1018,25 +931,25 @@ isc_socket_hasreuseport(void); #ifdef HAVE_LIBXML2 int -isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer); +isc_socketmgr_renderxml(isc_socketmgr_t *mgr, void *writer0); /*%< * Render internal statistics and other state into the XML document. */ #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C isc_result_t -isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats); +isc_socketmgr_renderjson(isc_socketmgr_t *mgr, void *stats0); /*%< * Render internal statistics and other state into JSON format. */ -#endif /* HAVE_JSON */ +#endif /* HAVE_JSON_C */ /*%< * See isc_socketmgr_create() above. */ -typedef isc_result_t -(*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp); +typedef isc_result_t (*isc_socketmgrcreatefunc_t)(isc_mem_t * mctx, + isc_socketmgr_t **managerp); ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/stats.h b/lib/isc/include/isc/stats.h index 8f41bb95..c2ab4e6c 100644 --- a/lib/isc/include/isc/stats.h +++ b/lib/isc/include/isc/stats.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STATS_H #define ISC_STATS_H 1 @@ -19,12 +18,96 @@ #include <isc/types.h> +/*% + * Statistics counters. Used as isc_statscounter_t values. + */ +enum { + /*% + * Socket statistics counters. + */ + isc_sockstatscounter_udp4open = 0, + isc_sockstatscounter_udp6open = 1, + isc_sockstatscounter_tcp4open = 2, + isc_sockstatscounter_tcp6open = 3, + isc_sockstatscounter_unixopen = 4, + + isc_sockstatscounter_udp4openfail = 5, + isc_sockstatscounter_udp6openfail = 6, + isc_sockstatscounter_tcp4openfail = 7, + isc_sockstatscounter_tcp6openfail = 8, + isc_sockstatscounter_unixopenfail = 9, + + isc_sockstatscounter_udp4close = 10, + isc_sockstatscounter_udp6close = 11, + isc_sockstatscounter_tcp4close = 12, + isc_sockstatscounter_tcp6close = 13, + isc_sockstatscounter_unixclose = 14, + isc_sockstatscounter_fdwatchclose = 15, + + isc_sockstatscounter_udp4bindfail = 16, + isc_sockstatscounter_udp6bindfail = 17, + isc_sockstatscounter_tcp4bindfail = 18, + isc_sockstatscounter_tcp6bindfail = 19, + isc_sockstatscounter_unixbindfail = 20, + isc_sockstatscounter_fdwatchbindfail = 21, + + isc_sockstatscounter_udp4connect = 22, + isc_sockstatscounter_udp6connect = 23, + isc_sockstatscounter_tcp4connect = 24, + isc_sockstatscounter_tcp6connect = 25, + isc_sockstatscounter_unixconnect = 26, + isc_sockstatscounter_fdwatchconnect = 27, + + isc_sockstatscounter_udp4connectfail = 28, + isc_sockstatscounter_udp6connectfail = 29, + isc_sockstatscounter_tcp4connectfail = 30, + isc_sockstatscounter_tcp6connectfail = 31, + isc_sockstatscounter_unixconnectfail = 32, + isc_sockstatscounter_fdwatchconnectfail = 33, + + isc_sockstatscounter_tcp4accept = 34, + isc_sockstatscounter_tcp6accept = 35, + isc_sockstatscounter_unixaccept = 36, + + isc_sockstatscounter_tcp4acceptfail = 37, + isc_sockstatscounter_tcp6acceptfail = 38, + isc_sockstatscounter_unixacceptfail = 39, + + isc_sockstatscounter_udp4sendfail = 40, + isc_sockstatscounter_udp6sendfail = 41, + isc_sockstatscounter_tcp4sendfail = 42, + isc_sockstatscounter_tcp6sendfail = 43, + isc_sockstatscounter_unixsendfail = 44, + isc_sockstatscounter_fdwatchsendfail = 45, + + isc_sockstatscounter_udp4recvfail = 46, + isc_sockstatscounter_udp6recvfail = 47, + isc_sockstatscounter_tcp4recvfail = 48, + isc_sockstatscounter_tcp6recvfail = 49, + isc_sockstatscounter_unixrecvfail = 50, + isc_sockstatscounter_fdwatchrecvfail = 51, + + isc_sockstatscounter_udp4active = 52, + isc_sockstatscounter_udp6active = 53, + isc_sockstatscounter_tcp4active = 54, + isc_sockstatscounter_tcp6active = 55, + isc_sockstatscounter_unixactive = 56, + + isc_sockstatscounter_rawopen = 57, + isc_sockstatscounter_rawopenfail = 58, + isc_sockstatscounter_rawclose = 59, + isc_sockstatscounter_rawrecvfail = 60, + isc_sockstatscounter_rawactive = 61, + + isc_sockstatscounter_max = 62 +}; + ISC_LANG_BEGINDECLS /*%< * Flag(s) for isc_stats_dump(). */ -#define ISC_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */ +#define ISC_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */ /*%< * Dump callback type. @@ -113,23 +196,46 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg, */ void -isc_stats_set(isc_stats_t *stats, uint64_t val, - isc_statscounter_t counter); +isc_stats_set(isc_stats_t *stats, uint64_t val, isc_statscounter_t counter); /*%< - * Set the given counter to the specfied value. + * Set the given counter to the specified value. * * Requires: *\li 'stats' is a valid isc_stats_t. */ void -isc_stats_set(isc_stats_t *stats, uint64_t val, - isc_statscounter_t counter); +isc_stats_set(isc_stats_t *stats, uint64_t val, isc_statscounter_t counter); +/*%< + * Set the given counter to the specified value. + * + * Requires: + *\li 'stats' is a valid isc_stats_t. + */ + +void +isc_stats_update_if_greater(isc_stats_t *stats, isc_statscounter_t counter, + isc_statscounter_t value); +/*%< + * Atomically assigns 'value' to 'counter' if value > counter. + * + * Requires: + *\li 'stats' is a valid isc_stats_t. + * + *\li counter is less than the maximum available ID for the stats specified + * on creation. + */ + +isc_statscounter_t +isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter); /*%< - * Set the given counter to the specfied value. + * Returns value currently stored in counter. * * Requires: *\li 'stats' is a valid isc_stats_t. + * + *\li counter is less than the maximum available ID for the stats specified + * on creation. */ ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/stdio.h b/lib/isc/include/isc/stdio.h index 1f44b5ac..0f0daba2 100644 --- a/lib/isc/include/isc/stdio.h +++ b/lib/isc/include/isc/stdio.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STDIO_H #define ISC_STDIO_H 1 @@ -49,8 +48,7 @@ isc_stdio_tell(FILE *f, off_t *offsetp); /*% Read */ isc_result_t -isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, - size_t *nret); +isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret); /*% Write */ isc_result_t diff --git a/lib/isc/include/isc/strerr.h b/lib/isc/include/isc/strerr.h index 1d168197..eebba510 100644 --- a/lib/isc/include/isc/strerr.h +++ b/lib/isc/include/isc/strerr.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,9 +13,9 @@ /*! \file isc/strerr.h */ -#include <string.h> +#include <isc/string.h> #if defined(strerror_r) #undef strerror_r -#endif +#endif /* if defined(strerror_r) */ #define strerror_r isc_string_strerror_r diff --git a/lib/isc/include/isc/string.h b/lib/isc/include/isc/string.h index 309b1277..2c187ff3 100644 --- a/lib/isc/include/isc/string.h +++ b/lib/isc/include/isc/string.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -15,8 +15,8 @@ #include <string.h> -#include "isc/platform.h" #include "isc/lang.h" +#include "isc/platform.h" ISC_LANG_BEGINDECLS @@ -28,7 +28,7 @@ strlcpy(char *dst, const char *src, size_t size); #if !defined(HAVE_STRLCAT) size_t strlcat(char *dst, const char *src, size_t size); -#endif +#endif /* if !defined(HAVE_STRLCAT) */ int isc_string_strerror_r(int errnum, char *buf, size_t buflen); diff --git a/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h index 0f53b5e2..ed85d798 100644 --- a/lib/isc/include/isc/symtab.h +++ b/lib/isc/include/isc/symtab.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SYMTAB_H #define ISC_SYMTAB_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/symtab.h * \brief Provides a simple memory-based symbol table. @@ -88,19 +87,19 @@ ***/ /*% Symbol table value. */ typedef union isc_symvalue { - void * as_pointer; - const void * as_cpointer; - int as_integer; - unsigned int as_uinteger; + void * as_pointer; + const void * as_cpointer; + int as_integer; + unsigned int as_uinteger; } isc_symvalue_t; typedef void (*isc_symtabaction_t)(char *key, unsigned int type, isc_symvalue_t value, void *userarg); /*% Symbol table exists. */ typedef enum { - isc_symexists_reject = 0, /*%< Disallow the define */ - isc_symexists_replace = 1, /*%< Replace the old value with the new */ - isc_symexists_add = 2 /*%< Add the new tuple */ + isc_symexists_reject = 0, /*%< Disallow the define */ + isc_symexists_replace = 1, /*%< Replace the old value with the new */ + isc_symexists_add = 2 /*%< Add the new tuple */ } isc_symexists_t; ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index b2d9c483..397d1150 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -3,24 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_TASK_H #define ISC_TASK_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/task.h * \brief The task system provides a lightweight execution context, which is * basically an event queue. - + * * When a task's event queue is non-empty, the * task is runnable. A small work crew of threads, typically one per CPU, * execute runnable tasks by dispatching the events on the tasks' event @@ -68,7 +67,6 @@ * unsend events which they have sent. */ - /*** *** Imports. ***/ @@ -76,20 +74,19 @@ #include <stdbool.h> #include <isc/eventclass.h> -#include <isc/json.h> #include <isc/lang.h> +#include <isc/netmgr.h> #include <isc/stdtime.h> #include <isc/types.h> -#include <isc/xml.h> -#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) -#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) -#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) -#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535) +#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) +#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) +#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) +#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535) /***** - ***** Tasks. - *****/ +***** Tasks. +*****/ ISC_LANG_BEGINDECLS @@ -98,8 +95,8 @@ ISC_LANG_BEGINDECLS ***/ typedef enum { - isc_taskmgrmode_normal = 0, - isc_taskmgrmode_privileged + isc_taskmgrmode_normal = 0, + isc_taskmgrmode_privileged } isc_taskmgrmode_t; /*% @@ -112,26 +109,25 @@ typedef enum { * all task invariants. */ struct isc_taskmgr { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g') -#define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \ - (m)->magic == ISCAPI_TASKMGR_MAGIC) +#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A', 't', 'm', 'g') +#define ISCAPI_TASKMGR_VALID(m) \ + ((m) != NULL && (m)->magic == ISCAPI_TASKMGR_MAGIC) /*% * This is the common prefix of a task object. The same note as * that for the taskmgr structure applies. */ struct isc_task { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t') -#define ISCAPI_TASK_VALID(s) ((s) != NULL && \ - (s)->magic == ISCAPI_TASK_MAGIC) +#define ISCAPI_TASK_MAGIC ISC_MAGIC('A', 't', 's', 't') +#define ISCAPI_TASK_VALID(s) ((s) != NULL && (s)->magic == ISCAPI_TASK_MAGIC) isc_result_t isc_task_create(isc_taskmgr_t *manager, unsigned int quantum, @@ -259,7 +255,6 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp); * all resources used by the task will be freed. */ - unsigned int isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag); @@ -287,8 +282,7 @@ isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, */ unsigned int -isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, - void *tag); +isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag); /*%< * Purge events from a task's event queue. * @@ -379,8 +373,8 @@ isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, */ unsigned int -isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, - void *tag, isc_eventlist_t *events); +isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, + isc_eventlist_t *events); /*%< * Remove events from a task's event queue. * @@ -410,8 +404,7 @@ isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, */ isc_result_t -isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, - void *arg); +isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Send a shutdown event with action 'action' and argument 'arg' when * 'task' is shutdown. @@ -431,7 +424,7 @@ isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, *\li When the task is shutdown, shutdown events requested with * isc_task_onshutdown() will be appended to the task's event queue. * - + * * Returns: * *\li #ISC_R_SUCCESS @@ -546,6 +539,8 @@ isc_task_beginexclusive(isc_task_t *task); * task. Waits for any other concurrently executing tasks to finish their * current event, and prevents any new events from executing in any of the * tasks sharing a task manager with 'task'. + * It also pauses processing of network events in netmgr if it was provided + * when taskmgr was created. * * The exclusive access must be relinquished by calling * isc_task_endexclusive() before returning from the current event handler. @@ -571,6 +566,22 @@ isc_task_endexclusive(isc_task_t *task); */ void +isc_task_pause(isc_task_t *task0); +void +isc_task_unpause(isc_task_t *task0); +/*%< + * Pause/unpause this task. Pausing a task removes it from the ready + * queue if it is present there; this ensures that the task will not + * run again until unpaused. This is necessary when the libuv network + * thread executes a function which schedules task manager events; this + * prevents the task manager from executing the next event in a task + * before the network thread has finished. + * + * Requires: + *\li 'task' is a valid task, and is not already paused or shutting down. + */ + +void isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t); void isc_task_getcurrenttimex(isc_task_t *task, isc_time_t *t); @@ -626,16 +637,16 @@ isc_task_privilege(isc_task_t *task); */ /***** - ***** Task Manager. - *****/ +***** Task Manager. +*****/ isc_result_t -isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - unsigned int workers, unsigned int default_quantum, - isc_taskmgr_t **managerp); +isc_taskmgr_createinctx(isc_mem_t *mctx, unsigned int workers, + unsigned int default_quantum, isc_taskmgr_t **managerp); isc_result_t isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, - unsigned int default_quantum, isc_taskmgr_t **managerp); + unsigned int default_quantum, isc_nm_t *nm, + isc_taskmgr_t **managerp); /*%< * Create a new task manager. isc_taskmgr_createinctx() also associates * the new manager with the specified application context. @@ -652,6 +663,9 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, * quantum value when tasks are created. If zero, then an implementation * defined default quantum will be used. * + *\li If 'nm' is set then netmgr is paused when an exclusive task mode + * is requested. + * * Requires: * *\li 'mctx' is a valid memory context. @@ -756,20 +770,19 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp); * * Requires: *\li 'manager' is a valid task manager. - + * *\li taskp != NULL && *taskp == NULL */ - #ifdef HAVE_LIBXML2 int -isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer); -#endif +isc_taskmgr_renderxml(isc_taskmgr_t *mgr, void *writer0); +#endif /* ifdef HAVE_LIBXML2 */ -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C isc_result_t -isc_taskmgr_renderjson(isc_taskmgr_t *mgr, json_object *tasksobj); -#endif +isc_taskmgr_renderjson(isc_taskmgr_t *mgr, void *tasksobj0); +#endif /* HAVE_JSON_C */ ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/taskpool.h b/lib/isc/include/isc/taskpool.h index 32ca594b..5a468bf8 100644 --- a/lib/isc/include/isc/taskpool.h +++ b/lib/isc/include/isc/taskpool.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_TASKPOOL_H #define ISC_TASKPOOL_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/taskpool.h * \brief A task pool is a mechanism for sharing a small number of tasks @@ -29,7 +28,6 @@ * could result from creating a separate task for each object. */ - /*** *** Imports. ***/ @@ -42,19 +40,18 @@ ISC_LANG_BEGINDECLS /***** - ***** Types. - *****/ +***** Types. +*****/ typedef struct isc_taskpool isc_taskpool_t; /***** - ***** Functions. - *****/ +***** Functions. +*****/ isc_result_t -isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, - unsigned int ntasks, unsigned int quantum, - isc_taskpool_t **poolp); +isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, + unsigned int quantum, isc_taskpool_t **poolp); /*%< * Create a task pool of "ntasks" tasks, each with quantum * "quantum". @@ -94,7 +91,7 @@ isc_taskpool_size(isc_taskpool_t *pool); isc_result_t isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, - isc_taskpool_t **targetp); + isc_taskpool_t **targetp); /*%< * If 'size' is larger than the number of tasks in the pool pointed to by diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index c8f31d9d..a31a0c47 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_TIMER_H #define ISC_TIMER_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file isc/timer.h * \brief Provides timers which are event sources in the task system. @@ -60,18 +59,17 @@ * None. */ - /*** *** Imports ***/ #include <stdbool.h> -#include <isc/types.h> #include <isc/event.h> #include <isc/eventclass.h> #include <isc/lang.h> #include <isc/time.h> +#include <isc/types.h> ISC_LANG_BEGINDECLS @@ -81,23 +79,23 @@ ISC_LANG_BEGINDECLS /*% Timer Type */ typedef enum { - isc_timertype_undefined = -1, /*%< Undefined */ - isc_timertype_ticker = 0, /*%< Ticker */ - isc_timertype_once = 1, /*%< Once */ - isc_timertype_limited = 2, /*%< Limited */ - isc_timertype_inactive = 3 /*%< Inactive */ + isc_timertype_undefined = -1, /*%< Undefined */ + isc_timertype_ticker = 0, /*%< Ticker */ + isc_timertype_once = 1, /*%< Once */ + isc_timertype_limited = 2, /*%< Limited */ + isc_timertype_inactive = 3 /*%< Inactive */ } isc_timertype_t; typedef struct isc_timerevent { - struct isc_event common; - isc_time_t due; + struct isc_event common; + isc_time_t due; } isc_timerevent_t; -#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0) -#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1) -#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2) -#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3) -#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535) +#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0) +#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1) +#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2) +#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3) +#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535) /*% * This structure is actually just the common prefix of a timer manager @@ -109,26 +107,25 @@ typedef struct isc_timerevent { * all timer invariants. */ struct isc_timermgr { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g') -#define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \ - (m)->magic == ISCAPI_TIMERMGR_MAGIC) +#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A', 't', 'm', 'g') +#define ISCAPI_TIMERMGR_VALID(m) \ + ((m) != NULL && (m)->magic == ISCAPI_TIMERMGR_MAGIC) /*% * This is the common prefix of a timer object. The same note as * that for the timermgr structure applies. */ struct isc_timer { - unsigned int impmagic; - unsigned int magic; + unsigned int impmagic; + unsigned int magic; }; -#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r') -#define ISCAPI_TIMER_VALID(s) ((s) != NULL && \ - (s)->magic == ISCAPI_TIMER_MAGIC) +#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A', 't', 'm', 'r') +#define ISCAPI_TIMER_VALID(s) ((s) != NULL && (s)->magic == ISCAPI_TIMER_MAGIC) /*** *** Timer and Timer Manager Functions @@ -138,13 +135,9 @@ struct isc_timer { ***/ isc_result_t -isc_timer_create(isc_timermgr_t *manager, - isc_timertype_t type, - const isc_time_t *expires, - const isc_interval_t *interval, - isc_task_t *task, - isc_taskaction_t action, - void *arg, +isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, + const isc_time_t *expires, const isc_interval_t *interval, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp); /*%< * Create a new 'type' timer managed by 'manager'. The timers parameters @@ -202,10 +195,8 @@ isc_timer_create(isc_timermgr_t *manager, */ isc_result_t -isc_timer_reset(isc_timer_t *timer, - isc_timertype_t type, - const isc_time_t *expires, - const isc_interval_t *interval, +isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, + const isc_time_t *expires, const isc_interval_t *interval, bool purge); /*%< * Change the timer's type, expires, and interval values to the given @@ -316,8 +307,7 @@ isc_timer_gettype(isc_timer_t *timer); */ isc_result_t -isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - isc_timermgr_t **managerp); +isc_timermgr_createinctx(isc_mem_t *mctx, isc_timermgr_t **managerp); isc_result_t isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp); @@ -371,7 +361,8 @@ isc_timermgr_destroy(isc_timermgr_t **managerp); *\li All resources used by the manager have been freed. */ -void isc_timermgr_poke(isc_timermgr_t *m); +void +isc_timermgr_poke(isc_timermgr_t *m); ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/tm.h b/lib/isc/include/isc/tm.h index b6f520cf..021389c1 100644 --- a/lib/isc/include/isc/tm.h +++ b/lib/isc/include/isc/tm.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -20,7 +20,6 @@ #include <isc/lang.h> #include <isc/types.h> - ISC_LANG_BEGINDECLS time_t diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h index f8e5ae6a..a6cfc2a6 100644 --- a/lib/isc/include/isc/types.h +++ b/lib/isc/include/isc/types.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -20,6 +20,7 @@ */ #include <inttypes.h> #include <stdbool.h> + #include <isc/offset.h> /* @@ -30,74 +31,83 @@ /* Core Types. Alphabetized by defined type. */ -typedef struct isc_appctx isc_appctx_t; /*%< Application context */ -typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */ -typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ -typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ -typedef struct isc_constregion isc_constregion_t; /*%< Const region */ -typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */ -typedef struct isc_counter isc_counter_t; /*%< Counter */ -typedef int16_t isc_dscp_t; /*%< Diffserv code point */ -typedef struct isc_event isc_event_t; /*%< Event */ -typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */ -typedef unsigned int isc_eventtype_t; /*%< Event Type */ -typedef uint32_t isc_fsaccess_t; /*%< FS Access */ -typedef struct isc_hash isc_hash_t; /*%< Hash */ -typedef struct isc_httpd isc_httpd_t; /*%< HTTP client */ -typedef void (isc_httpdfree_t)(isc_buffer_t *, void *); /*%< HTTP free function */ -typedef struct isc_httpdmgr isc_httpdmgr_t; /*%< HTTP manager */ -typedef struct isc_httpdurl isc_httpdurl_t; /*%< HTTP URL */ -typedef void (isc_httpdondestroy_t)(void *); /*%< Callback on destroying httpd */ -typedef struct isc_interface isc_interface_t; /*%< Interface */ -typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */ -typedef struct isc_interval isc_interval_t; /*%< Interval */ -typedef struct isc_lex isc_lex_t; /*%< Lex */ -typedef struct isc_log isc_log_t; /*%< Log */ -typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */ -typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */ -typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */ -typedef struct isc_mem isc_mem_t; /*%< Memory */ -typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */ -typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */ -typedef struct isc_portset isc_portset_t; /*%< Port Set */ -typedef struct isc_quota isc_quota_t; /*%< Quota */ -typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */ -typedef struct isc_region isc_region_t; /*%< Region */ -typedef uint64_t isc_resourcevalue_t; /*%< Resource Value */ -typedef unsigned int isc_result_t; /*%< Result */ -typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */ -typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */ -typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t; /*%< Socket Address List */ -typedef struct isc_socket isc_socket_t; /*%< Socket */ -typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */ -typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */ -typedef struct isc_stats isc_stats_t; /*%< Statistics */ -typedef int isc_statscounter_t; /*%< Statistics Counter */ -typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */ -typedef struct isc_task isc_task_t; /*%< Task */ -typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */ -typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */ -typedef struct isc_textregion isc_textregion_t; /*%< Text Region */ -typedef struct isc_time isc_time_t; /*%< Time */ -typedef struct isc_timer isc_timer_t; /*%< Timer */ -typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */ +typedef struct isc_astack isc_astack_t; /*%< Array-based fast stack */ +typedef struct isc_appctx isc_appctx_t; /*%< Application context */ +typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table + * Entry */ +typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ +typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ +typedef struct isc_constregion isc_constregion_t; /*%< Const region */ +typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region + */ +typedef struct isc_counter isc_counter_t; /*%< Counter */ +typedef int16_t isc_dscp_t; /*%< Diffserv code point */ +typedef struct isc_event isc_event_t; /*%< Event */ +typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */ +typedef unsigned int isc_eventtype_t; /*%< Event Type */ +typedef uint32_t isc_fsaccess_t; /*%< FS Access */ +typedef struct isc_hash isc_hash_t; /*%< Hash */ +typedef struct isc_hp isc_hp_t; /*%< Hazard + * pointer */ +typedef struct isc_httpd isc_httpd_t; /*%< HTTP client */ +typedef void(isc_httpdfree_t)(isc_buffer_t *, void *); /*%< HTTP free function + */ +typedef struct isc_httpdmgr isc_httpdmgr_t; /*%< HTTP manager */ +typedef struct isc_httpdurl isc_httpdurl_t; /*%< HTTP URL */ +typedef void(isc_httpdondestroy_t)(void *); /*%< Callback on destroying httpd */ +typedef struct isc_interface isc_interface_t; /*%< Interface */ +typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */ +typedef struct isc_interval isc_interval_t; /*%< Interval */ +typedef struct isc_lex isc_lex_t; /*%< Lex */ +typedef struct isc_log isc_log_t; /*%< Log */ +typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */ +typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */ +typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */ +typedef struct isc_mem isc_mem_t; /*%< Memory */ +typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */ +typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */ +typedef struct isc_nm isc_nm_t; /*%< Network manager */ +typedef struct isc_nmsocket isc_nmsocket_t; /*%< Network manager socket */ +typedef struct isc_nmiface isc_nmiface_t; /*%< Network manager interface. */ +typedef struct isc_nmhandle isc_nmhandle_t; /*%< Network manager handle */ +typedef struct isc_portset isc_portset_t; /*%< Port Set */ +typedef struct isc_quota isc_quota_t; /*%< Quota */ +typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */ +typedef struct isc_region isc_region_t; /*%< Region */ +typedef uint64_t isc_resourcevalue_t; /*%< Resource Value */ +typedef unsigned int isc_result_t; /*%< Result */ +typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */ +typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */ +typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t; /*%< Socket Address List + * */ +typedef struct isc_socket isc_socket_t; /*%< Socket */ +typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */ +typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */ +typedef struct isc_stats isc_stats_t; /*%< Statistics */ +#if defined(_WIN32) && !defined(_WIN64) +typedef int_fast32_t isc_statscounter_t; /*%< Statistics Counter */ +#else /* if defined(_WIN32) && !defined(_WIN64) */ +typedef int_fast64_t isc_statscounter_t; +#endif /* if defined(_WIN32) && !defined(_WIN64) */ +typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */ +typedef struct isc_task isc_task_t; /*%< Task */ +typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */ +typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */ +typedef struct isc_textregion isc_textregion_t; /*%< Text Region */ +typedef struct isc_time isc_time_t; /*%< Time */ +typedef struct isc_timer isc_timer_t; /*%< Timer */ +typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */ typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *); typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int); /* The following cannot be listed alphabetically due to forward reference */ -typedef isc_result_t (isc_httpdaction_t)(const char *url, - isc_httpdurl_t *urlinfo, - const char *querystring, - const char *headers, - void *arg, - unsigned int *retcode, - const char **retmsg, - const char **mimetype, - isc_buffer_t *body, - isc_httpdfree_t **freecb, - void **freecb_args); -typedef bool (isc_httpdclientok_t)(const isc_sockaddr_t *, void *); +typedef isc_result_t(isc_httpdaction_t)( + const char *url, isc_httpdurl_t *urlinfo, const char *querystring, + const char *headers, void *arg, unsigned int *retcode, + const char **retmsg, const char **mimetype, isc_buffer_t *body, + isc_httpdfree_t **freecb, void **freecb_args); +typedef bool(isc_httpdclientok_t)(const isc_sockaddr_t *, void *); /*% Resource */ typedef enum { diff --git a/lib/isc/include/isc/utf8.h b/lib/isc/include/isc/utf8.h new file mode 100644 index 00000000..42bc0ab4 --- /dev/null +++ b/lib/isc/include/isc/utf8.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +/*! \file isc/utf8.h */ + +#pragma once + +#include <isc/lang.h> +#include <isc/types.h> + +ISC_LANG_BEGINDECLS + +bool +isc_utf8_bom(const unsigned char *buf, size_t len); +/*< + * Returns 'true' if the string of bytes in 'buf' starts + * with an UTF-8 Byte Order Mark. + * + * Requires: + *\li 'buf' != NULL + */ + +bool +isc_utf8_valid(const unsigned char *buf, size_t len); +/*< + * Returns 'true' if the string of bytes in 'buf' is a valid UTF-8 + * byte sequence otherwise 'false' is returned. + * + * Requires: + *\li 'buf' != NULL + */ + +ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h index 4dfe1d77..8941ec12 100644 --- a/lib/isc/include/isc/util.h +++ b/lib/isc/include/isc/util.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -40,15 +40,21 @@ * } * \endcode */ -#define UNUSED(x) (void)(x) +#define UNUSED(x) (void)(x) + +#if __GNUC__ >= 8 && !defined(__clang__) +#define ISC_NONSTRING __attribute__((nonstring)) +#else /* if __GNUC__ >= 8 && !defined(__clang__) */ +#define ISC_NONSTRING +#endif /* __GNUC__ */ /*% * The opposite: silent warnings about stored values which are never read. */ -#define POST(x) (void)(x) +#define POST(x) (void)(x) -#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) #define ISC_CLAMP(v, x, y) ((v) < (x) ? (x) : ((v) > (y) ? (y) : (v))) @@ -60,13 +66,18 @@ * (as with gcc -Wcast-qual) when there is just no other good way to avoid the * situation. */ -#define DE_CONST(konst, var) \ - do { \ - union { const void *k; void *v; } _u; \ - _u.k = konst; \ - var = _u.v; \ +#define DE_CONST(konst, var) \ + do { \ + union { \ + const void *k; \ + void * v; \ + } _u; \ + _u.k = konst; \ + var = _u.v; \ } while (0) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + /*% * Use this in translation units that would otherwise be empty, to * suppress compiler warnings. @@ -82,44 +93,49 @@ #ifdef ISC_UTIL_TRACEON #define ISC_UTIL_TRACE(a) a -#include <stdio.h> /* Required for fprintf/stderr when tracing. */ -#else +#include <stdio.h> /* Required for fprintf/stderr when tracing. */ +#else /* ifdef ISC_UTIL_TRACEON */ #define ISC_UTIL_TRACE(a) -#endif +#endif /* ifdef ISC_UTIL_TRACEON */ -#include <isc/result.h> /* Contractual promise. */ +#include <isc/result.h> /* Contractual promise. */ -#define LOCK(lp) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "LOCKING %p %s %d\n", \ - (lp), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ - ISC_UTIL_TRACE(fprintf(stderr, "LOCKED %p %s %d\n", \ - (lp), __FILE__, __LINE__)); \ +#define LOCK(lp) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "LOCKING %p %s %d\n", (lp), \ + __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ + ISC_UTIL_TRACE(fprintf(stderr, "LOCKED %p %s %d\n", (lp), \ + __FILE__, __LINE__)); \ } while (0) -#define UNLOCK(lp) do { \ - RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ - ISC_UTIL_TRACE(fprintf(stderr, "UNLOCKED %p %s %d\n", \ - (lp), __FILE__, __LINE__)); \ +#define UNLOCK(lp) \ + do { \ + RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ + ISC_UTIL_TRACE(fprintf(stderr, "UNLOCKED %p %s %d\n", (lp), \ + __FILE__, __LINE__)); \ } while (0) -#define BROADCAST(cvp) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "BROADCAST %p %s %d\n", \ - (cvp), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \ +#define BROADCAST(cvp) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "BROADCAST %p %s %d\n", (cvp), \ + __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_condition_broadcast((cvp)) == \ + ISC_R_SUCCESS); \ } while (0) -#define SIGNAL(cvp) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "SIGNAL %p %s %d\n", \ - (cvp), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ +#define SIGNAL(cvp) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "SIGNAL %p %s %d\n", (cvp), \ + __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ } while (0) -#define WAIT(cvp, lp) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "WAIT %p LOCK %p %s %d\n", \ - (cvp), \ - (lp), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \ - ISC_UTIL_TRACE(fprintf(stderr, "WAITED %p LOCKED %p %s %d\n", \ - (cvp), \ - (lp), __FILE__, __LINE__)); \ +#define WAIT(cvp, lp) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "WAIT %p LOCK %p %s %d\n", \ + (cvp), (lp), __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == \ + ISC_R_SUCCESS); \ + ISC_UTIL_TRACE(fprintf(stderr, "WAITED %p LOCKED %p %s %d\n", \ + (cvp), (lp), __FILE__, __LINE__)); \ } while (0) /* @@ -129,44 +145,45 @@ * XXX Also, can't really debug this then... */ -#define WAITUNTIL(cvp, lp, tp) \ - isc_condition_waituntil((cvp), (lp), (tp)) +#define WAITUNTIL(cvp, lp, tp) isc_condition_waituntil((cvp), (lp), (tp)) -#define RWLOCK(lp, t) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "RWLOCK %p, %d %s %d\n", \ - (lp), (t), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ - ISC_UTIL_TRACE(fprintf(stderr, "RWLOCKED %p, %d %s %d\n", \ - (lp), (t), __FILE__, __LINE__)); \ +#define RWLOCK(lp, t) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "RWLOCK %p, %d %s %d\n", (lp), \ + (t), __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ + ISC_UTIL_TRACE(fprintf(stderr, "RWLOCKED %p, %d %s %d\n", \ + (lp), (t), __FILE__, __LINE__)); \ } while (0) -#define RWUNLOCK(lp, t) do { \ - ISC_UTIL_TRACE(fprintf(stderr, "RWUNLOCK %p, %d %s %d\n", \ - (lp), (t), __FILE__, __LINE__)); \ - RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ +#define RWUNLOCK(lp, t) \ + do { \ + ISC_UTIL_TRACE(fprintf(stderr, "RWUNLOCK %p, %d %s %d\n", \ + (lp), (t), __FILE__, __LINE__)); \ + RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ } while (0) /* * List Macros. */ -#include <isc/list.h> /* Contractual promise. */ - -#define LIST(type) ISC_LIST(type) -#define INIT_LIST(type) ISC_LIST_INIT(type) -#define LINK(type) ISC_LINK(type) -#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) -#define HEAD(list) ISC_LIST_HEAD(list) -#define TAIL(list) ISC_LIST_TAIL(list) -#define EMPTY(list) ISC_LIST_EMPTY(list) -#define PREV(elt, link) ISC_LIST_PREV(elt, link) -#define NEXT(elt, link) ISC_LIST_NEXT(elt, link) -#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) -#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) -#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) -#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) -#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) -#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) -#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) -#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) +#include <isc/list.h> /* Contractual promise. */ + +#define LIST(type) ISC_LIST(type) +#define INIT_LIST(type) ISC_LIST_INIT(type) +#define LINK(type) ISC_LINK(type) +#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) +#define HEAD(list) ISC_LIST_HEAD(list) +#define TAIL(list) ISC_LIST_TAIL(list) +#define EMPTY(list) ISC_LIST_EMPTY(list) +#define PREV(elt, link) ISC_LIST_PREV(elt, link) +#define NEXT(elt, link) ISC_LIST_NEXT(elt, link) +#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) +#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) +#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) +#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) +#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) +#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) +#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) +#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) /*% * Performance @@ -175,48 +192,63 @@ #ifdef HAVE_BUILTIN_UNREACHABLE #define ISC_UNREACHABLE() __builtin_unreachable(); -#else +#else /* ifdef HAVE_BUILTIN_UNREACHABLE */ #define ISC_UNREACHABLE() -#endif +#endif /* ifdef HAVE_BUILTIN_UNREACHABLE */ #if !defined(__has_feature) #define __has_feature(x) 0 -#endif +#endif /* if !defined(__has_feature) */ /* GCC defines __SANITIZE_ADDRESS__, so reuse the macro for clang */ #if __has_feature(address_sanitizer) #define __SANITIZE_ADDRESS__ 1 -#endif +#endif /* if __has_feature(address_sanitizer) */ + +#if __has_feature(thread_sanitizer) +#define __SANITIZE_THREAD__ 1 +#endif /* if __has_feature(thread_sanitizer) */ + +#if __SANITIZE_THREAD__ +#define ISC_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread"))) +#else /* if __SANITIZE_THREAD__ */ +#define ISC_NO_SANITIZE_THREAD +#endif /* if __SANITIZE_THREAD__ */ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6) #define STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) #elif __has_feature(c_static_assert) #define STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) -#else +#else /* if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6) */ #define STATIC_ASSERT(cond, msg) INSIST(cond) -#endif +#endif /* if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6) */ #ifdef UNIT_TESTING -extern void mock_assert(const int result, const char* const expression, - const char * const file, const int line); +extern void +mock_assert(const int result, const char *const expression, + const char *const file, const int line); /* * Allow clang to determine that the following code is not reached * by calling abort() if the condition fails. The abort() will * never be executed as mock_assert() and _assert_true() longjmp * or exit if the condition is false. */ -#define REQUIRE(expression) \ - ((!(expression)) ? \ - (mock_assert(0, #expression, __FILE__, __LINE__), abort()) : (void)0) -#define ENSURE(expression) \ - ((!(int)(expression)) ? \ - (mock_assert(0, #expression, __FILE__, __LINE__), abort()) : (void)0) -#define INSIST(expression) \ - ((!(expression)) ? \ - (mock_assert(0, #expression, __FILE__, __LINE__), abort()) : (void)0) -#define INVARIANT(expression) \ - ((!(expression)) ? \ - (mock_assert(0, #expression, __FILE__, __LINE__), abort()) : (void)0) +#define REQUIRE(expression) \ + ((!(expression)) \ + ? (mock_assert(0, #expression, __FILE__, __LINE__), abort()) \ + : (void)0) +#define ENSURE(expression) \ + ((!(int)(expression)) \ + ? (mock_assert(0, #expression, __FILE__, __LINE__), abort()) \ + : (void)0) +#define INSIST(expression) \ + ((!(expression)) \ + ? (mock_assert(0, #expression, __FILE__, __LINE__), abort()) \ + : (void)0) +#define INVARIANT(expression) \ + ((!(expression)) \ + ? (mock_assert(0, #expression, __FILE__, __LINE__), abort()) \ + : (void)0) #define _assert_true(c, e, f, l) \ ((c) ? (void)0 : (_assert_true(0, e, f, l), abort())) #define _assert_int_equal(a, b, f, l) \ @@ -224,57 +256,89 @@ extern void mock_assert(const int result, const char* const expression, #define _assert_int_not_equal(a, b, f, l) \ (((a) != (b)) ? (void)0 : (_assert_int_not_equal(a, b, f, l), abort())) #else /* UNIT_TESTING */ + +#ifndef CPPCHECK + /* * Assertions */ -#include <isc/assertions.h> /* Contractual promise. */ +#include <isc/assertions.h> /* Contractual promise. */ /*% Require Assertion */ -#define REQUIRE(e) ISC_REQUIRE(e) +#define REQUIRE(e) ISC_REQUIRE(e) /*% Ensure Assertion */ -#define ENSURE(e) ISC_ENSURE(e) +#define ENSURE(e) ISC_ENSURE(e) /*% Insist Assertion */ -#define INSIST(e) ISC_INSIST(e) +#define INSIST(e) ISC_INSIST(e) /*% Invariant Assertion */ -#define INVARIANT(e) ISC_INVARIANT(e) +#define INVARIANT(e) ISC_INVARIANT(e) + +#else /* CPPCHECK */ + +/*% Require Assertion */ +#define REQUIRE(e) \ + if (!(e)) \ + abort() +/*% Ensure Assertion */ +#define ENSURE(e) \ + if (!(e)) \ + abort() +/*% Insist Assertion */ +#define INSIST(e) \ + if (!(e)) \ + abort() +/*% Invariant Assertion */ +#define INVARIANT(e) \ + if (!(e)) \ + abort() + +#endif /* CPPCHECK */ #endif /* UNIT_TESTING */ /* * Errors */ -#include <isc/error.h> /* Contractual promise. */ +#include <isc/error.h> /* Contractual promise. */ /*% Unexpected Error */ -#define UNEXPECTED_ERROR isc_error_unexpected +#define UNEXPECTED_ERROR isc_error_unexpected /*% Fatal Error */ -#define FATAL_ERROR isc_error_fatal +#define FATAL_ERROR isc_error_fatal #ifdef UNIT_TESTING -#define RUNTIME_CHECK(expression) \ - mock_assert((int)(expression), #expression, __FILE__, __LINE__) +#define RUNTIME_CHECK(expression) \ + ((!(expression)) \ + ? (mock_assert(0, #expression, __FILE__, __LINE__), abort()) \ + : (void)0) #else /* UNIT_TESTING */ +#ifndef CPPCHECK /*% Runtime Check */ -#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) +#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) +#else /* ifndef CPPCHECK */ +#define RUNTIME_CHECK(e) \ + if (!(e)) \ + abort() +#endif /* ifndef CPPCHECK */ #endif /* UNIT_TESTING */ /*% * Time */ -#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) +#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) /*% * Alignment */ #ifdef __GNUC__ -#define ISC_ALIGN(x, a) (((x) + (a) - 1) & ~((typeof(x))(a) - 1)) -#else -#define ISC_ALIGN(x, a) (((x) + (a) - 1) & ~((uintmax_t)(a) - 1)) -#endif +#define ISC_ALIGN(x, a) (((x) + (a)-1) & ~((typeof(x))(a)-1)) +#else /* ifdef __GNUC__ */ +#define ISC_ALIGN(x, a) (((x) + (a)-1) & ~((uintmax_t)(a)-1)) +#endif /* ifdef __GNUC__ */ /*% * Misc diff --git a/lib/isc/include/isc/version.h b/lib/isc/include/isc/version.h index d371e0d3..6367c8f1 100644 --- a/lib/isc/include/isc/version.h +++ b/lib/isc/include/isc/version.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file isc/version.h */ #include <isc/platform.h> diff --git a/lib/isc/include/isc/xml.h b/lib/isc/include/isc/xml.h deleted file mode 100644 index a091d301..00000000 --- a/lib/isc/include/isc/xml.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef ISC_XML_H -#define ISC_XML_H 1 - -/* - * This file is here mostly to make it easy to add additional libxml header - * files as needed across all the users of this file. Rather than place - * these libxml includes in each file, one include makes it easy to handle - * the ifdef as well as adding the ability to add additional functions - * which may be useful. - */ - -#ifdef HAVE_LIBXML2 -#include <libxml/encoding.h> -#include <libxml/xmlwriter.h> -#endif - -#define ISC_XMLCHAR (const xmlChar *) - -#define ISC_XML_RENDERCONFIG 0x00000001 /* render config data */ -#define ISC_XML_RENDERSTATS 0x00000002 /* render stats */ -#define ISC_XML_RENDERALL 0x000000ff /* render everything */ - -#endif /* ISC_XML_H */ diff --git a/lib/isc/include/pk11/constants.h b/lib/isc/include/pk11/constants.h index 3f16ecbd..48e9a6f5 100644 --- a/lib/isc/include/pk11/constants.h +++ b/lib/isc/include/pk11/constants.h @@ -3,98 +3,33 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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 -#ifndef PK11_CONSTANTS_H -#define PK11_CONSTANTS_H 1 +#include <inttypes.h> /*! \file pk11/constants.h */ /*% - * Static arrays of data used for key template initalization + * Static arrays of data used for key template initialization */ -static CK_BYTE pk11_ecc_prime256v1[] = { - 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 -}; -static CK_BYTE pk11_ecc_secp384r1[] = { - 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 -}; -#if HAVE_PKCS11_ED25519 -static CK_BYTE pk11_ecc_ed25519[] = { - 0x06, 0x03, 0x2b, 0x65, 0x70 -}; -#endif /* HAVE_PKCS11_ED25519 */ -#if HAVE_PKCS11_ED448 -static CK_BYTE pk11_ecc_ed448[] = { - 0x06, 0x03, 0x2b, 0x65, 0x71 -}; -#endif /* HAVE_PKCS11_ED448 */ - -#ifdef WANT_DH_PRIMES -static CK_BYTE pk11_dh_bn2[] = { 2 }; -static CK_BYTE pk11_dh_bn768[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, - 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, - 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, - 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, - 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, - 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, - 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, - 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, - 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, - 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; -static CK_BYTE pk11_dh_bn1024[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, - 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, - 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, - 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, - 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, - 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, - 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, - 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, - 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, - 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, - 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, - 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, - 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, - 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; -static CK_BYTE pk11_dh_bn1536[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, - 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, - 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, - 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, - 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, - 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, - 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, - 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, - 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, - 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, - 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, - 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, - 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, - 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, - 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, - 0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, - 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f, - 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, - 0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, - 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, - 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, - 0xf1, 0x74, 0x6c, 0x08, 0xca, 0x23, 0x73, 0x27, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; -#endif - -#endif /* PK11_CONSTANTS_H */ +#define PK11_ECC_PRIME256V1 \ + (uint8_t[]) { \ + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 \ + } +#define PK11_ECC_SECP384R1 \ + (uint8_t[]) { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 } +#define PK11_ECX_ED25519 \ + (uint8_t[]) { \ + 0x13, 0xc, 'e', 'd', 'w', 'a', 'r', 'd', 's', '2', '5', '5', \ + '1', '9' \ + } +#define PK11_ECX_ED448 \ + (uint8_t[]) { \ + 0x13, 0xa, 'e', 'd', 'w', 'a', 'r', 'd', 's', '4', '4', '8' \ + } diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h index aa8907ab..9c067c56 100644 --- a/lib/isc/include/pk11/internal.h +++ b/lib/isc/include/pk11/internal.h @@ -3,37 +3,44 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef PK11_INTERNAL_H #define PK11_INTERNAL_H 1 /*! \file pk11/internal.h */ +#include <pk11/pk11.h> + ISC_LANG_BEGINDECLS -const char *pk11_get_lib_name(void); +const char * +pk11_get_lib_name(void); -void *pk11_mem_get(size_t size); +void * +pk11_mem_get(size_t size); -void pk11_mem_put(void *ptr, size_t size); +void +pk11_mem_put(void *ptr, size_t size); -CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); +CK_SLOT_ID +pk11_get_best_token(pk11_optype_t optype); -unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); +isc_result_t +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits); -CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj); +CK_ATTRIBUTE * +pk11_attribute_first(const pk11_object_t *obj); -CK_ATTRIBUTE *pk11_attribute_next(const pk11_object_t *obj, - CK_ATTRIBUTE *attr); +CK_ATTRIBUTE * +pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr); -CK_ATTRIBUTE *pk11_attribute_bytype(const pk11_object_t *obj, - CK_ATTRIBUTE_TYPE type); +CK_ATTRIBUTE * +pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type); ISC_LANG_ENDDECLS diff --git a/lib/isc/include/pk11/pk11.h b/lib/isc/include/pk11/pk11.h index 5354d1c3..de955685 100644 --- a/lib/isc/include/pk11/pk11.h +++ b/lib/isc/include/pk11/pk11.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -15,42 +15,43 @@ /*! \file pk11/pk11.h */ #include <stdbool.h> +#include <unistd.h> #include <isc/lang.h> #include <isc/magic.h> #include <isc/types.h> -#define PK11_FATALCHECK(func, args) \ - ((void) (((rv = (func) args) == CKR_OK) || \ - ((pk11_error_fatalcheck)(__FILE__, __LINE__, #func, rv), 0))) +#define PK11_FATALCHECK(func, args) \ + ((void)(((rv = (func)args) == CKR_OK) || \ + ((pk11_error_fatalcheck)(__FILE__, __LINE__, #func, rv), 0))) -#include <pkcs11/cryptoki.h> #include <pk11/site.h> +#include <pkcs11/pkcs11.h> ISC_LANG_BEGINDECLS -#define SES_MAGIC ISC_MAGIC('P','K','S','S') -#define TOK_MAGIC ISC_MAGIC('P','K','T','K') +#define SES_MAGIC ISC_MAGIC('P', 'K', 'S', 'S') +#define TOK_MAGIC ISC_MAGIC('P', 'K', 'T', 'K') -#define VALID_SES(x) ISC_MAGIC_VALID(x, SES_MAGIC) -#define VALID_TOK(x) ISC_MAGIC_VALID(x, TOK_MAGIC) +#define VALID_SES(x) ISC_MAGIC_VALID(x, SES_MAGIC) +#define VALID_TOK(x) ISC_MAGIC_VALID(x, TOK_MAGIC) typedef struct pk11_context pk11_context_t; struct pk11_object { - CK_OBJECT_HANDLE object; - CK_SLOT_ID slot; - CK_BBOOL ontoken; - CK_BBOOL reqlogon; - CK_BYTE attrcnt; - CK_ATTRIBUTE *repr; + CK_OBJECT_HANDLE object; + CK_SLOT_ID slot; + CK_BBOOL ontoken; + CK_BBOOL reqlogon; + CK_BYTE attrcnt; + CK_ATTRIBUTE * repr; }; struct pk11_context { - void *handle; - CK_SESSION_HANDLE session; - CK_BBOOL ontoken; - CK_OBJECT_HANDLE object; + void * handle; + CK_SESSION_HANDLE session; + CK_BBOOL ontoken; + CK_OBJECT_HANDLE object; }; typedef struct pk11_object pk11_object_t; @@ -73,12 +74,14 @@ LIBISC_EXTERNAL_DATA extern bool pk11_verbose_init; * Function prototypes */ -void pk11_set_lib_name(const char *lib_name); +void +pk11_set_lib_name(const char *lib_name); /*%< * Set the PKCS#11 provider (aka library) path/name. */ -isc_result_t pk11_initialize(isc_mem_t *mctx, const char *engine); +isc_result_t +pk11_initialize(isc_mem_t *mctx, const char *engine); /*%< * Initialize PKCS#11 device * @@ -94,13 +97,9 @@ isc_result_t pk11_initialize(isc_mem_t *mctx, const char *engine); * PK11_R_NOAESSERVICE: can't find required AES service */ -isc_result_t pk11_get_session(pk11_context_t *ctx, - pk11_optype_t optype, - bool need_services, - bool rw, - bool logon, - const char *pin, - CK_SLOT_ID slot); +isc_result_t +pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, bool need_services, + bool rw, bool logon, const char *pin, CK_SLOT_ID slot); /*%< * Initialize PKCS#11 device and acquire a session. * @@ -119,30 +118,34 @@ isc_result_t pk11_get_session(pk11_context_t *ctx, * slot: device slot ID */ -void pk11_return_session(pk11_context_t *ctx); +void +pk11_return_session(pk11_context_t *ctx); /*%< * Release an active PKCS#11 session for reuse. */ -isc_result_t pk11_finalize(void); +isc_result_t +pk11_finalize(void); /*%< * Shut down PKCS#11 device and free all sessions. */ -isc_result_t pk11_parse_uri(pk11_object_t *obj, const char *label, - isc_mem_t *mctx, pk11_optype_t optype); +isc_result_t +pk11_parse_uri(pk11_object_t *obj, const char *label, isc_mem_t *mctx, + pk11_optype_t optype); ISC_PLATFORM_NORETURN_PRE void -pk11_error_fatalcheck(const char *file, int line, - const char *funcname, CK_RV rv) -ISC_PLATFORM_NORETURN_POST; +pk11_error_fatalcheck(const char *file, int line, const char *funcname, + CK_RV rv) ISC_PLATFORM_NORETURN_POST; -void pk11_dump_tokens(void); +void +pk11_dump_tokens(void); CK_RV pkcs_C_Initialize(CK_VOID_PTR pReserved); -char *pk11_get_load_error_message(void); +char * +pk11_get_load_error_message(void); CK_RV pkcs_C_Finalize(CK_VOID_PTR pReserved); @@ -159,11 +162,10 @@ pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); CK_RV -pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, - CK_VOID_PTR pApplication, - CK_RV (*Notify) (CK_SESSION_HANDLE hSession, - CK_NOTIFICATION event, - CK_VOID_PTR pApplication), +pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, + CK_RV (*Notify)(CK_SESSION_HANDLE hSession, + CK_NOTIFICATION event, + CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession); CK_RV @@ -227,9 +229,8 @@ pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); CK_RV -pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen); +pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); CK_RV pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, @@ -244,9 +245,8 @@ pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); CK_RV -pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen); +pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); CK_RV pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, @@ -262,12 +262,11 @@ pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE_PTR phKey); CK_RV -pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG usPublicKeyAttributeCount, - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG usPrivateKeyAttributeCount, +pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG usPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey); diff --git a/lib/isc/include/pk11/result.h b/lib/isc/include/pk11/result.h index 21f4a375..6b16ae6d 100644 --- a/lib/isc/include/pk11/result.h +++ b/lib/isc/include/pk11/result.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -16,6 +16,7 @@ #include <isc/lang.h> #include <isc/resultclass.h> +#include <isc/types.h> /* * Nothing in this file truly depends on <isc/result.h>, but the @@ -23,20 +24,19 @@ * the ISC result codes, so including this file buys you the ISC_R_ * namespace too. */ -#include <isc/result.h> /* Contractual promise. */ +#include <isc/result.h> /* Contractual promise. */ -#define PK11_R_INITFAILED (ISC_RESULTCLASS_PK11 + 0) -#define PK11_R_NOPROVIDER (ISC_RESULTCLASS_PK11 + 1) -#define PK11_R_NORANDOMSERVICE (ISC_RESULTCLASS_PK11 + 2) -#define PK11_R_NODIGESTSERVICE (ISC_RESULTCLASS_PK11 + 3) -#define PK11_R_NOAESSERVICE (ISC_RESULTCLASS_PK11 + 4) +#define PK11_R_INITFAILED (ISC_RESULTCLASS_PK11 + 0) +#define PK11_R_NOPROVIDER (ISC_RESULTCLASS_PK11 + 1) +#define PK11_R_NORANDOMSERVICE (ISC_RESULTCLASS_PK11 + 2) +#define PK11_R_NODIGESTSERVICE (ISC_RESULTCLASS_PK11 + 3) +#define PK11_R_NOAESSERVICE (ISC_RESULTCLASS_PK11 + 4) -#define PK11_R_NRESULTS 5 /* Number of results */ +#define PK11_R_NRESULTS 5 /* Number of results */ ISC_LANG_BEGINDECLS -const char * -pk11_result_totext(isc_result_t); +const char *pk11_result_totext(isc_result_t); void pk11_result_register(void); diff --git a/lib/isc/include/pk11/site.h b/lib/isc/include/pk11/site.h index 442ce71c..95f7e9d1 100644 --- a/lib/isc/include/pk11/site.h +++ b/lib/isc/include/pk11/site.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/include/pkcs11/Makefile.in b/lib/isc/include/pkcs11/Makefile.in index 8b442b46..79a15837 100644 --- a/lib/isc/include/pkcs11/Makefile.in +++ b/lib/isc/include/pkcs11/Makefile.in @@ -18,7 +18,7 @@ VERSION=@BIND9_VERSION@ # machine generated. The latter are handled specially in the # install target below. # -HEADERS = pkcs11f.h pkcs11.h pkcs11t.h eddsa.h +HEADERS = pkcs11.h SUBDIRS = TARGETS = diff --git a/lib/isc/include/pkcs11/eddsa.h b/lib/isc/include/pkcs11/eddsa.h deleted file mode 100644 index c0b2e9cd..00000000 --- a/lib/isc/include/pkcs11/eddsa.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef _EDDSA_H_ -#define _EDDSA_H_ 1 - -#ifndef CKK_EDDSA -#ifdef PK11_SOFTHSMV2_FLAVOR -#define CKK_EDDSA 0x00008003UL -#endif -#endif - -#ifndef CKM_EDDSA_KEY_PAIR_GEN -#ifdef PK11_SOFTHSMV2_FLAVOR -#define CKM_EDDSA_KEY_PAIR_GEN 0x00009040UL -#endif -#endif - -#ifndef CKM_EDDSA -#ifdef PK11_SOFTHSMV2_FLAVOR -#define CKM_EDDSA 0x00009041UL -#endif -#endif - -#endif /* _EDDSA_H_ */ diff --git a/lib/isc/include/pkcs11/pkcs11.h b/lib/isc/include/pkcs11/pkcs11.h index c66b0bca..cd565ee6 100644 --- a/lib/isc/include/pkcs11/pkcs11.h +++ b/lib/isc/include/pkcs11/pkcs11.h @@ -1,264 +1,1653 @@ -/* - * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01 - * Committee Specification Draft 01 / Public Review Draft 01 - * 09 December 2015 - * Copyright (c) OASIS Open 2015. All Rights Reserved. - * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/ - * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - * https://www.oasis-open.org/policies-guidelines/ipr - */ - -#ifndef _PKCS11_H_ -#define _PKCS11_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Before including this file (pkcs11.h) (or pkcs11t.h by - * itself), 5 platform-specific macros must be defined. These - * macros are described below, and typical definitions for them - * are also given. Be advised that these definitions can depend - * on both the platform and the compiler used (and possibly also - * on whether a Cryptoki library is linked statically or - * dynamically). - * - * In addition to defining these 5 macros, the packing convention - * for Cryptoki structures should be set. The Cryptoki - * convention on packing is that structures should be 1-byte - * aligned. - * - * If you're using Microsoft Developer Studio 5.0 to produce - * Win32 stuff, this might be done by using the following - * preprocessor directive before including pkcs11.h or pkcs11t.h: - * - * #pragma pack(push, cryptoki, 1) - * - * and using the following preprocessor directive after including - * pkcs11.h or pkcs11t.h: - * - * #pragma pack(pop, cryptoki) - * - * If you're using an earlier version of Microsoft Developer - * Studio to produce Win16 stuff, this might be done by using - * the following preprocessor directive before including - * pkcs11.h or pkcs11t.h: - * - * #pragma pack(1) - * - * In a UNIX environment, you're on your own for this. You might - * not need to do (or be able to do!) anything. - * - * - * Now for the macros: - * - * - * 1. CK_PTR: The indirection string for making a pointer to an - * object. It can be used like this: - * - * typedef CK_BYTE CK_PTR CK_BYTE_PTR; - * - * If you're using Microsoft Developer Studio 5.0 to produce - * Win32 stuff, it might be defined by: - * - * #define CK_PTR * - * - * If you're using an earlier version of Microsoft Developer - * Studio to produce Win16 stuff, it might be defined by: - * - * #define CK_PTR far * - * - * In a typical UNIX environment, it might be defined by: - * - * #define CK_PTR * - * - * - * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes - * an importable Cryptoki library function declaration out of a - * return type and a function name. It should be used in the - * following fashion: - * - * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( - * CK_VOID_PTR pReserved - * ); - * - * If you're using Microsoft Developer Studio 5.0 to declare a - * function in a Win32 Cryptoki .dll, it might be defined by: - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType __declspec(dllimport) name - * - * If you're using an earlier version of Microsoft Developer - * Studio to declare a function in a Win16 Cryptoki .dll, it - * might be defined by: - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType __export _far _pascal name - * - * In a UNIX environment, it might be defined by: +/* pkcs11.h + * Copyright 2006, 2007 g10 Code GmbH + * Copyright 2006 Andreas Jellinghaus + * Copyright 2017 Red Hat, Inc. * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType name + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. */ + +/* Please submit any changes back to the p11-kit project at + * https://github.com/p11-glue/p11-kit/, so that + * they can be picked up by other projects from there as well. */ + +/* This file is a modified implementation of the PKCS #11 standard by + * OASIS group. It is mostly a drop-in replacement, with the + * following change: * - * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro - * which makes a Cryptoki API function pointer declaration or - * function pointer type declaration out of a return type and a - * function name. It should be used in the following fashion: - * - * // Define funcPtr to be a pointer to a Cryptoki API function - * // taking arguments args and returning CK_RV. - * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); - * - * or - * - * // Define funcPtrType to be the type of a pointer to a - * // Cryptoki API function taking arguments args and returning - * // CK_RV, and then define funcPtr to be a variable of type - * // funcPtrType. - * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); - * funcPtrType funcPtr; - * - * If you're using Microsoft Developer Studio 5.0 to access - * functions in a Win32 Cryptoki .dll, in might be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType __declspec(dllimport) (* name) - * - * If you're using an earlier version of Microsoft Developer - * Studio to access functions in a Win16 Cryptoki .dll, it might - * be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType __export _far _pascal (* name) - * - * In a UNIX environment, it might be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType (* name) - * - * - * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes - * a function pointer type for an application callback out of - * a return type for the callback and a name for the callback. - * It should be used in the following fashion: - * - * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); - * - * to declare a function pointer, myCallback, to a callback - * which takes arguments args and returns a CK_RV. It can also - * be used like this: - * - * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); - * myCallbackType myCallback; - * - * If you're using Microsoft Developer Studio 5.0 to do Win32 - * Cryptoki development, it might be defined by: - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) - * - * If you're using an earlier version of Microsoft Developer - * Studio to do Win16 development, it might be defined by: + * This header file does not require any macro definitions by the user + * (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros + * for you (if useful, some are missing, let me know if you need + * more). * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType _far _pascal (* name) + * There is an additional API available that does comply better to the + * GNU coding standard. It can be switched on by defining + * CRYPTOKI_GNU before including this header file. For this, the + * following changes are made to the specification: * - * In a UNIX environment, it might be defined by: + * All structure types are changed to a "struct ck_foo" where CK_FOO + * is the type name in PKCS #11. * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) + * All non-structure types are changed to ck_foo_t where CK_FOO is the + * lowercase version of the type name in PKCS #11. The basic types + * (CK_ULONG et al.) are removed without substitute. * + * All members of structures are modified in the following way: Type + * indication prefixes are removed, and underscore characters are + * inserted before words. Then the result is lowercased. * - * 5. NULL_PTR: This macro is the value of a NULL pointer. + * Note that function names are still in the original case, as they + * need for ABI compatibility. * - * In any ANSI/ISO C environment (and in many others as well), - * this should best be defined by + * CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use + * <stdbool.h>. * - * #ifndef NULL_PTR - * #define NULL_PTR 0 - * #endif - */ + * If CRYPTOKI_COMPAT is defined before including this header file, + * then none of the API changes above take place, and the API is the + * one defined by the PKCS #11 standard. */ + +#ifndef PKCS11_H +#define PKCS11_H 1 + +#if defined(__cplusplus) +extern "C" { +#endif /* if defined(__cplusplus) */ + +/* The version of cryptoki we implement. The revision is changed with + * each modification of this file. */ +#define CRYPTOKI_VERSION_MAJOR 2 +#define CRYPTOKI_VERSION_MINOR 40 +#define P11_KIT_CRYPTOKI_VERSION_REVISION 0 + +/* Compatibility interface is default, unless CRYPTOKI_GNU is + * given. */ +#ifndef CRYPTOKI_GNU +#ifndef CRYPTOKI_COMPAT +#define CRYPTOKI_COMPAT 1 +#endif /* ifndef CRYPTOKI_COMPAT */ +#endif /* ifndef CRYPTOKI_GNU */ + +/* System dependencies. */ + +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) + +/* There is a matching pop below. */ +#pragma pack(push, cryptoki, 1) + +#ifdef CRYPTOKI_EXPORTS +#define CK_SPEC __declspec(dllexport) +#else /* ifdef CRYPTOKI_EXPORTS */ +#define CK_SPEC __declspec(dllimport) +#endif /* ifdef CRYPTOKI_EXPORTS */ +#else /* if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) */ -/* All the various Cryptoki types and #define'd values are in the - * file pkcs11t.h. - */ -#include "pkcs11t.h" +#define CK_SPEC -#define __PASTE(x,y) x##y +#endif /* if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) */ +#ifdef CRYPTOKI_COMPAT +/* If we are in compatibility mode, switch all exposed names to the + * PKCS #11 variant. There are corresponding #undefs below. */ -/* ============================================================== - * Define the "extern" form of all the entry points. - * ============================================================== - */ +#define ck_flags_t CK_FLAGS +#define ck_version _CK_VERSION -#define CK_NEED_ARG_LIST 1 -#define CK_PKCS11_FUNCTION_INFO(name) \ - extern CK_DECLARE_FUNCTION(CK_RV, name) +#define ck_info _CK_INFO +#define cryptoki_version cryptokiVersion +#define manufacturer_id manufacturerID +#define library_description libraryDescription +#define library_version libraryVersion -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" +#define ck_notification_t CK_NOTIFICATION +#define ck_slot_id_t CK_SLOT_ID -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO +#define ck_slot_info _CK_SLOT_INFO +#define slot_description slotDescription +#define hardware_version hardwareVersion +#define firmware_version firmwareVersion +#define ck_token_info _CK_TOKEN_INFO +#define serial_number serialNumber +#define max_session_count ulMaxSessionCount +#define session_count ulSessionCount +#define max_rw_session_count ulMaxRwSessionCount +#define rw_session_count ulRwSessionCount +#define max_pin_len ulMaxPinLen +#define min_pin_len ulMinPinLen +#define total_public_memory ulTotalPublicMemory +#define free_public_memory ulFreePublicMemory +#define total_private_memory ulTotalPrivateMemory +#define free_private_memory ulFreePrivateMemory +#define utc_time utcTime -/* ============================================================== - * Define the typedef form of all the entry points. That is, for - * each Cryptoki function C_XXX, define a type CK_C_XXX which is - * a pointer to that kind of function. - * ============================================================== - */ +#define ck_session_handle_t CK_SESSION_HANDLE +#define ck_user_type_t CK_USER_TYPE +#define ck_state_t CK_STATE -#define CK_NEED_ARG_LIST 1 -#define CK_PKCS11_FUNCTION_INFO(name) \ - typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) +#define ck_session_info _CK_SESSION_INFO +#define slot_id slotID +#define device_error ulDeviceError -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" +#define ck_object_handle_t CK_OBJECT_HANDLE +#define ck_object_class_t CK_OBJECT_CLASS +#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE +#define ck_key_type_t CK_KEY_TYPE +#define ck_certificate_type_t CK_CERTIFICATE_TYPE +#define ck_attribute_type_t CK_ATTRIBUTE_TYPE -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO +#define ck_attribute _CK_ATTRIBUTE +#define value pValue +#define value_len ulValueLen +#define count ulCount -/* ============================================================== - * Define structed vector of entry points. A CK_FUNCTION_LIST - * contains a CK_VERSION indicating a library's Cryptoki version - * and then a whole slew of function pointers to the routines in - * the library. This type was declared, but not defined, in - * pkcs11t.h. - * ============================================================== - */ +#define ck_date _CK_DATE -#define CK_PKCS11_FUNCTION_INFO(name) \ - __PASTE(CK_,name) name; +#define ck_mechanism_type_t CK_MECHANISM_TYPE -struct CK_FUNCTION_LIST { +#define ck_mechanism _CK_MECHANISM +#define parameter pParameter +#define parameter_len ulParameterLen - CK_VERSION version; /* Cryptoki version */ +#define params pParams -/* Pile all the function pointers into the CK_FUNCTION_LIST. */ -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" +#define ck_mechanism_info _CK_MECHANISM_INFO +#define min_key_size ulMinKeySize +#define max_key_size ulMaxKeySize +#define ck_param_type CK_PARAM_TYPE +#define ck_otp_param CK_OTP_PARAM +#define ck_otp_params CK_OTP_PARAMS +#define ck_otp_signature_info CK_OTP_SIGNATURE_INFO + +#define ck_rv_t CK_RV +#define ck_notify_t CK_NOTIFY + +#define ck_function_list _CK_FUNCTION_LIST + +#define ck_createmutex_t CK_CREATEMUTEX +#define ck_destroymutex_t CK_DESTROYMUTEX +#define ck_lockmutex_t CK_LOCKMUTEX +#define ck_unlockmutex_t CK_UNLOCKMUTEX + +#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS +#define create_mutex CreateMutex +#define destroy_mutex DestroyMutex +#define lock_mutex LockMutex +#define unlock_mutex UnlockMutex +#define reserved pReserved + +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE +#define ck_rsa_pkcs_oaep_source_type_t CK_RSA_PKCS_OAEP_SOURCE_TYPE +#define hash_alg hashAlg +#define s_len sLen +#define source_data pSourceData +#define source_data_len ulSourceDataLen + +#define counter_bits ulCounterBits +#define iv_ptr pIv +#define iv_len ulIvLen +#define iv_bits ulIvBits +#define aad_ptr pAAD +#define aad_len ulAADLen +#define tag_bits ulTagBits +#define shared_data_len ulSharedDataLen +#define shared_data pSharedData +#define public_data_len ulPublicDataLen +#define public_data pPublicData +#define string_data pData +#define string_data_len ulLen +#define data_params pData +#endif /* CRYPTOKI_COMPAT */ + +typedef unsigned long ck_flags_t; + +struct ck_version { + unsigned char major; + unsigned char minor; +}; + +struct ck_info { + struct ck_version cryptoki_version; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + unsigned char library_description[32]; + struct ck_version library_version; }; -#undef CK_PKCS11_FUNCTION_INFO +typedef unsigned long ck_notification_t; +#define CKN_SURRENDER (0UL) -#undef __PASTE +typedef unsigned long ck_slot_id_t; -#ifdef __cplusplus -} -#endif +struct ck_slot_info { + unsigned char slot_description[64]; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + struct ck_version hardware_version; + struct ck_version firmware_version; +}; + +#define CKF_TOKEN_PRESENT (1UL << 0) +#define CKF_REMOVABLE_DEVICE (1UL << 1) +#define CKF_HW_SLOT (1UL << 2) +#define CKF_ARRAY_ATTRIBUTE (1UL << 30) + +struct ck_token_info { + unsigned char label[32]; + unsigned char manufacturer_id[32]; + unsigned char model[16]; + unsigned char serial_number[16]; + ck_flags_t flags; + unsigned long max_session_count; + unsigned long session_count; + unsigned long max_rw_session_count; + unsigned long rw_session_count; + unsigned long max_pin_len; + unsigned long min_pin_len; + unsigned long total_public_memory; + unsigned long free_public_memory; + unsigned long total_private_memory; + unsigned long free_private_memory; + struct ck_version hardware_version; + struct ck_version firmware_version; + unsigned char utc_time[16]; +}; + +#define CKF_RNG (1UL << 0) +#define CKF_WRITE_PROTECTED (1UL << 1) +#define CKF_LOGIN_REQUIRED (1UL << 2) +#define CKF_USER_PIN_INITIALIZED (1UL << 3) +#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) +#define CKF_CLOCK_ON_TOKEN (1UL << 6) +#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) +#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) +#define CKF_TOKEN_INITIALIZED (1UL << 10) +#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) +#define CKF_USER_PIN_COUNT_LOW (1UL << 16) +#define CKF_USER_PIN_FINAL_TRY (1UL << 17) +#define CKF_USER_PIN_LOCKED (1UL << 18) +#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) +#define CKF_SO_PIN_COUNT_LOW (1UL << 20) +#define CKF_SO_PIN_FINAL_TRY (1UL << 21) +#define CKF_SO_PIN_LOCKED (1UL << 22) +#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) + +#define CK_UNAVAILABLE_INFORMATION ((unsigned long)-1L) +#define CK_EFFECTIVELY_INFINITE (0UL) + +typedef unsigned long ck_session_handle_t; + +#define CK_INVALID_HANDLE (0UL) + +typedef unsigned long ck_user_type_t; + +#define CKU_SO (0UL) +#define CKU_USER (1UL) +#define CKU_CONTEXT_SPECIFIC (2UL) + +typedef unsigned long ck_state_t; + +#define CKS_RO_PUBLIC_SESSION (0UL) +#define CKS_RO_USER_FUNCTIONS (1UL) +#define CKS_RW_PUBLIC_SESSION (2UL) +#define CKS_RW_USER_FUNCTIONS (3UL) +#define CKS_RW_SO_FUNCTIONS (4UL) + +struct ck_session_info { + ck_slot_id_t slot_id; + ck_state_t state; + ck_flags_t flags; + unsigned long device_error; +}; + +#define CKF_RW_SESSION (1UL << 1) +#define CKF_SERIAL_SESSION (1UL << 2) + +typedef unsigned long ck_object_handle_t; + +typedef unsigned long ck_object_class_t; + +#define CKO_DATA (0UL) +#define CKO_CERTIFICATE (1UL) +#define CKO_PUBLIC_KEY (2UL) +#define CKO_PRIVATE_KEY (3UL) +#define CKO_SECRET_KEY (4UL) +#define CKO_HW_FEATURE (5UL) +#define CKO_DOMAIN_PARAMETERS (6UL) +#define CKO_MECHANISM (7UL) +#define CKO_OTP_KEY (8UL) +#define CKO_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +typedef unsigned long ck_hw_feature_type_t; + +#define CKH_MONOTONIC_COUNTER (1UL) +#define CKH_CLOCK (2UL) +#define CKH_USER_INTERFACE (3UL) +#define CKH_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +typedef unsigned long ck_key_type_t; + +#define CKK_RSA (0UL) +#define CKK_DSA (1UL) +#define CKK_DH (2UL) +#define CKK_ECDSA (3UL) +#define CKK_EC (3UL) +#define CKK_X9_42_DH (4UL) +#define CKK_KEA (5UL) +#define CKK_GENERIC_SECRET (0x10UL) +#define CKK_RC2 (0x11UL) +#define CKK_RC4 (0x12UL) +#define CKK_DES (0x13UL) +#define CKK_DES2 (0x14UL) +#define CKK_DES3 (0x15UL) +#define CKK_CAST (0x16UL) +#define CKK_CAST3 (0x17UL) +#define CKK_CAST128 (0x18UL) +#define CKK_RC5 (0x19UL) +#define CKK_IDEA (0x1aUL) +#define CKK_SKIPJACK (0x1bUL) +#define CKK_BATON (0x1cUL) +#define CKK_JUNIPER (0x1dUL) +#define CKK_CDMF (0x1eUL) +#define CKK_AES (0x1fUL) +#define CKK_BLOWFISH (0x20UL) +#define CKK_TWOFISH (0x21UL) +#define CKK_SECURID (0x22UL) +#define CKK_HOTP (0x23UL) +#define CKK_ACTI (0x24UL) +#define CKK_CAMELLIA (0x25UL) +#define CKK_ARIA (0x26UL) +#define CKK_MD5_HMAC (0x27UL) +#define CKK_SHA_1_HMAC (0x28UL) +#define CKK_RIPEMD128_HMAC (0x29UL) +#define CKK_RIPEMD160_HMAC (0x2aUL) +#define CKK_SHA256_HMAC (0x2bUL) +#define CKK_SHA384_HMAC (0x2cUL) +#define CKK_SHA512_HMAC (0x2dUL) +#define CKK_SHA224_HMAC (0x2eUL) +#define CKK_SEED (0x2fUL) +#define CKK_GOSTR3410 (0x30UL) +#define CKK_GOSTR3411 (0x31UL) +#define CKK_GOST28147 (0x32UL) +#define CKK_EC_EDWARDS (0x40UL) +#define CKK_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +typedef unsigned long ck_certificate_type_t; + +#define CKC_X_509 (0UL) +#define CKC_X_509_ATTR_CERT (1UL) +#define CKC_WTLS (2UL) +#define CKC_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +#define CKC_OPENPGP (CKC_VENDOR_DEFINED | 0x504750UL) + +typedef unsigned long ck_attribute_type_t; + +#define CKA_CLASS (0UL) +#define CKA_TOKEN (1UL) +#define CKA_PRIVATE (2UL) +#define CKA_LABEL (3UL) +#define CKA_APPLICATION (0x10UL) +#define CKA_VALUE (0x11UL) +#define CKA_OBJECT_ID (0x12UL) +#define CKA_CERTIFICATE_TYPE (0x80UL) +#define CKA_ISSUER (0x81UL) +#define CKA_SERIAL_NUMBER (0x82UL) +#define CKA_AC_ISSUER (0x83UL) +#define CKA_OWNER (0x84UL) +#define CKA_ATTR_TYPES (0x85UL) +#define CKA_TRUSTED (0x86UL) +#define CKA_CERTIFICATE_CATEGORY (0x87UL) +#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) +#define CKA_URL (0x89UL) +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) +#define CKA_NAME_HASH_ALGORITHM (0x8cUL) +#define CKA_CHECK_VALUE (0x90UL) +#define CKA_KEY_TYPE (0x100UL) +#define CKA_SUBJECT (0x101UL) +#define CKA_ID (0x102UL) +#define CKA_SENSITIVE (0x103UL) +#define CKA_ENCRYPT (0x104UL) +#define CKA_DECRYPT (0x105UL) +#define CKA_WRAP (0x106UL) +#define CKA_UNWRAP (0x107UL) +#define CKA_SIGN (0x108UL) +#define CKA_SIGN_RECOVER (0x109UL) +#define CKA_VERIFY (0x10aUL) +#define CKA_VERIFY_RECOVER (0x10bUL) +#define CKA_DERIVE (0x10cUL) +#define CKA_START_DATE (0x110UL) +#define CKA_END_DATE (0x111UL) +#define CKA_MODULUS (0x120UL) +#define CKA_MODULUS_BITS (0x121UL) +#define CKA_PUBLIC_EXPONENT (0x122UL) +#define CKA_PRIVATE_EXPONENT (0x123UL) +#define CKA_PRIME_1 (0x124UL) +#define CKA_PRIME_2 (0x125UL) +#define CKA_EXPONENT_1 (0x126UL) +#define CKA_EXPONENT_2 (0x127UL) +#define CKA_COEFFICIENT (0x128UL) +#define CKA_PUBLIC_KEY_INFO (0x129UL) +#define CKA_PRIME (0x130UL) +#define CKA_SUBPRIME (0x131UL) +#define CKA_BASE (0x132UL) +#define CKA_PRIME_BITS (0x133UL) +#define CKA_SUB_PRIME_BITS (0x134UL) +#define CKA_VALUE_BITS (0x160UL) +#define CKA_VALUE_LEN (0x161UL) +#define CKA_EXTRACTABLE (0x162UL) +#define CKA_LOCAL (0x163UL) +#define CKA_NEVER_EXTRACTABLE (0x164UL) +#define CKA_ALWAYS_SENSITIVE (0x165UL) +#define CKA_KEY_GEN_MECHANISM (0x166UL) +#define CKA_MODIFIABLE (0x170UL) +#define CKA_COPYABLE (0x171UL) +#define CKA_DESTROYABLE (0x172UL) +#define CKA_ECDSA_PARAMS (0x180UL) +#define CKA_EC_PARAMS (0x180UL) +#define CKA_EC_POINT (0x181UL) +#define CKA_SECONDARY_AUTH (0x200UL) +#define CKA_AUTH_PIN_FLAGS (0x201UL) +#define CKA_ALWAYS_AUTHENTICATE (0x202UL) +#define CKA_WRAP_WITH_TRUSTED (0x210UL) +#define CKA_OTP_FORMAT (0x220UL) +#define CKA_OTP_LENGTH (0x221UL) +#define CKA_OTP_TIME_INTERVAL (0x222UL) +#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) +#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) +#define CKA_OTP_TIME_REQUIREMENT (0x225UL) +#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) +#define CKA_OTP_PIN_REQUIREMENT (0x227UL) +#define CKA_OTP_USER_IDENTIFIER (0x22AUL) +#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) +#define CKA_OTP_SERVICE_LOGO (0x22CUL) +#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) +#define CKA_OTP_COUNTER (0x22EUL) +#define CKA_OTP_TIME (0x22FUL) +#define CKA_GOSTR3410_PARAMS (0x250UL) +#define CKA_GOSTR3411_PARAMS (0x251UL) +#define CKA_GOST28147_PARAMS (0x252UL) +#define CKA_HW_FEATURE_TYPE (0x300UL) +#define CKA_RESET_ON_INIT (0x301UL) +#define CKA_HAS_RESET (0x302UL) +#define CKA_PIXEL_X (0x400UL) +#define CKA_PIXEL_Y (0x401UL) +#define CKA_RESOLUTION (0x402UL) +#define CKA_CHAR_ROWS (0x403UL) +#define CKA_CHAR_COLUMNS (0x404UL) +#define CKA_COLOR (0x405UL) +#define CKA_BITS_PER_PIXEL (0x406UL) +#define CKA_CHAR_SETS (0x480UL) +#define CKA_ENCODING_METHODS (0x481UL) +#define CKA_MIME_TYPES (0x482UL) +#define CKA_MECHANISM_TYPE (0x500UL) +#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) +#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) +#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) +#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x213UL) +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) +#define CKA_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +struct ck_attribute { + ck_attribute_type_t type; + void * value; + unsigned long value_len; +}; + +struct ck_date { + unsigned char year[4]; + unsigned char month[2]; + unsigned char day[2]; +}; + +typedef unsigned long ck_mechanism_type_t; + +#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) +#define CKM_RSA_PKCS (1UL) +#define CKM_RSA_9796 (2UL) +#define CKM_RSA_X_509 (3UL) +#define CKM_MD2_RSA_PKCS (4UL) +#define CKM_MD5_RSA_PKCS (5UL) +#define CKM_SHA1_RSA_PKCS (6UL) +#define CKM_RIPEMD128_RSA_PKCS (7UL) +#define CKM_RIPEMD160_RSA_PKCS (8UL) +#define CKM_RSA_PKCS_OAEP (9UL) +#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) +#define CKM_RSA_X9_31 (0xbUL) +#define CKM_SHA1_RSA_X9_31 (0xcUL) +#define CKM_RSA_PKCS_PSS (0xdUL) +#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) +#define CKM_DSA_KEY_PAIR_GEN (0x10UL) +#define CKM_DSA (0x11UL) +#define CKM_DSA_SHA1 (0x12UL) +#define CKM_DSA_SHA224 (0x13UL) +#define CKM_DSA_SHA256 (0x14UL) +#define CKM_DSA_SHA384 (0x15UL) +#define CKM_DSA_SHA512 (0x16UL) +#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) +#define CKM_DH_PKCS_DERIVE (0x21UL) +#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) +#define CKM_X9_42_DH_DERIVE (0x31UL) +#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) +#define CKM_X9_42_MQV_DERIVE (0x33UL) +#define CKM_SHA256_RSA_PKCS (0x40UL) +#define CKM_SHA384_RSA_PKCS (0x41UL) +#define CKM_SHA512_RSA_PKCS (0x42UL) +#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) +#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) +#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA512_224 (0x48UL) +#define CKM_SHA512_224_HMAC (0x49UL) +#define CKM_SHA512_224_HMAC_GENERAL (0x4aUL) +#define CKM_SHA512_224_KEY_DERIVATION (0x4bUL) +#define CKM_SHA512_256 (0x4cUL) +#define CKM_SHA512_256_HMAC (0x4dUL) +#define CKM_SHA512_256_HMAC_GENERAL (0x4eUL) +#define CKM_SHA512_256_KEY_DERIVATION (0x4fUL) +#define CKM_SHA512_T (0x50UL) +#define CKM_SHA512_T_HMAC (0x51UL) +#define CKM_SHA512_T_HMAC_GENERAL (0x52UL) +#define CKM_SHA512_T_KEY_DERIVATION (0x53UL) +#define CKM_RC2_KEY_GEN (0x100UL) +#define CKM_RC2_ECB (0x101UL) +#define CKM_RC2_CBC (0x102UL) +#define CKM_RC2_MAC (0x103UL) +#define CKM_RC2_MAC_GENERAL (0x104UL) +#define CKM_RC2_CBC_PAD (0x105UL) +#define CKM_RC4_KEY_GEN (0x110UL) +#define CKM_RC4 (0x111UL) +#define CKM_DES_KEY_GEN (0x120UL) +#define CKM_DES_ECB (0x121UL) +#define CKM_DES_CBC (0x122UL) +#define CKM_DES_MAC (0x123UL) +#define CKM_DES_MAC_GENERAL (0x124UL) +#define CKM_DES_CBC_PAD (0x125UL) +#define CKM_DES2_KEY_GEN (0x130UL) +#define CKM_DES3_KEY_GEN (0x131UL) +#define CKM_DES3_ECB (0x132UL) +#define CKM_DES3_CBC (0x133UL) +#define CKM_DES3_MAC (0x134UL) +#define CKM_DES3_MAC_GENERAL (0x135UL) +#define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC_GENERAL (0x137UL) +#define CKM_DES3_CMAC (0x138UL) +#define CKM_CDMF_KEY_GEN (0x140UL) +#define CKM_CDMF_ECB (0x141UL) +#define CKM_CDMF_CBC (0x142UL) +#define CKM_CDMF_MAC (0x143UL) +#define CKM_CDMF_MAC_GENERAL (0x144UL) +#define CKM_CDMF_CBC_PAD (0x145UL) +#define CKM_DES_OFB64 (0x150UL) +#define CKM_DES_OFB8 (0x151UL) +#define CKM_DES_CFB64 (0x152UL) +#define CKM_DES_CFB8 (0x153UL) +#define CKM_MD2 (0x200UL) +#define CKM_MD2_HMAC (0x201UL) +#define CKM_MD2_HMAC_GENERAL (0x202UL) +#define CKM_MD5 (0x210UL) +#define CKM_MD5_HMAC (0x211UL) +#define CKM_MD5_HMAC_GENERAL (0x212UL) +#define CKM_SHA_1 (0x220UL) +#define CKM_SHA_1_HMAC (0x221UL) +#define CKM_SHA_1_HMAC_GENERAL (0x222UL) +#define CKM_RIPEMD128 (0x230UL) +#define CKM_RIPEMD128_HMAC (0x231UL) +#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) +#define CKM_RIPEMD160 (0x240UL) +#define CKM_RIPEMD160_HMAC (0x241UL) +#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) +#define CKM_SHA256 (0x250UL) +#define CKM_SHA256_HMAC (0x251UL) +#define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA384 (0x260UL) +#define CKM_SHA384_HMAC (0x261UL) +#define CKM_SHA384_HMAC_GENERAL (0x262UL) +#define CKM_SHA512 (0x270UL) +#define CKM_SHA512_HMAC (0x271UL) +#define CKM_SHA512_HMAC_GENERAL (0x272UL) +#define CKM_SECURID_KEY_GEN (0x280UL) +#define CKM_SECURID (0x282UL) +#define CKM_HOTP_KEY_GEN (0x290UL) +#define CKM_HOTP (0x291UL) +#define CKM_ACTI (0x2a0UL) +#define CKM_ACTI_KEY_GEN (0x2a1UL) +#define CKM_CAST_KEY_GEN (0x300UL) +#define CKM_CAST_ECB (0x301UL) +#define CKM_CAST_CBC (0x302UL) +#define CKM_CAST_MAC (0x303UL) +#define CKM_CAST_MAC_GENERAL (0x304UL) +#define CKM_CAST_CBC_PAD (0x305UL) +#define CKM_CAST3_KEY_GEN (0x310UL) +#define CKM_CAST3_ECB (0x311UL) +#define CKM_CAST3_CBC (0x312UL) +#define CKM_CAST3_MAC (0x313UL) +#define CKM_CAST3_MAC_GENERAL (0x314UL) +#define CKM_CAST3_CBC_PAD (0x315UL) +#define CKM_CAST5_KEY_GEN (0x320UL) +#define CKM_CAST128_KEY_GEN (0x320UL) +#define CKM_CAST5_ECB (0x321UL) +#define CKM_CAST128_ECB (0x321UL) +#define CKM_CAST5_CBC (0x322UL) +#define CKM_CAST128_CBC (0x322UL) +#define CKM_CAST5_MAC (0x323UL) +#define CKM_CAST128_MAC (0x323UL) +#define CKM_CAST5_MAC_GENERAL (0x324UL) +#define CKM_CAST128_MAC_GENERAL (0x324UL) +#define CKM_CAST5_CBC_PAD (0x325UL) +#define CKM_CAST128_CBC_PAD (0x325UL) +#define CKM_RC5_KEY_GEN (0x330UL) +#define CKM_RC5_ECB (0x331UL) +#define CKM_RC5_CBC (0x332UL) +#define CKM_RC5_MAC (0x333UL) +#define CKM_RC5_MAC_GENERAL (0x334UL) +#define CKM_RC5_CBC_PAD (0x335UL) +#define CKM_IDEA_KEY_GEN (0x340UL) +#define CKM_IDEA_ECB (0x341UL) +#define CKM_IDEA_CBC (0x342UL) +#define CKM_IDEA_MAC (0x343UL) +#define CKM_IDEA_MAC_GENERAL (0x344UL) +#define CKM_IDEA_CBC_PAD (0x345UL) +#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) +#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) +#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) +#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) +#define CKM_XOR_BASE_AND_DATA (0x364UL) +#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) +#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) +#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) +#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) +#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) +#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) +#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) +#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) +#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) +#define CKM_TLS_PRF (0x378UL) +#define CKM_SSL3_MD5_MAC (0x380UL) +#define CKM_SSL3_SHA1_MAC (0x381UL) +#define CKM_MD5_KEY_DERIVATION (0x390UL) +#define CKM_MD2_KEY_DERIVATION (0x391UL) +#define CKM_SHA1_KEY_DERIVATION (0x392UL) +#define CKM_SHA256_KEY_DERIVATION (0x393UL) +#define CKM_SHA384_KEY_DERIVATION (0x394UL) +#define CKM_SHA512_KEY_DERIVATION (0x395UL) +#define CKM_PBE_MD2_DES_CBC (0x3a0UL) +#define CKM_PBE_MD5_DES_CBC (0x3a1UL) +#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) +#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) +#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) +#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) +#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) +#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) +#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) +#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) +#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) +#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) +#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) +#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) +#define CKM_PKCS5_PBKD2 (0x3b0UL) +#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) +#define CKM_WTLS_PRE_MASTER_KEY_GEN (0x3d0UL) +#define CKM_WTLS_MASTER_KEY_DERIVE (0x3d1UL) +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC (0x3d2UL) +#define CKM_WTLS_PRF (0x3d3UL) +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE (0x3d4UL) +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE (0x3d5UL) +#define CKM_TLS10_MAC_SERVER (0x3d6UL) +#define CKM_TLS10_MAC_CLIENT (0x3d7UL) +#define CKM_TLS12_MAC (0x3d8UL) +#define CKM_TLS12_KDF (0x3d9UL) +#define CKM_TLS12_MASTER_KEY_DERIVE (0x3e0UL) +#define CKM_TLS12_KEY_AND_MAC_DERIVE (0x3e1UL) +#define CKM_TLS12_MASTER_KEY_DERIVE_DH (0x3e2UL) +#define CKM_TLS12_KEY_SAFE_DERIVE (0x3e3UL) +#define CKM_TLS_MAC (0x3e4UL) +#define CKM_TLS_KDF (0x3e5UL) +#define CKM_KEY_WRAP_LYNKS (0x400UL) +#define CKM_KEY_WRAP_SET_OAEP (0x401UL) +#define CKM_CMS_SIG (0x500UL) +#define CKM_KIP_DERIVE (0x510UL) +#define CKM_KIP_WRAP (0x511UL) +#define CKM_KIP_MAC (0x512UL) +#define CKM_ARIA_KEY_GEN (0x560UL) +#define CKM_ARIA_ECB (0x561UL) +#define CKM_ARIA_CBC (0x562UL) +#define CKM_ARIA_MAC (0x563UL) +#define CKM_ARIA_MAC_GENERAL (0x564UL) +#define CKM_ARIA_CBC_PAD (0x565UL) +#define CKM_ARIA_ECB_ENCRYPT_DATA (0x566UL) +#define CKM_ARIA_CBC_ENCRYPT_DATA (0x567UL) +#define CKM_SEED_KEY_GEN (0x650UL) +#define CKM_SEED_ECB (0x651UL) +#define CKM_SEED_CBC (0x652UL) +#define CKM_SEED_MAC (0x653UL) +#define CKM_SEED_MAC_GENERAL (0x654UL) +#define CKM_SEED_CBC_PAD (0x655UL) +#define CKM_SEED_ECB_ENCRYPT_DATA (0x656UL) +#define CKM_SEED_CBC_ENCRYPT_DATA (0x657UL) +#define CKM_SKIPJACK_KEY_GEN (0x1000UL) +#define CKM_SKIPJACK_ECB64 (0x1001UL) +#define CKM_SKIPJACK_CBC64 (0x1002UL) +#define CKM_SKIPJACK_OFB64 (0x1003UL) +#define CKM_SKIPJACK_CFB64 (0x1004UL) +#define CKM_SKIPJACK_CFB32 (0x1005UL) +#define CKM_SKIPJACK_CFB16 (0x1006UL) +#define CKM_SKIPJACK_CFB8 (0x1007UL) +#define CKM_SKIPJACK_WRAP (0x1008UL) +#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) +#define CKM_SKIPJACK_RELAYX (0x100aUL) +#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) +#define CKM_KEA_KEY_DERIVE (0x1011UL) +#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) +#define CKM_BATON_KEY_GEN (0x1030UL) +#define CKM_BATON_ECB128 (0x1031UL) +#define CKM_BATON_ECB96 (0x1032UL) +#define CKM_BATON_CBC128 (0x1033UL) +#define CKM_BATON_COUNTER (0x1034UL) +#define CKM_BATON_SHUFFLE (0x1035UL) +#define CKM_BATON_WRAP (0x1036UL) +#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) +#define CKM_EC_KEY_PAIR_GEN (0x1040UL) +#define CKM_ECDSA (0x1041UL) +#define CKM_ECDSA_SHA1 (0x1042UL) +#define CKM_ECDSA_SHA224 (0x1043UL) +#define CKM_ECDSA_SHA256 (0x1044UL) +#define CKM_ECDSA_SHA384 (0x1045UL) +#define CKM_ECDSA_SHA512 (0x1046UL) +#define CKM_ECDH1_DERIVE (0x1050UL) +#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) +#define CKM_ECMQV_DERIVE (0x1052UL) +#define CKM_ECDH_AES_KEY_WRAP (0x1053UL) +#define CKM_RSA_AES_KEY_WRAP (0x1054UL) +#define CKM_JUNIPER_KEY_GEN (0x1060UL) +#define CKM_JUNIPER_ECB128 (0x1061UL) +#define CKM_JUNIPER_CBC128 (0x1062UL) +#define CKM_JUNIPER_COUNTER (0x1063UL) +#define CKM_JUNIPER_SHUFFLE (0x1064UL) +#define CKM_JUNIPER_WRAP (0x1065UL) +#define CKM_FASTHASH (0x1070UL) +#define CKM_AES_KEY_GEN (0x1080UL) +#define CKM_AES_ECB (0x1081UL) +#define CKM_AES_CBC (0x1082UL) +#define CKM_AES_MAC (0x1083UL) +#define CKM_AES_MAC_GENERAL (0x1084UL) +#define CKM_AES_CBC_PAD (0x1085UL) +#define CKM_AES_CTR (0x1086UL) +#define CKM_AES_GCM (0x1087UL) +#define CKM_AES_CCM (0x1088UL) +#define CKM_AES_CTS (0x1089UL) +#define CKM_AES_CMAC (0x108aUL) +#define CKM_AES_CMAC_GENERAL (0x108bUL) +#define CKM_AES_XCBC_MAC (0x108cUL) +#define CKM_AES_XCBC_MAC_96 (0x108dUL) +#define CKM_AES_GMAC (0x108eUL) +#define CKM_BLOWFISH_KEY_GEN (0x1090UL) +#define CKM_BLOWFISH_CBC (0x1091UL) +#define CKM_TWOFISH_KEY_GEN (0x1092UL) +#define CKM_TWOFISH_CBC (0x1093UL) +#define CKM_BLOWFISH_CBC_PAD (0x1094UL) +#define CKM_TWOFISH_CBC_PAD (0x1095UL) +#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) +#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) +#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) +#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) +#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) +#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) +#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) +#define CKM_GOSTR3410 (0x1201UL) +#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) +#define CKM_GOSTR3410_KEY_WRAP (0x1203UL) +#define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3411 (0x1210UL) +#define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOST28147_KEY_GEN (0x1220UL) +#define CKM_GOST28147_ECB (0x1221UL) +#define CKM_GOST28147 (0x1222UL) +#define CKM_GOST28147_MAC (0x1223UL) +#define CKM_GOST28147_KEY_WRAP (0x1224UL) +#define CKM_DSA_PARAMETER_GEN (0x2000UL) +#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) +#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN (0x2003UL) +#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN (0x2004UL) +#define CKM_AES_OFB (0x2104UL) +#define CKM_AES_CFB64 (0x2105UL) +#define CKM_AES_CFB8 (0x2106UL) +#define CKM_AES_CFB128 (0x2107UL) +#define CKM_AES_CFB1 (0x2108UL) + +#define CKM_VENDOR_DEFINED ((unsigned long)(1UL << 31)) + +/* Amendments */ +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) +#define CKM_SHA224_KEY_DERIVATION (0x396UL) + +#define CKM_CAMELLIA_KEY_GEN (0x550UL) +#define CKM_CAMELLIA_ECB (0x551UL) +#define CKM_CAMELLIA_CBC (0x552UL) +#define CKM_CAMELLIA_MAC (0x553UL) +#define CKM_CAMELLIA_MAC_GENERAL (0x554UL) +#define CKM_CAMELLIA_CBC_PAD (0x555UL) +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA (0x556UL) +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA (0x557UL) +#define CKM_CAMELLIA_CTR (0x558UL) + +#define CKM_AES_KEY_WRAP (0x2109UL) +#define CKM_AES_KEY_WRAP_PAD (0x210aUL) + +#define CKM_RSA_PKCS_TPM_1_1 (0x4001UL) +#define CKM_RSA_PKCS_OAEP_TPM_1_1 (0x4002UL) + +/* From version 3.0 */ +#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL) +#define CKM_EDDSA (0x1057UL) + +/* Attribute and other constants related to OTP */ +#define CK_OTP_FORMAT_DECIMAL (0UL) +#define CK_OTP_FORMAT_HEXADECIMAL (1UL) +#define CK_OTP_FORMAT_ALPHANUMERIC (2UL) +#define CK_OTP_FORMAT_BINARY (3UL) +#define CK_OTP_PARAM_IGNORED (0UL) +#define CK_OTP_PARAM_OPTIONAL (1UL) +#define CK_OTP_PARAM_MANDATORY (2UL) + +#define CK_OTP_VALUE (0UL) +#define CK_OTP_PIN (1UL) +#define CK_OTP_CHALLENGE (2UL) +#define CK_OTP_TIME (3UL) +#define CK_OTP_COUNTER (4UL) +#define CK_OTP_FLAGS (5UL) +#define CK_OTP_OUTPUT_LENGTH (6UL) +#define CK_OTP_FORMAT (7UL) + +/* OTP mechanism flags */ +#define CKF_NEXT_OTP (0x01UL) +#define CKF_EXCLUDE_TIME (0x02UL) +#define CKF_EXCLUDE_COUNTER (0x04UL) +#define CKF_EXCLUDE_CHALLENGE (0x08UL) +#define CKF_EXCLUDE_PIN (0x10UL) +#define CKF_USER_FRIENDLY_OTP (0x20UL) + +#define CKN_OTP_CHANGED (0x01UL) + +struct ck_mechanism { + ck_mechanism_type_t mechanism; + void * parameter; + unsigned long parameter_len; +}; + +struct ck_mechanism_info { + unsigned long min_key_size; + unsigned long max_key_size; + ck_flags_t flags; +}; + +typedef unsigned long ck_param_type; + +typedef struct ck_otp_param { + ck_param_type type; + void * value; + unsigned long value_len; +} ck_otp_param; + +typedef struct ck_otp_params { + struct ck_otp_param *params; + unsigned long count; +} ck_otp_params; + +typedef struct ck_otp_signature_info { + struct ck_otp_param *params; + unsigned long count; +} ck_otp_signature_info; + +#define CKG_MGF1_SHA1 0x00000001UL +#define CKG_MGF1_SHA224 0x00000005UL +#define CKG_MGF1_SHA256 0x00000002UL +#define CKG_MGF1_SHA384 0x00000003UL +#define CKG_MGF1_SHA512 0x00000004UL + +typedef unsigned long ck_rsa_pkcs_mgf_type_t; + +struct ck_rsa_pkcs_pss_params { + ck_mechanism_type_t hash_alg; + ck_rsa_pkcs_mgf_type_t mgf; + unsigned long s_len; +}; + +typedef unsigned long ck_rsa_pkcs_oaep_source_type_t; + +struct ck_rsa_pkcs_oaep_params { + ck_mechanism_type_t hash_alg; + ck_rsa_pkcs_mgf_type_t mgf; + ck_rsa_pkcs_oaep_source_type_t source; + void * source_data; + unsigned long source_data_len; +}; + +struct ck_aes_ctr_params { + unsigned long counter_bits; + unsigned char cb[16]; +}; + +struct ck_gcm_params { + unsigned char *iv_ptr; + unsigned long iv_len; + unsigned long iv_bits; + unsigned char *aad_ptr; + unsigned long aad_len; + unsigned long tag_bits; +}; + +/* The following EC Key Derivation Functions are defined */ +#define CKD_NULL (0x01UL) +#define CKD_SHA1_KDF (0x02UL) + +/* The following X9.42 DH key derivation functions are defined */ +#define CKD_SHA1_KDF_ASN1 (0x03UL) +#define CKD_SHA1_KDF_CONCATENATE (0x04UL) +#define CKD_SHA224_KDF (0x05UL) +#define CKD_SHA256_KDF (0x06UL) +#define CKD_SHA384_KDF (0x07UL) +#define CKD_SHA512_KDF (0x08UL) +#define CKD_CPDIVERSIFY_KDF (0x09UL) + +typedef unsigned long ck_ec_kdf_t; + +struct ck_ecdh1_derive_params { + ck_ec_kdf_t kdf; + unsigned long shared_data_len; + unsigned char *shared_data; + unsigned long public_data_len; + unsigned char *public_data; +}; + +struct ck_key_derivation_string_data { + unsigned char *string_data; + unsigned long string_data_len; +}; + +struct ck_des_cbc_encrypt_data_params { + unsigned char iv[8]; + unsigned char *data_params; + unsigned long length; +}; + +struct ck_aes_cbc_encrypt_data_params { + unsigned char iv[16]; + unsigned char *data_params; + unsigned long length; +}; + +#define CKF_HW (1UL << 0) +#define CKF_ENCRYPT (1UL << 8) +#define CKF_DECRYPT (1UL << 9) +#define CKF_DIGEST (1UL << 10) +#define CKF_SIGN (1UL << 11) +#define CKF_SIGN_RECOVER (1UL << 12) +#define CKF_VERIFY (1UL << 13) +#define CKF_VERIFY_RECOVER (1UL << 14) +#define CKF_GENERATE (1UL << 15) +#define CKF_GENERATE_KEY_PAIR (1UL << 16) +#define CKF_WRAP (1UL << 17) +#define CKF_UNWRAP (1UL << 18) +#define CKF_DERIVE (1UL << 19) +#define CKF_EXTENSION ((unsigned long)(1UL << 31)) + +#define CKF_EC_F_P (1UL << 20) +#define CKF_EC_NAMEDCURVE (1UL << 23) +#define CKF_EC_UNCOMPRESS (1UL << 24) +#define CKF_EC_COMPRESS (1UL << 25) + +/* Flags for C_WaitForSlotEvent. */ +#define CKF_DONT_BLOCK (1UL) + +typedef unsigned long ck_rv_t; + +typedef ck_rv_t (*ck_notify_t)(ck_session_handle_t session, + ck_notification_t event, void *application); + +/* Forward reference. */ +struct ck_function_list; + +#define _CK_DECLARE_FUNCTION(name, args) \ + typedef ck_rv_t(*CK_##name) args; \ + ck_rv_t CK_SPEC name args + +_CK_DECLARE_FUNCTION(C_Initialize, (void *init_args)); +_CK_DECLARE_FUNCTION(C_Finalize, (void *reserved)); +_CK_DECLARE_FUNCTION(C_GetInfo, (struct ck_info * info)); +_CK_DECLARE_FUNCTION(C_GetFunctionList, + (struct ck_function_list * *function_list)); + +_CK_DECLARE_FUNCTION(C_GetSlotList, + (unsigned char token_present, ck_slot_id_t *slot_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION(C_GetSlotInfo, + (ck_slot_id_t slot_id, struct ck_slot_info *info)); +_CK_DECLARE_FUNCTION(C_GetTokenInfo, + (ck_slot_id_t slot_id, struct ck_token_info *info)); +_CK_DECLARE_FUNCTION(C_WaitForSlotEvent, + (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); +_CK_DECLARE_FUNCTION(C_GetMechanismList, + (ck_slot_id_t slot_id, ck_mechanism_type_t *mechanism_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION(C_GetMechanismInfo, + (ck_slot_id_t slot_id, ck_mechanism_type_t type, + struct ck_mechanism_info *info)); +_CK_DECLARE_FUNCTION(C_InitToken, + (ck_slot_id_t slot_id, unsigned char *pin, + unsigned long pin_len, unsigned char *label)); +_CK_DECLARE_FUNCTION(C_InitPIN, (ck_session_handle_t session, + unsigned char *pin, unsigned long pin_len)); +_CK_DECLARE_FUNCTION(C_SetPIN, (ck_session_handle_t session, + unsigned char *old_pin, unsigned long old_len, + unsigned char *new_pin, unsigned long new_len)); + +_CK_DECLARE_FUNCTION(C_OpenSession, + (ck_slot_id_t slot_id, ck_flags_t flags, void *application, + ck_notify_t notify, ck_session_handle_t *session)); +_CK_DECLARE_FUNCTION(C_CloseSession, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION(C_CloseAllSessions, (ck_slot_id_t slot_id)); +_CK_DECLARE_FUNCTION(C_GetSessionInfo, (ck_session_handle_t session, + struct ck_session_info *info)); +_CK_DECLARE_FUNCTION(C_GetOperationState, (ck_session_handle_t session, + unsigned char * operation_state, + unsigned long *operation_state_len)); +_CK_DECLARE_FUNCTION(C_SetOperationState, + (ck_session_handle_t session, + unsigned char * operation_state, + unsigned long operation_state_len, + ck_object_handle_t encryption_key, + ck_object_handle_t authentiation_key)); +_CK_DECLARE_FUNCTION(C_Login, + (ck_session_handle_t session, ck_user_type_t user_type, + unsigned char *pin, unsigned long pin_len)); +_CK_DECLARE_FUNCTION(C_Logout, (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION(C_CreateObject, + (ck_session_handle_t session, struct ck_attribute *templ, + unsigned long count, ck_object_handle_t *object)); +_CK_DECLARE_FUNCTION(C_CopyObject, + (ck_session_handle_t session, ck_object_handle_t object, + struct ck_attribute *templ, unsigned long count, + ck_object_handle_t *new_object)); +_CK_DECLARE_FUNCTION(C_DestroyObject, + (ck_session_handle_t session, ck_object_handle_t object)); +_CK_DECLARE_FUNCTION(C_GetObjectSize, + (ck_session_handle_t session, ck_object_handle_t object, + unsigned long *size)); +_CK_DECLARE_FUNCTION(C_GetAttributeValue, + (ck_session_handle_t session, ck_object_handle_t object, + struct ck_attribute *templ, unsigned long count)); +_CK_DECLARE_FUNCTION(C_SetAttributeValue, + (ck_session_handle_t session, ck_object_handle_t object, + struct ck_attribute *templ, unsigned long count)); +_CK_DECLARE_FUNCTION(C_FindObjectsInit, + (ck_session_handle_t session, struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION(C_FindObjects, + (ck_session_handle_t session, ck_object_handle_t *object, + unsigned long max_object_count, + unsigned long *object_count)); +_CK_DECLARE_FUNCTION(C_FindObjectsFinal, (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION(C_EncryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_Encrypt, + (ck_session_handle_t session, unsigned char *data, + unsigned long data_len, unsigned char *encrypted_data, + unsigned long *encrypted_data_len)); +_CK_DECLARE_FUNCTION(C_EncryptUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len, unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION(C_EncryptFinal, (ck_session_handle_t session, + unsigned char * last_encrypted_part, + unsigned long *last_encrypted_part_len)); + +_CK_DECLARE_FUNCTION(C_DecryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_Decrypt, (ck_session_handle_t session, + unsigned char * encrypted_data, + unsigned long encrypted_data_len, + unsigned char *data, unsigned long *data_len)); +_CK_DECLARE_FUNCTION(C_DecryptUpdate, + (ck_session_handle_t session, + unsigned char * encrypted_part, + unsigned long encrypted_part_len, unsigned char *part, + unsigned long *part_len)); +_CK_DECLARE_FUNCTION(C_DecryptFinal, + (ck_session_handle_t session, unsigned char *last_part, + unsigned long *last_part_len)); + +_CK_DECLARE_FUNCTION(C_DigestInit, (ck_session_handle_t session, + struct ck_mechanism *mechanism)); +_CK_DECLARE_FUNCTION(C_Digest, + (ck_session_handle_t session, unsigned char *data, + unsigned long data_len, unsigned char *digest, + unsigned long *digest_len)); +_CK_DECLARE_FUNCTION(C_DigestUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len)); +_CK_DECLARE_FUNCTION(C_DigestKey, + (ck_session_handle_t session, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_DigestFinal, + (ck_session_handle_t session, unsigned char *digest, + unsigned long *digest_len)); + +_CK_DECLARE_FUNCTION(C_SignInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_Sign, (ck_session_handle_t session, unsigned char *data, + unsigned long data_len, unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION(C_SignUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len)); +_CK_DECLARE_FUNCTION(C_SignFinal, + (ck_session_handle_t session, unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION(C_SignRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_SignRecover, + (ck_session_handle_t session, unsigned char *data, + unsigned long data_len, unsigned char *signature, + unsigned long *signature_len)); + +_CK_DECLARE_FUNCTION(C_VerifyInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_Verify, + (ck_session_handle_t session, unsigned char *data, + unsigned long data_len, unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION(C_VerifyUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len)); +_CK_DECLARE_FUNCTION(C_VerifyFinal, + (ck_session_handle_t session, unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION(C_VerifyRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION(C_VerifyRecover, + (ck_session_handle_t session, unsigned char *signature, + unsigned long signature_len, unsigned char *data, + unsigned long *data_len)); + +_CK_DECLARE_FUNCTION(C_DigestEncryptUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len, unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION(C_DecryptDigestUpdate, + (ck_session_handle_t session, + unsigned char * encrypted_part, + unsigned long encrypted_part_len, unsigned char *part, + unsigned long *part_len)); +_CK_DECLARE_FUNCTION(C_SignEncryptUpdate, + (ck_session_handle_t session, unsigned char *part, + unsigned long part_len, unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION(C_DecryptVerifyUpdate, + (ck_session_handle_t session, + unsigned char * encrypted_part, + unsigned long encrypted_part_len, unsigned char *part, + unsigned long *part_len)); + +_CK_DECLARE_FUNCTION(C_GenerateKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *templ, unsigned long count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION(C_GenerateKeyPair, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *public_key_template, + unsigned long public_key_attribute_count, + struct ck_attribute *private_key_template, + unsigned long private_key_attribute_count, + ck_object_handle_t * public_key, + ck_object_handle_t * private_key)); +_CK_DECLARE_FUNCTION(C_WrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t wrapping_key, ck_object_handle_t key, + unsigned char *wrapped_key, + unsigned long *wrapped_key_len)); +_CK_DECLARE_FUNCTION(C_UnwrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t unwrapping_key, + unsigned char *wrapped_key, unsigned long wrapped_key_len, + struct ck_attribute *templ, unsigned long attribute_count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION(C_DeriveKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t base_key, struct ck_attribute *templ, + unsigned long attribute_count, ck_object_handle_t *key)); + +_CK_DECLARE_FUNCTION(C_SeedRandom, + (ck_session_handle_t session, unsigned char *seed, + unsigned long seed_len)); +_CK_DECLARE_FUNCTION(C_GenerateRandom, + (ck_session_handle_t session, unsigned char *random_data, + unsigned long random_len)); + +_CK_DECLARE_FUNCTION(C_GetFunctionStatus, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION(C_CancelFunction, (ck_session_handle_t session)); + +struct ck_function_list { + struct ck_version version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; +}; + +typedef ck_rv_t (*ck_createmutex_t)(void **mutex); +typedef ck_rv_t (*ck_destroymutex_t)(void *mutex); +typedef ck_rv_t (*ck_lockmutex_t)(void *mutex); +typedef ck_rv_t (*ck_unlockmutex_t)(void *mutex); + +struct ck_c_initialize_args { + ck_createmutex_t create_mutex; + ck_destroymutex_t destroy_mutex; + ck_lockmutex_t lock_mutex; + ck_unlockmutex_t unlock_mutex; + ck_flags_t flags; + void * reserved; +}; + +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) +#define CKF_OS_LOCKING_OK (1UL << 1) + +#define CKR_OK (0UL) +#define CKR_CANCEL (1UL) +#define CKR_HOST_MEMORY (2UL) +#define CKR_SLOT_ID_INVALID (3UL) +#define CKR_GENERAL_ERROR (5UL) +#define CKR_FUNCTION_FAILED (6UL) +#define CKR_ARGUMENTS_BAD (7UL) +#define CKR_NO_EVENT (8UL) +#define CKR_NEED_TO_CREATE_THREADS (9UL) +#define CKR_CANT_LOCK (0xaUL) +#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) +#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) +#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) +#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) +#define CKR_ACTION_PROHIBITED (0x1BUL) +#define CKR_DATA_INVALID (0x20UL) +#define CKR_DATA_LEN_RANGE (0x21UL) +#define CKR_DEVICE_ERROR (0x30UL) +#define CKR_DEVICE_MEMORY (0x31UL) +#define CKR_DEVICE_REMOVED (0x32UL) +#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) +#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) +#define CKR_FUNCTION_CANCELED (0x50UL) +#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) +#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) +#define CKR_KEY_HANDLE_INVALID (0x60UL) +#define CKR_KEY_SIZE_RANGE (0x62UL) +#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) +#define CKR_KEY_NOT_NEEDED (0x64UL) +#define CKR_KEY_CHANGED (0x65UL) +#define CKR_KEY_NEEDED (0x66UL) +#define CKR_KEY_INDIGESTIBLE (0x67UL) +#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) +#define CKR_KEY_NOT_WRAPPABLE (0x69UL) +#define CKR_KEY_UNEXTRACTABLE (0x6aUL) +#define CKR_MECHANISM_INVALID (0x70UL) +#define CKR_MECHANISM_PARAM_INVALID (0x71UL) +#define CKR_OBJECT_HANDLE_INVALID (0x82UL) +#define CKR_OPERATION_ACTIVE (0x90UL) +#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) +#define CKR_PIN_INCORRECT (0xa0UL) +#define CKR_PIN_INVALID (0xa1UL) +#define CKR_PIN_LEN_RANGE (0xa2UL) +#define CKR_PIN_EXPIRED (0xa3UL) +#define CKR_PIN_LOCKED (0xa4UL) +#define CKR_SESSION_CLOSED (0xb0UL) +#define CKR_SESSION_COUNT (0xb1UL) +#define CKR_SESSION_HANDLE_INVALID (0xb3UL) +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) +#define CKR_SESSION_READ_ONLY (0xb5UL) +#define CKR_SESSION_EXISTS (0xb6UL) +#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) +#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) +#define CKR_SIGNATURE_INVALID (0xc0UL) +#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) +#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) +#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) +#define CKR_TOKEN_NOT_PRESENT (0xe0UL) +#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) +#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) +#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) +#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) +#define CKR_USER_NOT_LOGGED_IN (0x101UL) +#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) +#define CKR_USER_TYPE_INVALID (0x103UL) +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) +#define CKR_USER_TOO_MANY_TYPES (0x105UL) +#define CKR_WRAPPED_KEY_INVALID (0x110UL) +#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) +#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) +#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) +#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) +#define CKR_RANDOM_NO_RNG (0x121UL) +#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) +#define CKR_BUFFER_TOO_SMALL (0x150UL) +#define CKR_SAVED_STATE_INVALID (0x160UL) +#define CKR_INFORMATION_SENSITIVE (0x170UL) +#define CKR_STATE_UNSAVEABLE (0x180UL) +#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) +#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) +#define CKR_MUTEX_BAD (0x1a0UL) +#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) +#define CKR_NEW_PIN_MODE (0x1b0UL) +#define CKR_NEXT_OTP (0x1b1UL) +#define CKR_EXCEEDED_MAX_ITERATIONS (0x1c0UL) +#define CKR_FIPS_SELF_TEST_FAILED (0x1c1UL) +#define CKR_LIBRARY_LOAD_FAILED (0x1c2UL) +#define CKR_PIN_TOO_WEAK (0x1c3UL) +#define CKR_PUBLIC_KEY_INVALID (0x1c4UL) +#define CKR_FUNCTION_REJECTED (0x200UL) +#define CKR_VENDOR_DEFINED ((unsigned long)(1UL << 31)) -#endif /* _PKCS11_H_ */ +#define CKZ_DATA_SPECIFIED (0x01UL) + +/* Compatibility layer. */ + +#ifdef CRYPTOKI_COMPAT + +#undef CK_DEFINE_FUNCTION +#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name + +/* For NULL. */ +#include <stddef.h> + +typedef unsigned char CK_BYTE; +typedef unsigned char CK_CHAR; +typedef unsigned char CK_UTF8CHAR; +typedef unsigned char CK_BBOOL; +typedef unsigned long int CK_ULONG; +typedef long int CK_LONG; +typedef CK_BYTE * CK_BYTE_PTR; +typedef CK_CHAR * CK_CHAR_PTR; +typedef CK_UTF8CHAR * CK_UTF8CHAR_PTR; +typedef CK_ULONG * CK_ULONG_PTR; +typedef void * CK_VOID_PTR; +typedef void ** CK_VOID_PTR_PTR; +#define CK_FALSE 0 +#define CK_TRUE 1 +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE 0 +#endif /* ifndef FALSE */ +#ifndef TRUE +#define TRUE 1 +#endif /* ifndef TRUE */ +#endif /* ifndef CK_DISABLE_TRUE_FALSE */ + +typedef struct ck_version CK_VERSION; +typedef struct ck_version *CK_VERSION_PTR; + +typedef struct ck_info CK_INFO; +typedef struct ck_info *CK_INFO_PTR; + +typedef ck_slot_id_t *CK_SLOT_ID_PTR; + +typedef struct ck_slot_info CK_SLOT_INFO; +typedef struct ck_slot_info *CK_SLOT_INFO_PTR; + +typedef struct ck_token_info CK_TOKEN_INFO; +typedef struct ck_token_info *CK_TOKEN_INFO_PTR; + +typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; + +typedef struct ck_session_info CK_SESSION_INFO; +typedef struct ck_session_info *CK_SESSION_INFO_PTR; + +typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; + +typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; + +typedef struct ck_attribute CK_ATTRIBUTE; +typedef struct ck_attribute *CK_ATTRIBUTE_PTR; + +typedef struct ck_date CK_DATE; +typedef struct ck_date *CK_DATE_PTR; + +typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; + +typedef struct ck_mechanism CK_MECHANISM; +typedef struct ck_mechanism *CK_MECHANISM_PTR; + +typedef struct ck_mechanism_info CK_MECHANISM_INFO; +typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; + +typedef struct ck_otp_mechanism_info CK_OTP_MECHANISM_INFO; +typedef struct ck_otp_mechanism_info *CK_OTP_MECHANISM_INFO_PTR; + +typedef struct ck_function_list CK_FUNCTION_LIST; +typedef struct ck_function_list * CK_FUNCTION_LIST_PTR; +typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; + +typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; +typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; + +typedef struct ck_rsa_pkcs_pss_params CK_RSA_PKCS_PSS_PARAMS; +typedef struct ck_rsa_pkcs_pss_params *CK_RSA_PKCS_PSS_PARAMS_PTR; + +typedef struct ck_rsa_pkcs_oaep_params CK_RSA_PKCS_OAEP_PARAMS; +typedef struct ck_rsa_pkcs_oaep_params *CK_RSA_PKCS_OAEP_PARAMS_PTR; + +typedef struct ck_aes_ctr_params CK_AES_CTR_PARAMS; +typedef struct ck_aes_ctr_params *CK_AES_CTR_PARAMS_PTR; + +typedef struct ck_gcm_params CK_GCM_PARAMS; +typedef struct ck_gcm_params *CK_GCM_PARAMS_PTR; + +typedef struct ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS; +typedef struct ck_ecdh1_derive_params *CK_ECDH1_DERIVE_PARAMS_PTR; + +typedef struct ck_key_derivation_string_data CK_KEY_DERIVATION_STRING_DATA; +typedef struct ck_key_derivation_string_data *CK_KEY_DERIVATION_STRING_DATA_PTR; + +typedef struct ck_des_cbc_encrypt_data_params CK_DES_CBC_ENCRYPT_DATA_PARAMS; +typedef struct ck_des_cbc_encrypt_data_params + *CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct ck_aes_cbc_encrypt_data_params CK_AES_CBC_ENCRYPT_DATA_PARAMS; +typedef struct ck_aes_cbc_encrypt_data_params + *CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +#ifndef NULL_PTR +#define NULL_PTR NULL +#endif /* ifndef NULL_PTR */ + +/* Delete the helper macros defined at the top of the file. */ +#undef ck_flags_t +#undef ck_version + +#undef ck_info +#undef cryptoki_version +#undef manufacturer_id +#undef library_description +#undef library_version + +#undef ck_notification_t +#undef ck_slot_id_t + +#undef ck_slot_info +#undef slot_description +#undef hardware_version +#undef firmware_version + +#undef ck_token_info +#undef serial_number +#undef max_session_count +#undef session_count +#undef max_rw_session_count +#undef rw_session_count +#undef max_pin_len +#undef min_pin_len +#undef total_public_memory +#undef free_public_memory +#undef total_private_memory +#undef free_private_memory +#undef utc_time + +#undef ck_session_handle_t +#undef ck_user_type_t +#undef ck_state_t + +#undef ck_session_info +#undef slot_id +#undef device_error + +#undef ck_object_handle_t +#undef ck_object_class_t +#undef ck_hw_feature_type_t +#undef ck_key_type_t +#undef ck_certificate_type_t +#undef ck_attribute_type_t + +#undef ck_attribute +#undef value +#undef value_len + +#undef params +#undef count + +#undef ck_date + +#undef ck_mechanism_type_t + +#undef ck_mechanism +#undef parameter +#undef parameter_len + +#undef ck_mechanism_info + +#undef ck_param_type +#undef ck_otp_param +#undef ck_otp_params +#undef ck_otp_signature_info + +#undef min_key_size +#undef max_key_size + +#undef ck_rv_t +#undef ck_notify_t + +#undef ck_function_list + +#undef ck_createmutex_t +#undef ck_destroymutex_t +#undef ck_lockmutex_t +#undef ck_unlockmutex_t + +#undef ck_c_initialize_args +#undef create_mutex +#undef destroy_mutex +#undef lock_mutex +#undef unlock_mutex +#undef reserved + +#endif /* CRYPTOKI_COMPAT */ + +/* System dependencies. */ +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) +#pragma pack(pop, cryptoki) +#endif /* if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) */ + +#if defined(__cplusplus) +} +#endif /* if defined(__cplusplus) */ +#endif /* PKCS11_H */ diff --git a/lib/isc/include/pkcs11/pkcs11f.h b/lib/isc/include/pkcs11/pkcs11f.h deleted file mode 100644 index 48ba5726..00000000 --- a/lib/isc/include/pkcs11/pkcs11f.h +++ /dev/null @@ -1,938 +0,0 @@ -/* - * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01 - * Committee Specification Draft 01 / Public Review Draft 01 - * 09 December 2015 - * Copyright (c) OASIS Open 2015. All Rights Reserved. - * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/ - * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - * https://www.oasis-open.org/policies-guidelines/ipr - */ - -/* This header file contains pretty much everything about all the - * Cryptoki function prototypes. Because this information is - * used for more than just declaring function prototypes, the - * order of the functions appearing herein is important, and - * should not be altered. - */ - -/* General-purpose */ - -/* C_Initialize initializes the Cryptoki library. */ -CK_PKCS11_FUNCTION_INFO(C_Initialize) -#ifdef CK_NEED_ARG_LIST -( - CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets - * cast to CK_C_INITIALIZE_ARGS_PTR - * and dereferenced - */ -); -#endif - - -/* C_Finalize indicates that an application is done with the - * Cryptoki library. - */ -CK_PKCS11_FUNCTION_INFO(C_Finalize) -#ifdef CK_NEED_ARG_LIST -( - CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ -); -#endif - - -/* C_GetInfo returns general information about Cryptoki. */ -CK_PKCS11_FUNCTION_INFO(C_GetInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_INFO_PTR pInfo /* location that receives information */ -); -#endif - - -/* C_GetFunctionList returns the function list. */ -CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) -#ifdef CK_NEED_ARG_LIST -( - CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to - * function list - */ -); -#endif - - - -/* Slot and token management */ - -/* C_GetSlotList obtains a list of slots in the system. */ -CK_PKCS11_FUNCTION_INFO(C_GetSlotList) -#ifdef CK_NEED_ARG_LIST -( - CK_BBOOL tokenPresent, /* only slots with tokens */ - CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ - CK_ULONG_PTR pulCount /* receives number of slots */ -); -#endif - - -/* C_GetSlotInfo obtains information about a particular slot in - * the system. - */ -CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* the ID of the slot */ - CK_SLOT_INFO_PTR pInfo /* receives the slot information */ -); -#endif - - -/* C_GetTokenInfo obtains information about a particular token - * in the system. - */ -CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_TOKEN_INFO_PTR pInfo /* receives the token information */ -); -#endif - - -/* C_GetMechanismList obtains a list of mechanism types - * supported by a token. - */ -CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of token's slot */ - CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ - CK_ULONG_PTR pulCount /* gets # of mechs. */ -); -#endif - - -/* C_GetMechanismInfo obtains information about a particular - * mechanism possibly supported by a token. - */ -CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_MECHANISM_TYPE type, /* type of mechanism */ - CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ -); -#endif - - -/* C_InitToken initializes a token. */ -CK_PKCS11_FUNCTION_INFO(C_InitToken) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ - CK_ULONG ulPinLen, /* length in bytes of the PIN */ - CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ -); -#endif - - -/* C_InitPIN initializes the normal user's PIN. */ -CK_PKCS11_FUNCTION_INFO(C_InitPIN) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ - CK_ULONG ulPinLen /* length in bytes of the PIN */ -); -#endif - - -/* C_SetPIN modifies the PIN of the user who is logged in. */ -CK_PKCS11_FUNCTION_INFO(C_SetPIN) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ - CK_ULONG ulOldLen, /* length of the old PIN */ - CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ - CK_ULONG ulNewLen /* length of the new PIN */ -); -#endif - - - -/* Session management */ - -/* C_OpenSession opens a session between an application and a - * token. - */ -CK_PKCS11_FUNCTION_INFO(C_OpenSession) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* the slot's ID */ - CK_FLAGS flags, /* from CK_SESSION_INFO */ - CK_VOID_PTR pApplication, /* passed to callback */ - CK_NOTIFY Notify, /* callback function */ - CK_SESSION_HANDLE_PTR phSession /* gets session handle */ -); -#endif - - -/* C_CloseSession closes a session between an application and a - * token. - */ -CK_PKCS11_FUNCTION_INFO(C_CloseSession) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_CloseAllSessions closes all sessions with a token. */ -CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID /* the token's slot */ -); -#endif - - -/* C_GetSessionInfo obtains information about the session. */ -CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_SESSION_INFO_PTR pInfo /* receives session info */ -); -#endif - - -/* C_GetOperationState obtains the state of the cryptographic operation - * in a session. - */ -CK_PKCS11_FUNCTION_INFO(C_GetOperationState) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pOperationState, /* gets state */ - CK_ULONG_PTR pulOperationStateLen /* gets state length */ -); -#endif - - -/* C_SetOperationState restores the state of the cryptographic - * operation in a session. - */ -CK_PKCS11_FUNCTION_INFO(C_SetOperationState) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pOperationState, /* holds state */ - CK_ULONG ulOperationStateLen, /* holds state length */ - CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ - CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ -); -#endif - - -/* C_Login logs a user into a token. */ -CK_PKCS11_FUNCTION_INFO(C_Login) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_USER_TYPE userType, /* the user type */ - CK_UTF8CHAR_PTR pPin, /* the user's PIN */ - CK_ULONG ulPinLen /* the length of the PIN */ -); -#endif - - -/* C_Logout logs a user out from a token. */ -CK_PKCS11_FUNCTION_INFO(C_Logout) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - - -/* Object management */ - -/* C_CreateObject creates a new object. */ -CK_PKCS11_FUNCTION_INFO(C_CreateObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ - CK_ULONG ulCount, /* attributes in template */ - CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ -); -#endif - - -/* C_CopyObject copies an object, creating a new object for the - * copy. - */ -CK_PKCS11_FUNCTION_INFO(C_CopyObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ - CK_ULONG ulCount, /* attributes in template */ - CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ -); -#endif - - -/* C_DestroyObject destroys an object. */ -CK_PKCS11_FUNCTION_INFO(C_DestroyObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject /* the object's handle */ -); -#endif - - -/* C_GetObjectSize gets the size of an object in bytes. */ -CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ULONG_PTR pulSize /* receives size of object */ -); -#endif - - -/* C_GetAttributeValue obtains the value of one or more object - * attributes. - */ -CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ - CK_ULONG ulCount /* attributes in template */ -); -#endif - - -/* C_SetAttributeValue modifies the value of one or more object - * attributes. - */ -CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ - CK_ULONG ulCount /* attributes in template */ -); -#endif - - -/* C_FindObjectsInit initializes a search for token and session - * objects that match a template. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ - CK_ULONG ulCount /* attrs in search template */ -); -#endif - - -/* C_FindObjects continues a search for token and session - * objects that match a template, obtaining additional object - * handles. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjects) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ - CK_ULONG ulMaxObjectCount, /* max handles to get */ - CK_ULONG_PTR pulObjectCount /* actual # returned */ -); -#endif - - -/* C_FindObjectsFinal finishes a search for token and session - * objects. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - - -/* Encryption and decryption */ - -/* C_EncryptInit initializes an encryption operation. */ -CK_PKCS11_FUNCTION_INFO(C_EncryptInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ - CK_OBJECT_HANDLE hKey /* handle of encryption key */ -); -#endif - - -/* C_Encrypt encrypts single-part data. */ -CK_PKCS11_FUNCTION_INFO(C_Encrypt) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pData, /* the plaintext data */ - CK_ULONG ulDataLen, /* bytes of plaintext */ - CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ -); -#endif - - -/* C_EncryptUpdate continues a multiple-part encryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext data len */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ -); -#endif - - -/* C_EncryptFinal finishes a multiple-part encryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session handle */ - CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ - CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ -); -#endif - - -/* C_DecryptInit initializes a decryption operation. */ -CK_PKCS11_FUNCTION_INFO(C_DecryptInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ - CK_OBJECT_HANDLE hKey /* handle of decryption key */ -); -#endif - - -/* C_Decrypt decrypts encrypted data in a single part. */ -CK_PKCS11_FUNCTION_INFO(C_Decrypt) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedData, /* ciphertext */ - CK_ULONG ulEncryptedDataLen, /* ciphertext length */ - CK_BYTE_PTR pData, /* gets plaintext */ - CK_ULONG_PTR pulDataLen /* gets p-text size */ -); -#endif - - -/* C_DecryptUpdate continues a multiple-part decryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* encrypted data */ - CK_ULONG ulEncryptedPartLen, /* input length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* p-text size */ -); -#endif - - -/* C_DecryptFinal finishes a multiple-part decryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pLastPart, /* gets plaintext */ - CK_ULONG_PTR pulLastPartLen /* p-text size */ -); -#endif - - - -/* Message digesting */ - -/* C_DigestInit initializes a message-digesting operation. */ -CK_PKCS11_FUNCTION_INFO(C_DigestInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ -); -#endif - - -/* C_Digest digests data in a single part. */ -CK_PKCS11_FUNCTION_INFO(C_Digest) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* data to be digested */ - CK_ULONG ulDataLen, /* bytes of data to digest */ - CK_BYTE_PTR pDigest, /* gets the message digest */ - CK_ULONG_PTR pulDigestLen /* gets digest length */ -); -#endif - - -/* C_DigestUpdate continues a multiple-part message-digesting - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* data to be digested */ - CK_ULONG ulPartLen /* bytes of data to be digested */ -); -#endif - - -/* C_DigestKey continues a multi-part message-digesting - * operation, by digesting the value of a secret key as part of - * the data already digested. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hKey /* secret key to digest */ -); -#endif - - -/* C_DigestFinal finishes a multiple-part message-digesting - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pDigest, /* gets the message digest */ - CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ -); -#endif - - - -/* Signing and MACing */ - -/* C_SignInit initializes a signature (private key encryption) - * operation, where the signature is (will be) an appendix to - * the data, and plaintext cannot be recovered from the - * signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ - CK_OBJECT_HANDLE hKey /* handle of signature key */ -); -#endif - - -/* C_Sign signs (encrypts with private key) data in a single - * part, where the signature is (will be) an appendix to the - * data, and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_Sign) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* the data to sign */ - CK_ULONG ulDataLen, /* count of bytes to sign */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - -/* C_SignUpdate continues a multiple-part signature operation, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* the data to sign */ - CK_ULONG ulPartLen /* count of bytes to sign */ -); -#endif - - -/* C_SignFinal finishes a multiple-part signature operation, - * returning the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - -/* C_SignRecoverInit initializes a signature operation, where - * the data can be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ - CK_OBJECT_HANDLE hKey /* handle of the signature key */ -); -#endif - - -/* C_SignRecover signs data in a single operation, where the - * data can be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignRecover) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* the data to sign */ - CK_ULONG ulDataLen, /* count of bytes to sign */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - - -/* Verifying signatures and MACs */ - -/* C_VerifyInit initializes a verification operation, where the - * signature is an appendix to the data, and plaintext cannot - * cannot be recovered from the signature (e.g. DSA). - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ - CK_OBJECT_HANDLE hKey /* verification key */ -); -#endif - - -/* C_Verify verifies a signature in a single-part operation, - * where the signature is an appendix to the data, and plaintext - * cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_Verify) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* signed data */ - CK_ULONG ulDataLen, /* length of signed data */ - CK_BYTE_PTR pSignature, /* signature */ - CK_ULONG ulSignatureLen /* signature length*/ -); -#endif - - -/* C_VerifyUpdate continues a multiple-part verification - * operation, where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* signed data */ - CK_ULONG ulPartLen /* length of signed data */ -); -#endif - - -/* C_VerifyFinal finishes a multiple-part verification - * operation, checking the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* signature to verify */ - CK_ULONG ulSignatureLen /* signature length */ -); -#endif - - -/* C_VerifyRecoverInit initializes a signature verification - * operation, where the data is recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ - CK_OBJECT_HANDLE hKey /* verification key */ -); -#endif - - -/* C_VerifyRecover verifies a signature in a single-part - * operation, where the data is recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* signature to verify */ - CK_ULONG ulSignatureLen, /* signature length */ - CK_BYTE_PTR pData, /* gets signed data */ - CK_ULONG_PTR pulDataLen /* gets signed data len */ -); -#endif - - - -/* Dual-function cryptographic operations */ - -/* C_DigestEncryptUpdate continues a multiple-part digesting - * and encryption operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext length */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -); -#endif - - -/* C_DecryptDigestUpdate continues a multiple-part decryption and - * digesting operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* ciphertext */ - CK_ULONG ulEncryptedPartLen, /* ciphertext length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* gets plaintext len */ -); -#endif - - -/* C_SignEncryptUpdate continues a multiple-part signing and - * encryption operation. - */ -CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext length */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -); -#endif - - -/* C_DecryptVerifyUpdate continues a multiple-part decryption and - * verify operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* ciphertext */ - CK_ULONG ulEncryptedPartLen, /* ciphertext length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* gets p-text length */ -); -#endif - - - -/* Key management */ - -/* C_GenerateKey generates a secret key, creating a new key - * object. - */ -CK_PKCS11_FUNCTION_INFO(C_GenerateKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* key generation mech. */ - CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ - CK_ULONG ulCount, /* # of attrs in template */ - CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ -); -#endif - - -/* C_GenerateKeyPair generates a public-key/private-key pair, - * creating new key objects. - */ -CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session handle */ - CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ - CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ - CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ - CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ - CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ - CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ -); -#endif - - -/* C_WrapKey wraps (i.e., encrypts) a key. */ -CK_PKCS11_FUNCTION_INFO(C_WrapKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ - CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ - CK_OBJECT_HANDLE hKey, /* key to be wrapped */ - CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ - CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ -); -#endif - - -/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new - * key object. - */ -CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ - CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ - CK_BYTE_PTR pWrappedKey, /* the wrapped key */ - CK_ULONG ulWrappedKeyLen, /* wrapped key len */ - CK_ATTRIBUTE_PTR pTemplate, /* new key template */ - CK_ULONG ulAttributeCount, /* template length */ - CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -); -#endif - - -/* C_DeriveKey derives a key from a base key, creating a new key - * object. - */ -CK_PKCS11_FUNCTION_INFO(C_DeriveKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ - CK_OBJECT_HANDLE hBaseKey, /* base key */ - CK_ATTRIBUTE_PTR pTemplate, /* new key template */ - CK_ULONG ulAttributeCount, /* template length */ - CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -); -#endif - - - -/* Random number generation */ - -/* C_SeedRandom mixes additional seed material into the token's - * random number generator. - */ -CK_PKCS11_FUNCTION_INFO(C_SeedRandom) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSeed, /* the seed material */ - CK_ULONG ulSeedLen /* length of seed material */ -); -#endif - - -/* C_GenerateRandom generates random data. */ -CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR RandomData, /* receives the random data */ - CK_ULONG ulRandomLen /* # of bytes to generate */ -); -#endif - - - -/* Parallel function management */ - -/* C_GetFunctionStatus is a legacy function; it obtains an - * updated status of a function running in parallel with an - * application. - */ -CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_CancelFunction is a legacy function; it cancels a function - * running in parallel. - */ -CK_PKCS11_FUNCTION_INFO(C_CancelFunction) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_WaitForSlotEvent waits for a slot event (token insertion, - * removal, etc.) to occur. - */ -CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) -#ifdef CK_NEED_ARG_LIST -( - CK_FLAGS flags, /* blocking/nonblocking flag */ - CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ - CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ -); -#endif - diff --git a/lib/isc/include/pkcs11/pkcs11t.h b/lib/isc/include/pkcs11/pkcs11t.h deleted file mode 100644 index ed83ed37..00000000 --- a/lib/isc/include/pkcs11/pkcs11t.h +++ /dev/null @@ -1,2006 +0,0 @@ -/* - * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01 - * Committee Specification Draft 01 / Public Review Draft 01 - * 09 December 2015 - * Copyright (c) OASIS Open 2015. All Rights Reserved. - * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/ - * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - * https://www.oasis-open.org/policies-guidelines/ipr - */ - -/* See top of pkcs11.h for information about the macros that - * must be defined and the structure-packing conventions that - * must be set before including this file. - */ - -#ifndef _PKCS11T_H_ -#define _PKCS11T_H_ 1 - -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 40 -#define CRYPTOKI_VERSION_AMENDMENT 0 - -#define CK_TRUE 1 -#define CK_FALSE 0 - -#ifndef CK_DISABLE_TRUE_FALSE -#ifndef FALSE -#define FALSE CK_FALSE -#endif -#ifndef TRUE -#define TRUE CK_TRUE -#endif -#endif - -/* an unsigned 8-bit value */ -typedef unsigned char CK_BYTE; - -/* an unsigned 8-bit character */ -typedef CK_BYTE CK_CHAR; - -/* an 8-bit UTF-8 character */ -typedef CK_BYTE CK_UTF8CHAR; - -/* a BYTE-sized Boolean flag */ -typedef CK_BYTE CK_BBOOL; - -/* an unsigned value, at least 32 bits long */ -typedef unsigned long int CK_ULONG; - -/* a signed value, the same size as a CK_ULONG */ -typedef long int CK_LONG; - -/* at least 32 bits; each bit is a Boolean flag */ -typedef CK_ULONG CK_FLAGS; - - -/* some special values for certain CK_ULONG variables */ -#define CK_UNAVAILABLE_INFORMATION (~0UL) -#define CK_EFFECTIVELY_INFINITE 0UL - - -typedef CK_BYTE CK_PTR CK_BYTE_PTR; -typedef CK_CHAR CK_PTR CK_CHAR_PTR; -typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; -typedef CK_ULONG CK_PTR CK_ULONG_PTR; -typedef void CK_PTR CK_VOID_PTR; - -/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ -typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; - - -/* The following value is always invalid if used as a session - * handle or object handle - */ -#define CK_INVALID_HANDLE 0UL - - -typedef struct CK_VERSION { - CK_BYTE major; /* integer portion of version number */ - CK_BYTE minor; /* 1/100ths portion of version number */ -} CK_VERSION; - -typedef CK_VERSION CK_PTR CK_VERSION_PTR; - - -typedef struct CK_INFO { - CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; /* must be zero */ - CK_UTF8CHAR libraryDescription[32]; /* blank padded */ - CK_VERSION libraryVersion; /* version of library */ -} CK_INFO; - -typedef CK_INFO CK_PTR CK_INFO_PTR; - - -/* CK_NOTIFICATION enumerates the types of notifications that - * Cryptoki provides to an application - */ -typedef CK_ULONG CK_NOTIFICATION; -#define CKN_SURRENDER 0UL -#define CKN_OTP_CHANGED 1UL - -typedef CK_ULONG CK_SLOT_ID; - -typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; - - -/* CK_SLOT_INFO provides information about a slot */ -typedef struct CK_SLOT_INFO { - CK_UTF8CHAR slotDescription[64]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; - - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ -} CK_SLOT_INFO; - -/* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ -#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */ -#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/ -#define CKF_HW_SLOT 0x00000004UL /* hardware slot */ - -typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; - - -/* CK_TOKEN_INFO provides information about a token */ -typedef struct CK_TOKEN_INFO { - CK_UTF8CHAR label[32]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_UTF8CHAR model[16]; /* blank padded */ - CK_CHAR serialNumber[16]; /* blank padded */ - CK_FLAGS flags; /* see below */ - - CK_ULONG ulMaxSessionCount; /* max open sessions */ - CK_ULONG ulSessionCount; /* sess. now open */ - CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ - CK_ULONG ulRwSessionCount; /* R/W sess. now open */ - CK_ULONG ulMaxPinLen; /* in bytes */ - CK_ULONG ulMinPinLen; /* in bytes */ - CK_ULONG ulTotalPublicMemory; /* in bytes */ - CK_ULONG ulFreePublicMemory; /* in bytes */ - CK_ULONG ulTotalPrivateMemory; /* in bytes */ - CK_ULONG ulFreePrivateMemory; /* in bytes */ - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ - CK_CHAR utcTime[16]; /* time */ -} CK_TOKEN_INFO; - -/* The flags parameter is defined as follows: - * Bit Flag Mask Meaning - */ -#define CKF_RNG 0x00000001UL /* has random # generator */ -#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */ -#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */ -#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */ - -/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set, - * that means that *every* time the state of cryptographic - * operations of a session is successfully saved, all keys - * needed to continue those operations are stored in the state - */ -#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL - -/* CKF_CLOCK_ON_TOKEN. If it is set, that means - * that the token has some sort of clock. The time on that - * clock is returned in the token info structure - */ -#define CKF_CLOCK_ON_TOKEN 0x00000040UL - -/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is - * set, that means that there is some way for the user to login - * without sending a PIN through the Cryptoki library itself - */ -#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL - -/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true, - * that means that a single session with the token can perform - * dual simultaneous cryptographic operations (digest and - * encrypt; decrypt and digest; sign and encrypt; and decrypt - * and sign) - */ -#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL - -/* CKF_TOKEN_INITIALIZED. If it is true, the - * token has been initialized using C_InitializeToken or an - * equivalent mechanism outside the scope of PKCS #11. - * Calling C_InitializeToken when this flag is set will cause - * the token to be reinitialized. - */ -#define CKF_TOKEN_INITIALIZED 0x00000400UL - -/* CKF_SECONDARY_AUTHENTICATION. If it is - * true, the token supports secondary authentication for - * private key objects. - */ -#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL - -/* CKF_USER_PIN_COUNT_LOW. If it is true, an - * incorrect user login PIN has been entered at least once - * since the last successful authentication. - */ -#define CKF_USER_PIN_COUNT_LOW 0x00010000UL - -/* CKF_USER_PIN_FINAL_TRY. If it is true, - * supplying an incorrect user PIN will it to become locked. - */ -#define CKF_USER_PIN_FINAL_TRY 0x00020000UL - -/* CKF_USER_PIN_LOCKED. If it is true, the - * user PIN has been locked. User login to the token is not - * possible. - */ -#define CKF_USER_PIN_LOCKED 0x00040000UL - -/* CKF_USER_PIN_TO_BE_CHANGED. If it is true, - * the user PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been - * expired by the card. - */ -#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL - -/* CKF_SO_PIN_COUNT_LOW. If it is true, an - * incorrect SO login PIN has been entered at least once since - * the last successful authentication. - */ -#define CKF_SO_PIN_COUNT_LOW 0x00100000UL - -/* CKF_SO_PIN_FINAL_TRY. If it is true, - * supplying an incorrect SO PIN will it to become locked. - */ -#define CKF_SO_PIN_FINAL_TRY 0x00200000UL - -/* CKF_SO_PIN_LOCKED. If it is true, the SO - * PIN has been locked. SO login to the token is not possible. - */ -#define CKF_SO_PIN_LOCKED 0x00400000UL - -/* CKF_SO_PIN_TO_BE_CHANGED. If it is true, - * the SO PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been - * expired by the card. - */ -#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL - -#define CKF_ERROR_STATE 0x01000000UL - -typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; - - -/* CK_SESSION_HANDLE is a Cryptoki-assigned value that - * identifies a session - */ -typedef CK_ULONG CK_SESSION_HANDLE; - -typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; - - -/* CK_USER_TYPE enumerates the types of Cryptoki users */ -typedef CK_ULONG CK_USER_TYPE; -/* Security Officer */ -#define CKU_SO 0UL -/* Normal user */ -#define CKU_USER 1UL -/* Context specific */ -#define CKU_CONTEXT_SPECIFIC 2UL - -/* CK_STATE enumerates the session states */ -typedef CK_ULONG CK_STATE; -#define CKS_RO_PUBLIC_SESSION 0UL -#define CKS_RO_USER_FUNCTIONS 1UL -#define CKS_RW_PUBLIC_SESSION 2UL -#define CKS_RW_USER_FUNCTIONS 3UL -#define CKS_RW_SO_FUNCTIONS 4UL - -/* CK_SESSION_INFO provides information about a session */ -typedef struct CK_SESSION_INFO { - CK_SLOT_ID slotID; - CK_STATE state; - CK_FLAGS flags; /* see below */ - CK_ULONG ulDeviceError; /* device-dependent error code */ -} CK_SESSION_INFO; - -/* The flags are defined in the following table: - * Bit Flag Mask Meaning - */ -#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ -#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ - -typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; - - -/* CK_OBJECT_HANDLE is a token-specific identifier for an - * object - */ -typedef CK_ULONG CK_OBJECT_HANDLE; - -typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; - - -/* CK_OBJECT_CLASS is a value that identifies the classes (or - * types) of objects that Cryptoki recognizes. It is defined - * as follows: - */ -typedef CK_ULONG CK_OBJECT_CLASS; - -/* The following classes of objects are defined: */ -#define CKO_DATA 0x00000000UL -#define CKO_CERTIFICATE 0x00000001UL -#define CKO_PUBLIC_KEY 0x00000002UL -#define CKO_PRIVATE_KEY 0x00000003UL -#define CKO_SECRET_KEY 0x00000004UL -#define CKO_HW_FEATURE 0x00000005UL -#define CKO_DOMAIN_PARAMETERS 0x00000006UL -#define CKO_MECHANISM 0x00000007UL -#define CKO_OTP_KEY 0x00000008UL - -#define CKO_VENDOR_DEFINED 0x80000000UL - -typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; - -/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type - * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. - */ -typedef CK_ULONG CK_HW_FEATURE_TYPE; - -/* The following hardware feature types are defined */ -#define CKH_MONOTONIC_COUNTER 0x00000001UL -#define CKH_CLOCK 0x00000002UL -#define CKH_USER_INTERFACE 0x00000003UL -#define CKH_VENDOR_DEFINED 0x80000000UL - -/* CK_KEY_TYPE is a value that identifies a key type */ -typedef CK_ULONG CK_KEY_TYPE; - -/* the following key types are defined: */ -#define CKK_RSA 0x00000000UL -#define CKK_DSA 0x00000001UL -#define CKK_DH 0x00000002UL -#define CKK_ECDSA 0x00000003UL /* Deprecated */ -#define CKK_EC 0x00000003UL -#define CKK_X9_42_DH 0x00000004UL -#define CKK_KEA 0x00000005UL -#define CKK_GENERIC_SECRET 0x00000010UL -#define CKK_RC2 0x00000011UL -#define CKK_RC4 0x00000012UL -#define CKK_DES 0x00000013UL -#define CKK_DES2 0x00000014UL -#define CKK_DES3 0x00000015UL -#define CKK_CAST 0x00000016UL -#define CKK_CAST3 0x00000017UL -#define CKK_CAST5 0x00000018UL /* Deprecated */ -#define CKK_CAST128 0x00000018UL -#define CKK_RC5 0x00000019UL -#define CKK_IDEA 0x0000001AUL -#define CKK_SKIPJACK 0x0000001BUL -#define CKK_BATON 0x0000001CUL -#define CKK_JUNIPER 0x0000001DUL -#define CKK_CDMF 0x0000001EUL -#define CKK_AES 0x0000001FUL -#define CKK_BLOWFISH 0x00000020UL -#define CKK_TWOFISH 0x00000021UL -#define CKK_SECURID 0x00000022UL -#define CKK_HOTP 0x00000023UL -#define CKK_ACTI 0x00000024UL -#define CKK_CAMELLIA 0x00000025UL -#define CKK_ARIA 0x00000026UL - -#define CKK_MD5_HMAC 0x00000027UL -#define CKK_SHA_1_HMAC 0x00000028UL -#define CKK_RIPEMD128_HMAC 0x00000029UL -#define CKK_RIPEMD160_HMAC 0x0000002AUL -#define CKK_SHA256_HMAC 0x0000002BUL -#define CKK_SHA384_HMAC 0x0000002CUL -#define CKK_SHA512_HMAC 0x0000002DUL -#define CKK_SHA224_HMAC 0x0000002EUL - -#define CKK_SEED 0x0000002FUL -#define CKK_GOSTR3410 0x00000030UL -#define CKK_GOSTR3411 0x00000031UL -#define CKK_GOST28147 0x00000032UL - - - -#define CKK_VENDOR_DEFINED 0x80000000UL - - -/* CK_CERTIFICATE_TYPE is a value that identifies a certificate - * type - */ -typedef CK_ULONG CK_CERTIFICATE_TYPE; - -#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL -#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL -#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL -#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL - -#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL -#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL -#define CK_SECURITY_DOMAIN_OPERATOR 2UL -#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL - - -/* The following certificate types are defined: */ -#define CKC_X_509 0x00000000UL -#define CKC_X_509_ATTR_CERT 0x00000001UL -#define CKC_WTLS 0x00000002UL -#define CKC_VENDOR_DEFINED 0x80000000UL - - -/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute - * type - */ -typedef CK_ULONG CK_ATTRIBUTE_TYPE; - -/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which - * consists of an array of values. - */ -#define CKF_ARRAY_ATTRIBUTE 0x40000000UL - -/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */ -#define CK_OTP_FORMAT_DECIMAL 0UL -#define CK_OTP_FORMAT_HEXADECIMAL 1UL -#define CK_OTP_FORMAT_ALPHANUMERIC 2UL -#define CK_OTP_FORMAT_BINARY 3UL - -/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT - * attributes - */ -#define CK_OTP_PARAM_IGNORED 0UL -#define CK_OTP_PARAM_OPTIONAL 1UL -#define CK_OTP_PARAM_MANDATORY 2UL - -/* The following attribute types are defined: */ -#define CKA_CLASS 0x00000000UL -#define CKA_TOKEN 0x00000001UL -#define CKA_PRIVATE 0x00000002UL -#define CKA_LABEL 0x00000003UL -#define CKA_APPLICATION 0x00000010UL -#define CKA_VALUE 0x00000011UL -#define CKA_OBJECT_ID 0x00000012UL -#define CKA_CERTIFICATE_TYPE 0x00000080UL -#define CKA_ISSUER 0x00000081UL -#define CKA_SERIAL_NUMBER 0x00000082UL -#define CKA_AC_ISSUER 0x00000083UL -#define CKA_OWNER 0x00000084UL -#define CKA_ATTR_TYPES 0x00000085UL -#define CKA_TRUSTED 0x00000086UL -#define CKA_CERTIFICATE_CATEGORY 0x00000087UL -#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL -#define CKA_URL 0x00000089UL -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL -#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL -#define CKA_CHECK_VALUE 0x00000090UL - -#define CKA_KEY_TYPE 0x00000100UL -#define CKA_SUBJECT 0x00000101UL -#define CKA_ID 0x00000102UL -#define CKA_SENSITIVE 0x00000103UL -#define CKA_ENCRYPT 0x00000104UL -#define CKA_DECRYPT 0x00000105UL -#define CKA_WRAP 0x00000106UL -#define CKA_UNWRAP 0x00000107UL -#define CKA_SIGN 0x00000108UL -#define CKA_SIGN_RECOVER 0x00000109UL -#define CKA_VERIFY 0x0000010AUL -#define CKA_VERIFY_RECOVER 0x0000010BUL -#define CKA_DERIVE 0x0000010CUL -#define CKA_START_DATE 0x00000110UL -#define CKA_END_DATE 0x00000111UL -#define CKA_MODULUS 0x00000120UL -#define CKA_MODULUS_BITS 0x00000121UL -#define CKA_PUBLIC_EXPONENT 0x00000122UL -#define CKA_PRIVATE_EXPONENT 0x00000123UL -#define CKA_PRIME_1 0x00000124UL -#define CKA_PRIME_2 0x00000125UL -#define CKA_EXPONENT_1 0x00000126UL -#define CKA_EXPONENT_2 0x00000127UL -#define CKA_COEFFICIENT 0x00000128UL -#define CKA_PUBLIC_KEY_INFO 0x00000129UL -#define CKA_PRIME 0x00000130UL -#define CKA_SUBPRIME 0x00000131UL -#define CKA_BASE 0x00000132UL - -#define CKA_PRIME_BITS 0x00000133UL -#define CKA_SUBPRIME_BITS 0x00000134UL -#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS - -#define CKA_VALUE_BITS 0x00000160UL -#define CKA_VALUE_LEN 0x00000161UL -#define CKA_EXTRACTABLE 0x00000162UL -#define CKA_LOCAL 0x00000163UL -#define CKA_NEVER_EXTRACTABLE 0x00000164UL -#define CKA_ALWAYS_SENSITIVE 0x00000165UL -#define CKA_KEY_GEN_MECHANISM 0x00000166UL - -#define CKA_MODIFIABLE 0x00000170UL -#define CKA_COPYABLE 0x00000171UL - -#define CKA_DESTROYABLE 0x00000172UL - -#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */ -#define CKA_EC_PARAMS 0x00000180UL - -#define CKA_EC_POINT 0x00000181UL - -#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */ -#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */ - -#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL - -#define CKA_WRAP_WITH_TRUSTED 0x00000210UL -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL) -#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL) - -#define CKA_OTP_FORMAT 0x00000220UL -#define CKA_OTP_LENGTH 0x00000221UL -#define CKA_OTP_TIME_INTERVAL 0x00000222UL -#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL -#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL -#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL -#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL -#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL -#define CKA_OTP_COUNTER 0x0000022EUL -#define CKA_OTP_TIME 0x0000022FUL -#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL -#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL -#define CKA_OTP_SERVICE_LOGO 0x0000022CUL -#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL - -#define CKA_GOSTR3410_PARAMS 0x00000250UL -#define CKA_GOSTR3411_PARAMS 0x00000251UL -#define CKA_GOST28147_PARAMS 0x00000252UL - -#define CKA_HW_FEATURE_TYPE 0x00000300UL -#define CKA_RESET_ON_INIT 0x00000301UL -#define CKA_HAS_RESET 0x00000302UL - -#define CKA_PIXEL_X 0x00000400UL -#define CKA_PIXEL_Y 0x00000401UL -#define CKA_RESOLUTION 0x00000402UL -#define CKA_CHAR_ROWS 0x00000403UL -#define CKA_CHAR_COLUMNS 0x00000404UL -#define CKA_COLOR 0x00000405UL -#define CKA_BITS_PER_PIXEL 0x00000406UL -#define CKA_CHAR_SETS 0x00000480UL -#define CKA_ENCODING_METHODS 0x00000481UL -#define CKA_MIME_TYPES 0x00000482UL -#define CKA_MECHANISM_TYPE 0x00000500UL -#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL -#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL -#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL) - -#define CKA_VENDOR_DEFINED 0x80000000UL - -/* CK_ATTRIBUTE is a structure that includes the type, length - * and value of an attribute - */ -typedef struct CK_ATTRIBUTE { - CK_ATTRIBUTE_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; /* in bytes */ -} CK_ATTRIBUTE; - -typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; - -/* CK_DATE is a structure that defines a date */ -typedef struct CK_DATE{ - CK_CHAR year[4]; /* the year ("1900" - "9999") */ - CK_CHAR month[2]; /* the month ("01" - "12") */ - CK_CHAR day[2]; /* the day ("01" - "31") */ -} CK_DATE; - - -/* CK_MECHANISM_TYPE is a value that identifies a mechanism - * type - */ -typedef CK_ULONG CK_MECHANISM_TYPE; - -/* the following mechanism types are defined: */ -#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL -#define CKM_RSA_PKCS 0x00000001UL -#define CKM_RSA_9796 0x00000002UL -#define CKM_RSA_X_509 0x00000003UL - -#define CKM_MD2_RSA_PKCS 0x00000004UL -#define CKM_MD5_RSA_PKCS 0x00000005UL -#define CKM_SHA1_RSA_PKCS 0x00000006UL - -#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL -#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL -#define CKM_RSA_PKCS_OAEP 0x00000009UL - -#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL -#define CKM_RSA_X9_31 0x0000000BUL -#define CKM_SHA1_RSA_X9_31 0x0000000CUL -#define CKM_RSA_PKCS_PSS 0x0000000DUL -#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL - -#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL -#define CKM_DSA 0x00000011UL -#define CKM_DSA_SHA1 0x00000012UL -#define CKM_DSA_SHA224 0x00000013UL -#define CKM_DSA_SHA256 0x00000014UL -#define CKM_DSA_SHA384 0x00000015UL -#define CKM_DSA_SHA512 0x00000016UL - -#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL -#define CKM_DH_PKCS_DERIVE 0x00000021UL - -#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL -#define CKM_X9_42_DH_DERIVE 0x00000031UL -#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL -#define CKM_X9_42_MQV_DERIVE 0x00000033UL - -#define CKM_SHA256_RSA_PKCS 0x00000040UL -#define CKM_SHA384_RSA_PKCS 0x00000041UL -#define CKM_SHA512_RSA_PKCS 0x00000042UL -#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL -#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL -#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL - -#define CKM_SHA224_RSA_PKCS 0x00000046UL -#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL - -#define CKM_SHA512_224 0x00000048UL -#define CKM_SHA512_224_HMAC 0x00000049UL -#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL -#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL -#define CKM_SHA512_256 0x0000004CUL -#define CKM_SHA512_256_HMAC 0x0000004DUL -#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL -#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL - -#define CKM_SHA512_T 0x00000050UL -#define CKM_SHA512_T_HMAC 0x00000051UL -#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL -#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL - -#define CKM_RC2_KEY_GEN 0x00000100UL -#define CKM_RC2_ECB 0x00000101UL -#define CKM_RC2_CBC 0x00000102UL -#define CKM_RC2_MAC 0x00000103UL - -#define CKM_RC2_MAC_GENERAL 0x00000104UL -#define CKM_RC2_CBC_PAD 0x00000105UL - -#define CKM_RC4_KEY_GEN 0x00000110UL -#define CKM_RC4 0x00000111UL -#define CKM_DES_KEY_GEN 0x00000120UL -#define CKM_DES_ECB 0x00000121UL -#define CKM_DES_CBC 0x00000122UL -#define CKM_DES_MAC 0x00000123UL - -#define CKM_DES_MAC_GENERAL 0x00000124UL -#define CKM_DES_CBC_PAD 0x00000125UL - -#define CKM_DES2_KEY_GEN 0x00000130UL -#define CKM_DES3_KEY_GEN 0x00000131UL -#define CKM_DES3_ECB 0x00000132UL -#define CKM_DES3_CBC 0x00000133UL -#define CKM_DES3_MAC 0x00000134UL - -#define CKM_DES3_MAC_GENERAL 0x00000135UL -#define CKM_DES3_CBC_PAD 0x00000136UL -#define CKM_DES3_CMAC_GENERAL 0x00000137UL -#define CKM_DES3_CMAC 0x00000138UL -#define CKM_CDMF_KEY_GEN 0x00000140UL -#define CKM_CDMF_ECB 0x00000141UL -#define CKM_CDMF_CBC 0x00000142UL -#define CKM_CDMF_MAC 0x00000143UL -#define CKM_CDMF_MAC_GENERAL 0x00000144UL -#define CKM_CDMF_CBC_PAD 0x00000145UL - -#define CKM_DES_OFB64 0x00000150UL -#define CKM_DES_OFB8 0x00000151UL -#define CKM_DES_CFB64 0x00000152UL -#define CKM_DES_CFB8 0x00000153UL - -#define CKM_MD2 0x00000200UL - -#define CKM_MD2_HMAC 0x00000201UL -#define CKM_MD2_HMAC_GENERAL 0x00000202UL - -#define CKM_MD5 0x00000210UL - -#define CKM_MD5_HMAC 0x00000211UL -#define CKM_MD5_HMAC_GENERAL 0x00000212UL - -#define CKM_SHA_1 0x00000220UL - -#define CKM_SHA_1_HMAC 0x00000221UL -#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL - -#define CKM_RIPEMD128 0x00000230UL -#define CKM_RIPEMD128_HMAC 0x00000231UL -#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL -#define CKM_RIPEMD160 0x00000240UL -#define CKM_RIPEMD160_HMAC 0x00000241UL -#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL - -#define CKM_SHA256 0x00000250UL -#define CKM_SHA256_HMAC 0x00000251UL -#define CKM_SHA256_HMAC_GENERAL 0x00000252UL -#define CKM_SHA224 0x00000255UL -#define CKM_SHA224_HMAC 0x00000256UL -#define CKM_SHA224_HMAC_GENERAL 0x00000257UL -#define CKM_SHA384 0x00000260UL -#define CKM_SHA384_HMAC 0x00000261UL -#define CKM_SHA384_HMAC_GENERAL 0x00000262UL -#define CKM_SHA512 0x00000270UL -#define CKM_SHA512_HMAC 0x00000271UL -#define CKM_SHA512_HMAC_GENERAL 0x00000272UL -#define CKM_SECURID_KEY_GEN 0x00000280UL -#define CKM_SECURID 0x00000282UL -#define CKM_HOTP_KEY_GEN 0x00000290UL -#define CKM_HOTP 0x00000291UL -#define CKM_ACTI 0x000002A0UL -#define CKM_ACTI_KEY_GEN 0x000002A1UL - -#define CKM_CAST_KEY_GEN 0x00000300UL -#define CKM_CAST_ECB 0x00000301UL -#define CKM_CAST_CBC 0x00000302UL -#define CKM_CAST_MAC 0x00000303UL -#define CKM_CAST_MAC_GENERAL 0x00000304UL -#define CKM_CAST_CBC_PAD 0x00000305UL -#define CKM_CAST3_KEY_GEN 0x00000310UL -#define CKM_CAST3_ECB 0x00000311UL -#define CKM_CAST3_CBC 0x00000312UL -#define CKM_CAST3_MAC 0x00000313UL -#define CKM_CAST3_MAC_GENERAL 0x00000314UL -#define CKM_CAST3_CBC_PAD 0x00000315UL -/* Note that CAST128 and CAST5 are the same algorithm */ -#define CKM_CAST5_KEY_GEN 0x00000320UL -#define CKM_CAST128_KEY_GEN 0x00000320UL -#define CKM_CAST5_ECB 0x00000321UL -#define CKM_CAST128_ECB 0x00000321UL -#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */ -#define CKM_CAST128_CBC 0x00000322UL -#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */ -#define CKM_CAST128_MAC 0x00000323UL -#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */ -#define CKM_CAST128_MAC_GENERAL 0x00000324UL -#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */ -#define CKM_CAST128_CBC_PAD 0x00000325UL -#define CKM_RC5_KEY_GEN 0x00000330UL -#define CKM_RC5_ECB 0x00000331UL -#define CKM_RC5_CBC 0x00000332UL -#define CKM_RC5_MAC 0x00000333UL -#define CKM_RC5_MAC_GENERAL 0x00000334UL -#define CKM_RC5_CBC_PAD 0x00000335UL -#define CKM_IDEA_KEY_GEN 0x00000340UL -#define CKM_IDEA_ECB 0x00000341UL -#define CKM_IDEA_CBC 0x00000342UL -#define CKM_IDEA_MAC 0x00000343UL -#define CKM_IDEA_MAC_GENERAL 0x00000344UL -#define CKM_IDEA_CBC_PAD 0x00000345UL -#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL -#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL -#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL -#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL -#define CKM_XOR_BASE_AND_DATA 0x00000364UL -#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL -#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL -#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL -#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL - -#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL -#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL -#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL -#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL -#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL - -#define CKM_TLS_PRF 0x00000378UL - -#define CKM_SSL3_MD5_MAC 0x00000380UL -#define CKM_SSL3_SHA1_MAC 0x00000381UL -#define CKM_MD5_KEY_DERIVATION 0x00000390UL -#define CKM_MD2_KEY_DERIVATION 0x00000391UL -#define CKM_SHA1_KEY_DERIVATION 0x00000392UL - -#define CKM_SHA256_KEY_DERIVATION 0x00000393UL -#define CKM_SHA384_KEY_DERIVATION 0x00000394UL -#define CKM_SHA512_KEY_DERIVATION 0x00000395UL -#define CKM_SHA224_KEY_DERIVATION 0x00000396UL - -#define CKM_PBE_MD2_DES_CBC 0x000003A0UL -#define CKM_PBE_MD5_DES_CBC 0x000003A1UL -#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL -#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL -#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */ -#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL -#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */ -#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL -#define CKM_PBE_SHA1_RC4_128 0x000003A6UL -#define CKM_PBE_SHA1_RC4_40 0x000003A7UL -#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL -#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL -#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL -#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL - -#define CKM_PKCS5_PBKD2 0x000003B0UL - -#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL - -#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL -#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL -#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL -#define CKM_WTLS_PRF 0x000003D3UL -#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL -#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL - -#define CKM_TLS10_MAC_SERVER 0x000003D6UL -#define CKM_TLS10_MAC_CLIENT 0x000003D7UL -#define CKM_TLS12_MAC 0x000003D8UL -#define CKM_TLS12_KDF 0x000003D9UL -#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL -#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL -#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL -#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL -#define CKM_TLS_MAC 0x000003E4UL -#define CKM_TLS_KDF 0x000003E5UL - -#define CKM_KEY_WRAP_LYNKS 0x00000400UL -#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL - -#define CKM_CMS_SIG 0x00000500UL -#define CKM_KIP_DERIVE 0x00000510UL -#define CKM_KIP_WRAP 0x00000511UL -#define CKM_KIP_MAC 0x00000512UL - -#define CKM_CAMELLIA_KEY_GEN 0x00000550UL -#define CKM_CAMELLIA_ECB 0x00000551UL -#define CKM_CAMELLIA_CBC 0x00000552UL -#define CKM_CAMELLIA_MAC 0x00000553UL -#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL -#define CKM_CAMELLIA_CBC_PAD 0x00000555UL -#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL -#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL -#define CKM_CAMELLIA_CTR 0x00000558UL - -#define CKM_ARIA_KEY_GEN 0x00000560UL -#define CKM_ARIA_ECB 0x00000561UL -#define CKM_ARIA_CBC 0x00000562UL -#define CKM_ARIA_MAC 0x00000563UL -#define CKM_ARIA_MAC_GENERAL 0x00000564UL -#define CKM_ARIA_CBC_PAD 0x00000565UL -#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL -#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL - -#define CKM_SEED_KEY_GEN 0x00000650UL -#define CKM_SEED_ECB 0x00000651UL -#define CKM_SEED_CBC 0x00000652UL -#define CKM_SEED_MAC 0x00000653UL -#define CKM_SEED_MAC_GENERAL 0x00000654UL -#define CKM_SEED_CBC_PAD 0x00000655UL -#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL -#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL - -#define CKM_SKIPJACK_KEY_GEN 0x00001000UL -#define CKM_SKIPJACK_ECB64 0x00001001UL -#define CKM_SKIPJACK_CBC64 0x00001002UL -#define CKM_SKIPJACK_OFB64 0x00001003UL -#define CKM_SKIPJACK_CFB64 0x00001004UL -#define CKM_SKIPJACK_CFB32 0x00001005UL -#define CKM_SKIPJACK_CFB16 0x00001006UL -#define CKM_SKIPJACK_CFB8 0x00001007UL -#define CKM_SKIPJACK_WRAP 0x00001008UL -#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL -#define CKM_SKIPJACK_RELAYX 0x0000100aUL -#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL -#define CKM_KEA_KEY_DERIVE 0x00001011UL -#define CKM_KEA_DERIVE 0x00001012UL -#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL -#define CKM_BATON_KEY_GEN 0x00001030UL -#define CKM_BATON_ECB128 0x00001031UL -#define CKM_BATON_ECB96 0x00001032UL -#define CKM_BATON_CBC128 0x00001033UL -#define CKM_BATON_COUNTER 0x00001034UL -#define CKM_BATON_SHUFFLE 0x00001035UL -#define CKM_BATON_WRAP 0x00001036UL - -#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */ -#define CKM_EC_KEY_PAIR_GEN 0x00001040UL - -#define CKM_ECDSA 0x00001041UL -#define CKM_ECDSA_SHA1 0x00001042UL -#define CKM_ECDSA_SHA224 0x00001043UL -#define CKM_ECDSA_SHA256 0x00001044UL -#define CKM_ECDSA_SHA384 0x00001045UL -#define CKM_ECDSA_SHA512 0x00001046UL - -#define CKM_ECDH1_DERIVE 0x00001050UL -#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL -#define CKM_ECMQV_DERIVE 0x00001052UL - -#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL -#define CKM_RSA_AES_KEY_WRAP 0x00001054UL - -#define CKM_JUNIPER_KEY_GEN 0x00001060UL -#define CKM_JUNIPER_ECB128 0x00001061UL -#define CKM_JUNIPER_CBC128 0x00001062UL -#define CKM_JUNIPER_COUNTER 0x00001063UL -#define CKM_JUNIPER_SHUFFLE 0x00001064UL -#define CKM_JUNIPER_WRAP 0x00001065UL -#define CKM_FASTHASH 0x00001070UL - -#define CKM_AES_KEY_GEN 0x00001080UL -#define CKM_AES_ECB 0x00001081UL -#define CKM_AES_CBC 0x00001082UL -#define CKM_AES_MAC 0x00001083UL -#define CKM_AES_MAC_GENERAL 0x00001084UL -#define CKM_AES_CBC_PAD 0x00001085UL -#define CKM_AES_CTR 0x00001086UL -#define CKM_AES_GCM 0x00001087UL -#define CKM_AES_CCM 0x00001088UL -#define CKM_AES_CTS 0x00001089UL -#define CKM_AES_CMAC 0x0000108AUL -#define CKM_AES_CMAC_GENERAL 0x0000108BUL - -#define CKM_AES_XCBC_MAC 0x0000108CUL -#define CKM_AES_XCBC_MAC_96 0x0000108DUL -#define CKM_AES_GMAC 0x0000108EUL - -#define CKM_BLOWFISH_KEY_GEN 0x00001090UL -#define CKM_BLOWFISH_CBC 0x00001091UL -#define CKM_TWOFISH_KEY_GEN 0x00001092UL -#define CKM_TWOFISH_CBC 0x00001093UL -#define CKM_BLOWFISH_CBC_PAD 0x00001094UL -#define CKM_TWOFISH_CBC_PAD 0x00001095UL - -#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL -#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL -#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL -#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL -#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL -#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL - -#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL -#define CKM_GOSTR3410 0x00001201UL -#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL -#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL -#define CKM_GOSTR3410_DERIVE 0x00001204UL -#define CKM_GOSTR3411 0x00001210UL -#define CKM_GOSTR3411_HMAC 0x00001211UL -#define CKM_GOST28147_KEY_GEN 0x00001220UL -#define CKM_GOST28147_ECB 0x00001221UL -#define CKM_GOST28147 0x00001222UL -#define CKM_GOST28147_MAC 0x00001223UL -#define CKM_GOST28147_KEY_WRAP 0x00001224UL - -#define CKM_DSA_PARAMETER_GEN 0x00002000UL -#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL -#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL -#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL -#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL - -#define CKM_AES_OFB 0x00002104UL -#define CKM_AES_CFB64 0x00002105UL -#define CKM_AES_CFB8 0x00002106UL -#define CKM_AES_CFB128 0x00002107UL - -#define CKM_AES_CFB1 0x00002108UL -#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */ -#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */ - -#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL -#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL - -#define CKM_VENDOR_DEFINED 0x80000000UL - -typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; - - -/* CK_MECHANISM is a structure that specifies a particular - * mechanism - */ -typedef struct CK_MECHANISM { - CK_MECHANISM_TYPE mechanism; - CK_VOID_PTR pParameter; - CK_ULONG ulParameterLen; /* in bytes */ -} CK_MECHANISM; - -typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; - - -/* CK_MECHANISM_INFO provides information about a particular - * mechanism - */ -typedef struct CK_MECHANISM_INFO { - CK_ULONG ulMinKeySize; - CK_ULONG ulMaxKeySize; - CK_FLAGS flags; -} CK_MECHANISM_INFO; - -/* The flags are defined as follows: - * Bit Flag Mask Meaning */ -#define CKF_HW 0x00000001UL /* performed by HW */ - -/* Specify whether or not a mechanism can be used for a particular task */ -#define CKF_ENCRYPT 0x00000100UL -#define CKF_DECRYPT 0x00000200UL -#define CKF_DIGEST 0x00000400UL -#define CKF_SIGN 0x00000800UL -#define CKF_SIGN_RECOVER 0x00001000UL -#define CKF_VERIFY 0x00002000UL -#define CKF_VERIFY_RECOVER 0x00004000UL -#define CKF_GENERATE 0x00008000UL -#define CKF_GENERATE_KEY_PAIR 0x00010000UL -#define CKF_WRAP 0x00020000UL -#define CKF_UNWRAP 0x00040000UL -#define CKF_DERIVE 0x00080000UL - -/* Describe a token's EC capabilities not available in mechanism - * information. - */ -#define CKF_EC_F_P 0x00100000UL -#define CKF_EC_F_2M 0x00200000UL -#define CKF_EC_ECPARAMETERS 0x00400000UL -#define CKF_EC_NAMEDCURVE 0x00800000UL -#define CKF_EC_UNCOMPRESS 0x01000000UL -#define CKF_EC_COMPRESS 0x02000000UL - -#define CKF_EXTENSION 0x80000000UL - -typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; - -/* CK_RV is a value that identifies the return value of a - * Cryptoki function - */ -typedef CK_ULONG CK_RV; - -#define CKR_OK 0x00000000UL -#define CKR_CANCEL 0x00000001UL -#define CKR_HOST_MEMORY 0x00000002UL -#define CKR_SLOT_ID_INVALID 0x00000003UL - -#define CKR_GENERAL_ERROR 0x00000005UL -#define CKR_FUNCTION_FAILED 0x00000006UL - -#define CKR_ARGUMENTS_BAD 0x00000007UL -#define CKR_NO_EVENT 0x00000008UL -#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL -#define CKR_CANT_LOCK 0x0000000AUL - -#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL -#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL -#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL -#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL - -#define CKR_ACTION_PROHIBITED 0x0000001BUL - -#define CKR_DATA_INVALID 0x00000020UL -#define CKR_DATA_LEN_RANGE 0x00000021UL -#define CKR_DEVICE_ERROR 0x00000030UL -#define CKR_DEVICE_MEMORY 0x00000031UL -#define CKR_DEVICE_REMOVED 0x00000032UL -#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL -#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL -#define CKR_FUNCTION_CANCELED 0x00000050UL -#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL - -#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL - -#define CKR_KEY_HANDLE_INVALID 0x00000060UL - -#define CKR_KEY_SIZE_RANGE 0x00000062UL -#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL - -#define CKR_KEY_NOT_NEEDED 0x00000064UL -#define CKR_KEY_CHANGED 0x00000065UL -#define CKR_KEY_NEEDED 0x00000066UL -#define CKR_KEY_INDIGESTIBLE 0x00000067UL -#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL -#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL -#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL - -#define CKR_MECHANISM_INVALID 0x00000070UL -#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL - -#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL -#define CKR_OPERATION_ACTIVE 0x00000090UL -#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL -#define CKR_PIN_INCORRECT 0x000000A0UL -#define CKR_PIN_INVALID 0x000000A1UL -#define CKR_PIN_LEN_RANGE 0x000000A2UL - -#define CKR_PIN_EXPIRED 0x000000A3UL -#define CKR_PIN_LOCKED 0x000000A4UL - -#define CKR_SESSION_CLOSED 0x000000B0UL -#define CKR_SESSION_COUNT 0x000000B1UL -#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL -#define CKR_SESSION_READ_ONLY 0x000000B5UL -#define CKR_SESSION_EXISTS 0x000000B6UL - -#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL -#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL - -#define CKR_SIGNATURE_INVALID 0x000000C0UL -#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL -#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL -#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL -#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL -#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL -#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL -#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL -#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL -#define CKR_USER_NOT_LOGGED_IN 0x00000101UL -#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL -#define CKR_USER_TYPE_INVALID 0x00000103UL - -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL -#define CKR_USER_TOO_MANY_TYPES 0x00000105UL - -#define CKR_WRAPPED_KEY_INVALID 0x00000110UL -#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL -#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL -#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL -#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL - -#define CKR_RANDOM_NO_RNG 0x00000121UL - -#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL - -#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL - -#define CKR_BUFFER_TOO_SMALL 0x00000150UL -#define CKR_SAVED_STATE_INVALID 0x00000160UL -#define CKR_INFORMATION_SENSITIVE 0x00000170UL -#define CKR_STATE_UNSAVEABLE 0x00000180UL - -#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL -#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL -#define CKR_MUTEX_BAD 0x000001A0UL -#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL - -#define CKR_NEW_PIN_MODE 0x000001B0UL -#define CKR_NEXT_OTP 0x000001B1UL - -#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL -#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL -#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL -#define CKR_PIN_TOO_WEAK 0x000001B8UL -#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL - -#define CKR_FUNCTION_REJECTED 0x00000200UL - -#define CKR_VENDOR_DEFINED 0x80000000UL - -/* private extra values */ -#define CKR_LIBRARY_ALREADY_INITIALIZED 0x000000FDUL -#define CKR_LIBRARY_FAILED_TO_LOAD 0x000000FEUL -#define CKR_SYMBOL_RESOLUTION_FAILED 0x000000FFUL - -/* CK_NOTIFY is an application callback that processes events */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_NOTIFICATION event, - CK_VOID_PTR pApplication /* passed to C_OpenSession */ -); - - -/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec - * version and pointers of appropriate types to all the - * Cryptoki functions - */ -typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; - -typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; - -typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; - - -/* CK_CREATEMUTEX is an application callback for creating a - * mutex object - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( - CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ -); - - -/* CK_DESTROYMUTEX is an application callback for destroying a - * mutex object - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_LOCKMUTEX is an application callback for locking a mutex */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_UNLOCKMUTEX is an application callback for unlocking a - * mutex - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_C_INITIALIZE_ARGS provides the optional arguments to - * C_Initialize - */ -typedef struct CK_C_INITIALIZE_ARGS { - CK_CREATEMUTEX CreateMutex; - CK_DESTROYMUTEX DestroyMutex; - CK_LOCKMUTEX LockMutex; - CK_UNLOCKMUTEX UnlockMutex; - CK_FLAGS flags; - CK_VOID_PTR pReserved; -} CK_C_INITIALIZE_ARGS; - -/* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL -#define CKF_OS_LOCKING_OK 0x00000002UL - -typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; - - -/* additional flags for parameters to functions */ - -/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ -#define CKF_DONT_BLOCK 1 - -/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message - * Generation Function (MGF) applied to a message block when - * formatting a message block for the PKCS #1 OAEP encryption - * scheme. - */ -typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; - -typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; - -/* The following MGFs are defined */ -#define CKG_MGF1_SHA1 0x00000001UL -#define CKG_MGF1_SHA256 0x00000002UL -#define CKG_MGF1_SHA384 0x00000003UL -#define CKG_MGF1_SHA512 0x00000004UL -#define CKG_MGF1_SHA224 0x00000005UL - -/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source - * of the encoding parameter when formatting a message block - * for the PKCS #1 OAEP encryption scheme. - */ -typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; - -typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; - -/* The following encoding parameter sources are defined */ -#define CKZ_DATA_SPECIFIED 0x00000001UL - -/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the - * CKM_RSA_PKCS_OAEP mechanism. - */ -typedef struct CK_RSA_PKCS_OAEP_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; - CK_VOID_PTR pSourceData; - CK_ULONG ulSourceDataLen; -} CK_RSA_PKCS_OAEP_PARAMS; - -typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; - -/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the - * CKM_RSA_PKCS_PSS mechanism(s). - */ -typedef struct CK_RSA_PKCS_PSS_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_ULONG sLen; -} CK_RSA_PKCS_PSS_PARAMS; - -typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; - -typedef CK_ULONG CK_EC_KDF_TYPE; - -/* The following EC Key Derivation Functions are defined */ -#define CKD_NULL 0x00000001UL -#define CKD_SHA1_KDF 0x00000002UL - -/* The following X9.42 DH key derivation functions are defined */ -#define CKD_SHA1_KDF_ASN1 0x00000003UL -#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL -#define CKD_SHA224_KDF 0x00000005UL -#define CKD_SHA256_KDF 0x00000006UL -#define CKD_SHA384_KDF 0x00000007UL -#define CKD_SHA512_KDF 0x00000008UL -#define CKD_CPDIVERSIFY_KDF 0x00000009UL - - -/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the - * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, - * where each party contributes one key pair. - */ -typedef struct CK_ECDH1_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_ECDH1_DERIVE_PARAMS; - -typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; - -/* - * CK_ECDH2_DERIVE_PARAMS provides the parameters to the - * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. - */ -typedef struct CK_ECDH2_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; -} CK_ECDH2_DERIVE_PARAMS; - -typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; - -typedef struct CK_ECMQV_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; -} CK_ECMQV_DERIVE_PARAMS; - -typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; - -/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the - * CKM_X9_42_DH_PARAMETER_GEN mechanisms - */ -typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; -typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; - -/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party - * contributes one key pair - */ -typedef struct CK_X9_42_DH1_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_X9_42_DH1_DERIVE_PARAMS; - -typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; - -/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation - * mechanisms, where each party contributes two key pairs - */ -typedef struct CK_X9_42_DH2_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; -} CK_X9_42_DH2_DERIVE_PARAMS; - -typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; - -typedef struct CK_X9_42_MQV_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; -} CK_X9_42_MQV_DERIVE_PARAMS; - -typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; - -/* CK_KEA_DERIVE_PARAMS provides the parameters to the - * CKM_KEA_DERIVE mechanism - */ -typedef struct CK_KEA_DERIVE_PARAMS { - CK_BBOOL isSender; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pRandomB; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_KEA_DERIVE_PARAMS; - -typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; - - -/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and - * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just - * holds the effective keysize - */ -typedef CK_ULONG CK_RC2_PARAMS; - -typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; - - -/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC - * mechanism - */ -typedef struct CK_RC2_CBC_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_BYTE iv[8]; /* IV for CBC mode */ -} CK_RC2_CBC_PARAMS; - -typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; - - -/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the - * CKM_RC2_MAC_GENERAL mechanism - */ -typedef struct CK_RC2_MAC_GENERAL_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ -} CK_RC2_MAC_GENERAL_PARAMS; - -typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC2_MAC_GENERAL_PARAMS_PTR; - - -/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and - * CKM_RC5_MAC mechanisms - */ -typedef struct CK_RC5_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ -} CK_RC5_PARAMS; - -typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; - - -/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC - * mechanism - */ -typedef struct CK_RC5_CBC_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_BYTE_PTR pIv; /* pointer to IV */ - CK_ULONG ulIvLen; /* length of IV in bytes */ -} CK_RC5_CBC_PARAMS; - -typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; - - -/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the - * CKM_RC5_MAC_GENERAL mechanism - */ -typedef struct CK_RC5_MAC_GENERAL_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ -} CK_RC5_MAC_GENERAL_PARAMS; - -typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC5_MAC_GENERAL_PARAMS_PTR; - -/* CK_MAC_GENERAL_PARAMS provides the parameters to most block - * ciphers' MAC_GENERAL mechanisms. Its value is the length of - * the MAC - */ -typedef CK_ULONG CK_MAC_GENERAL_PARAMS; - -typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; - -typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[8]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_DES_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_AES_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; - -/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the - * CKM_SKIPJACK_PRIVATE_WRAP mechanism - */ -typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pPassword; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPAndGLen; - CK_ULONG ulQLen; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pPrimeP; - CK_BYTE_PTR pBaseG; - CK_BYTE_PTR pSubprimeQ; -} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; - -typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ - CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; - - -/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the - * CKM_SKIPJACK_RELAYX mechanism - */ -typedef struct CK_SKIPJACK_RELAYX_PARAMS { - CK_ULONG ulOldWrappedXLen; - CK_BYTE_PTR pOldWrappedX; - CK_ULONG ulOldPasswordLen; - CK_BYTE_PTR pOldPassword; - CK_ULONG ulOldPublicDataLen; - CK_BYTE_PTR pOldPublicData; - CK_ULONG ulOldRandomLen; - CK_BYTE_PTR pOldRandomA; - CK_ULONG ulNewPasswordLen; - CK_BYTE_PTR pNewPassword; - CK_ULONG ulNewPublicDataLen; - CK_BYTE_PTR pNewPublicData; - CK_ULONG ulNewRandomLen; - CK_BYTE_PTR pNewRandomA; -} CK_SKIPJACK_RELAYX_PARAMS; - -typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ - CK_SKIPJACK_RELAYX_PARAMS_PTR; - - -typedef struct CK_PBE_PARAMS { - CK_BYTE_PTR pInitVector; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pSalt; - CK_ULONG ulSaltLen; - CK_ULONG ulIteration; -} CK_PBE_PARAMS; - -typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; - - -/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the - * CKM_KEY_WRAP_SET_OAEP mechanism - */ -typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { - CK_BYTE bBC; /* block contents byte */ - CK_BYTE_PTR pX; /* extra data */ - CK_ULONG ulXLen; /* length of extra data in bytes */ -} CK_KEY_WRAP_SET_OAEP_PARAMS; - -typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; - -typedef struct CK_SSL3_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; -} CK_SSL3_RANDOM_DATA; - - -typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; -} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; - -typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_SSL3_KEY_MAT_OUT { - CK_OBJECT_HANDLE hClientMacSecret; - CK_OBJECT_HANDLE hServerMacSecret; - CK_OBJECT_HANDLE hClientKey; - CK_OBJECT_HANDLE hServerKey; - CK_BYTE_PTR pIVClient; - CK_BYTE_PTR pIVServer; -} CK_SSL3_KEY_MAT_OUT; - -typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; - - -typedef struct CK_SSL3_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -} CK_SSL3_KEY_MAT_PARAMS; - -typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; - -typedef struct CK_TLS_PRF_PARAMS { - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; -} CK_TLS_PRF_PARAMS; - -typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; - -typedef struct CK_WTLS_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; -} CK_WTLS_RANDOM_DATA; - -typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; - -typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pVersion; -} CK_WTLS_MASTER_KEY_DERIVE_PARAMS; - -typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_WTLS_PRF_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; -} CK_WTLS_PRF_PARAMS; - -typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; - -typedef struct CK_WTLS_KEY_MAT_OUT { - CK_OBJECT_HANDLE hMacSecret; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pIV; -} CK_WTLS_KEY_MAT_OUT; - -typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; - -typedef struct CK_WTLS_KEY_MAT_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_ULONG ulSequenceNumber; - CK_BBOOL bIsExport; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -} CK_WTLS_KEY_MAT_PARAMS; - -typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; - -typedef struct CK_CMS_SIG_PARAMS { - CK_OBJECT_HANDLE certificateHandle; - CK_MECHANISM_PTR pSigningMechanism; - CK_MECHANISM_PTR pDigestMechanism; - CK_UTF8CHAR_PTR pContentType; - CK_BYTE_PTR pRequestedAttributes; - CK_ULONG ulRequestedAttributesLen; - CK_BYTE_PTR pRequiredAttributes; - CK_ULONG ulRequiredAttributesLen; -} CK_CMS_SIG_PARAMS; - -typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; - -typedef struct CK_KEY_DERIVATION_STRING_DATA { - CK_BYTE_PTR pData; - CK_ULONG ulLen; -} CK_KEY_DERIVATION_STRING_DATA; - -typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ - CK_KEY_DERIVATION_STRING_DATA_PTR; - - -/* The CK_EXTRACT_PARAMS is used for the - * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit - * of the base key should be used as the first bit of the - * derived key - */ -typedef CK_ULONG CK_EXTRACT_PARAMS; - -typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; - -/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to - * indicate the Pseudo-Random Function (PRF) used to generate - * key bits using PKCS #5 PBKDF2. - */ -typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; - -typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; - -#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL -#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL -#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL -#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL -#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL - -/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the - * source of the salt value when deriving a key using PKCS #5 - * PBKDF2. - */ -typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; - -typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; - -/* The following salt value sources are defined in PKCS #5 v2.0. */ -#define CKZ_SALT_SPECIFIED 0x00000001UL - -/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the - * parameters to the CKM_PKCS5_PBKD2 mechanism. - */ -typedef struct CK_PKCS5_PBKD2_PARAMS { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG_PTR ulPasswordLen; -} CK_PKCS5_PBKD2_PARAMS; - -typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; - -/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS - * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism - * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR. - */ -typedef struct CK_PKCS5_PBKD2_PARAMS2 { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; -} CK_PKCS5_PBKD2_PARAMS2; - -typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR; - -typedef CK_ULONG CK_OTP_PARAM_TYPE; -typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ - -typedef struct CK_OTP_PARAM { - CK_OTP_PARAM_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; -} CK_OTP_PARAM; - -typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; - -typedef struct CK_OTP_PARAMS { - CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; -} CK_OTP_PARAMS; - -typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; - -typedef struct CK_OTP_SIGNATURE_INFO { - CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; -} CK_OTP_SIGNATURE_INFO; - -typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; - -#define CK_OTP_VALUE 0UL -#define CK_OTP_PIN 1UL -#define CK_OTP_CHALLENGE 2UL -#define CK_OTP_TIME 3UL -#define CK_OTP_COUNTER 4UL -#define CK_OTP_FLAGS 5UL -#define CK_OTP_OUTPUT_LENGTH 6UL -#define CK_OTP_OUTPUT_FORMAT 7UL - -#define CKF_NEXT_OTP 0x00000001UL -#define CKF_EXCLUDE_TIME 0x00000002UL -#define CKF_EXCLUDE_COUNTER 0x00000004UL -#define CKF_EXCLUDE_CHALLENGE 0x00000008UL -#define CKF_EXCLUDE_PIN 0x00000010UL -#define CKF_USER_FRIENDLY_OTP 0x00000020UL - -typedef struct CK_KIP_PARAMS { - CK_MECHANISM_PTR pMechanism; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; -} CK_KIP_PARAMS; - -typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; - -typedef struct CK_AES_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -} CK_AES_CTR_PARAMS; - -typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; - -typedef struct CK_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -} CK_GCM_PARAMS; - -typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; - -typedef struct CK_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -} CK_CCM_PARAMS; - -typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; - -/* Deprecated. Use CK_GCM_PARAMS */ -typedef struct CK_AES_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -} CK_AES_GCM_PARAMS; - -typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR; - -/* Deprecated. Use CK_CCM_PARAMS */ -typedef struct CK_AES_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -} CK_AES_CCM_PARAMS; - -typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR; - -typedef struct CK_CAMELLIA_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -} CK_CAMELLIA_CTR_PARAMS; - -typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; - -typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_DSA_PARAMETER_GEN_PARAM { - CK_MECHANISM_TYPE hash; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_ULONG ulIndex; -} CK_DSA_PARAMETER_GEN_PARAM; - -typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR; - -typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; -} CK_ECDH_AES_KEY_WRAP_PARAMS; - -typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR; - -typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; - -typedef CK_ULONG CK_CERTIFICATE_CATEGORY; - -typedef struct CK_RSA_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; -} CK_RSA_AES_KEY_WRAP_PARAMS; - -typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR; - -typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; - CK_MECHANISM_TYPE prfHashMechanism; -} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; - -typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_TLS12_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; - CK_MECHANISM_TYPE prfHashMechanism; -} CK_TLS12_KEY_MAT_PARAMS; - -typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; - -typedef struct CK_TLS_KDF_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLength; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pContextData; - CK_ULONG ulContextDataLength; -} CK_TLS_KDF_PARAMS; - -typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR; - -typedef struct CK_TLS_MAC_PARAMS { - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulMacLength; - CK_ULONG ulServerOrClient; -} CK_TLS_MAC_PARAMS; - -typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; - -typedef struct CK_GOSTR3410_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; -} CK_GOSTR3410_DERIVE_PARAMS; - -typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR; - -typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS { - CK_BYTE_PTR pWrapOID; - CK_ULONG ulWrapOIDLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; - CK_OBJECT_HANDLE hKey; -} CK_GOSTR3410_KEY_WRAP_PARAMS; - -typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR; - -typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_SEED_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; - -#endif /* _PKCS11T_H_ */ - diff --git a/lib/isc/iterated_hash.c b/lib/isc/iterated_hash.c index b32d6671..c0148c98 100644 --- a/lib/isc/iterated_hash.c +++ b/lib/isc/iterated_hash.c @@ -3,27 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <stdio.h> -#include <isc/md.h> #include <isc/iterated_hash.h> +#include <isc/md.h> #include <isc/util.h> int -isc_iterated_hash(unsigned char *out, - const unsigned int hashalg, const int iterations, - const unsigned char *salt, const int saltlength, - const unsigned char *in, const int inlength) -{ +isc_iterated_hash(unsigned char *out, const unsigned int hashalg, + const int iterations, const unsigned char *salt, + const int saltlength, const unsigned char *in, + const int inlength) { isc_md_t *md; isc_result_t result; int n = 0; diff --git a/lib/isc/lex.c b/lib/isc/lex.c index ca5fe6d1..3aef6916 100644 --- a/lib/isc/lex.c +++ b/lib/isc/lex.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <ctype.h> #include <errno.h> #include <inttypes.h> @@ -31,37 +28,37 @@ #include <isc/util.h> typedef struct inputsource { - isc_result_t result; - bool is_file; - bool need_close; - bool at_eof; - bool last_was_eol; - isc_buffer_t * pushback; - unsigned int ignored; - void * input; - char * name; - unsigned long line; - unsigned long saved_line; - ISC_LINK(struct inputsource) link; + isc_result_t result; + bool is_file; + bool need_close; + bool at_eof; + bool last_was_eol; + isc_buffer_t *pushback; + unsigned int ignored; + void *input; + char *name; + unsigned long line; + unsigned long saved_line; + ISC_LINK(struct inputsource) link; } inputsource; -#define LEX_MAGIC ISC_MAGIC('L', 'e', 'x', '!') -#define VALID_LEX(l) ISC_MAGIC_VALID(l, LEX_MAGIC) +#define LEX_MAGIC ISC_MAGIC('L', 'e', 'x', '!') +#define VALID_LEX(l) ISC_MAGIC_VALID(l, LEX_MAGIC) struct isc_lex { /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - size_t max_token; - char * data; - unsigned int comments; - bool comment_ok; - bool last_was_eol; - unsigned int brace_count; - unsigned int paren_count; - unsigned int saved_paren_count; - isc_lexspecials_t specials; - LIST(struct inputsource) sources; + unsigned int magic; + isc_mem_t *mctx; + size_t max_token; + char *data; + unsigned int comments; + bool comment_ok; + bool last_was_eol; + unsigned int brace_count; + unsigned int paren_count; + unsigned int saved_paren_count; + isc_lexspecials_t specials; + LIST(struct inputsource) sources; }; static inline isc_result_t @@ -69,12 +66,11 @@ grow_data(isc_lex_t *lex, size_t *remainingp, char **currp, char **prevp) { char *tmp; tmp = isc_mem_get(lex->mctx, lex->max_token * 2 + 1); - if (tmp == NULL) - return (ISC_R_NOMEMORY); memmove(tmp, lex->data, lex->max_token + 1); *currp = tmp + (*currp - lex->data); - if (*prevp != NULL) + if (*prevp != NULL) { *prevp = tmp + (*prevp - lex->data); + } isc_mem_put(lex->mctx, lex->data, lex->max_token + 1); lex->data = tmp; *remainingp += lex->max_token; @@ -91,17 +87,12 @@ isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp) { */ REQUIRE(lexp != NULL && *lexp == NULL); - if (max_token == 0U) + if (max_token == 0U) { max_token = 1; + } lex = isc_mem_get(mctx, sizeof(*lex)); - if (lex == NULL) - return (ISC_R_NOMEMORY); lex->data = isc_mem_get(mctx, max_token + 1); - if (lex->data == NULL) { - isc_mem_put(mctx, lex, sizeof(*lex)); - return (ISC_R_NOMEMORY); - } lex->mctx = mctx; lex->max_token = max_token; lex->comments = 0; @@ -129,16 +120,17 @@ isc_lex_destroy(isc_lex_t **lexp) { REQUIRE(lexp != NULL); lex = *lexp; + *lexp = NULL; REQUIRE(VALID_LEX(lex)); - while (!EMPTY(lex->sources)) + while (!EMPTY(lex->sources)) { RUNTIME_CHECK(isc_lex_close(lex) == ISC_R_SUCCESS); - if (lex->data != NULL) + } + if (lex->data != NULL) { isc_mem_put(lex->mctx, lex->data, lex->max_token + 1); + } lex->magic = 0; isc_mem_put(lex->mctx, lex, sizeof(*lex)); - - *lexp = NULL; } unsigned int @@ -187,15 +179,11 @@ isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials) { } static inline isc_result_t -new_source(isc_lex_t *lex, bool is_file, bool need_close, - void *input, const char *name) -{ +new_source(isc_lex_t *lex, bool is_file, bool need_close, void *input, + const char *name) { inputsource *source; - isc_result_t result; source = isc_mem_get(lex->mctx, sizeof(*source)); - if (source == NULL) - return (ISC_R_NOMEMORY); source->result = ISC_R_SUCCESS; source->is_file = is_file; source->need_close = need_close; @@ -203,18 +191,9 @@ new_source(isc_lex_t *lex, bool is_file, bool need_close, source->last_was_eol = lex->last_was_eol; source->input = input; source->name = isc_mem_strdup(lex->mctx, name); - if (source->name == NULL) { - isc_mem_put(lex->mctx, source, sizeof(*source)); - return (ISC_R_NOMEMORY); - } source->pushback = NULL; - result = isc_buffer_allocate(lex->mctx, &source->pushback, - (unsigned int)lex->max_token); - if (result != ISC_R_SUCCESS) { - isc_mem_free(lex->mctx, source->name); - isc_mem_put(lex->mctx, source, sizeof(*source)); - return (result); - } + isc_buffer_allocate(lex->mctx, &source->pushback, + (unsigned int)lex->max_token); source->ignored = 0; source->line = 1; ISC_LIST_INITANDPREPEND(lex->sources, source, link); @@ -234,12 +213,14 @@ isc_lex_openfile(isc_lex_t *lex, const char *filename) { REQUIRE(VALID_LEX(lex)); result = isc_stdio_open(filename, "r", &stream); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } result = new_source(lex, true, true, stream, filename); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { (void)fclose(stream); + } return (result); } @@ -284,14 +265,16 @@ isc_lex_close(isc_lex_t *lex) { REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (ISC_R_NOMORE); + } ISC_LIST_UNLINK(lex->sources, source, link); lex->last_was_eol = source->last_was_eol; if (source->is_file) { - if (source->need_close) + if (source->need_close) { (void)fclose((FILE *)(source->input)); + } } isc_mem_free(lex->mctx, source->name); isc_buffer_free(&source->pushback); @@ -323,8 +306,9 @@ pushback(inputsource *source, int c) { return; } source->pushback->current--; - if (c == '\n') + if (c == '\n') { source->line--; + } } static isc_result_t @@ -336,9 +320,7 @@ pushandgrow(isc_lex_t *lex, inputsource *source, int c) { isc_result_t result; oldlen = isc_buffer_length(source->pushback); - result = isc_buffer_allocate(lex->mctx, &tbuf, oldlen * 2); - if (result != ISC_R_SUCCESS) - return (result); + isc_buffer_allocate(lex->mctx, &tbuf, oldlen * 2); isc_buffer_usedregion(source->pushback, &used); result = isc_buffer_copyregion(tbuf, &used); INSIST(result == ISC_R_SUCCESS); @@ -383,23 +365,21 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { return (ISC_R_NOMORE); } - if (source->result != ISC_R_SUCCESS) + if (source->result != ISC_R_SUCCESS) { return (source->result); + } lex->saved_paren_count = lex->paren_count; source->saved_line = source->line; - if (isc_buffer_remaininglength(source->pushback) == 0 && - source->at_eof) + if (isc_buffer_remaininglength(source->pushback) == 0 && source->at_eof) { if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && - lex->paren_count != 0) - { + lex->paren_count != 0) { lex->paren_count = 0; return (ISC_R_UNBALANCED); } - if ((options & ISC_LEXOPT_BTEXT) != 0 && - lex->brace_count != 0) + if ((options & ISC_LEXOPT_BTEXT) != 0 && lex->brace_count != 0) { lex->brace_count = 0; return (ISC_R_UNBALANCED); @@ -414,8 +394,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { isc_buffer_compact(source->pushback); saved_options = options; - if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count > 0) + if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count > 0) { options &= ~IWSEOL; + } curr = lex->data; *curr = '\0'; @@ -424,9 +405,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { remaining = lex->max_token; #ifdef HAVE_FLOCKFILE - if (source->is_file) + if (source->is_file) { flockfile(source->input); -#endif + } +#endif /* ifdef HAVE_FLOCKFILE */ do { if (isc_buffer_remaininglength(source->pushback) == 0) { @@ -435,9 +417,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { #if defined(HAVE_FLOCKFILE) && defined(HAVE_GETC_UNLOCKED) c = getc_unlocked(stream); -#else +#else /* if defined(HAVE_FLOCKFILE) && defined(HAVE_GETC_UNLOCKED) */ c = getc(stream); -#endif +#endif /* if defined(HAVE_FLOCKFILE) && defined(HAVE_GETC_UNLOCKED) */ if (c == EOF) { if (ferror(stream)) { source->result = ISC_R_IOERROR; @@ -468,37 +450,40 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } if (!source->at_eof) { - if (state == lexstate_start) + if (state == lexstate_start) { /* Token has not started yet. */ - source->ignored = - isc_buffer_consumedlength(source->pushback); + source->ignored = isc_buffer_consumedlength( + source->pushback); + } c = isc_buffer_getuint8(source->pushback); } else { c = EOF; } - if (c == '\n') + if (c == '\n') { source->line++; + } if (lex->comment_ok && !no_comments) { if (!escaped && c == ';' && - ((lex->comments & ISC_LEXCOMMENT_DNSMASTERFILE) - != 0)) { + ((lex->comments & ISC_LEXCOMMENT_DNSMASTERFILE) != + 0)) + { saved_state = state; state = lexstate_eatline; no_comments = true; continue; } else if (c == '/' && (lex->comments & - (ISC_LEXCOMMENT_C| - ISC_LEXCOMMENT_CPLUSPLUS)) != 0) { + (ISC_LEXCOMMENT_C | + ISC_LEXCOMMENT_CPLUSPLUS)) != 0) + { saved_state = state; state = lexstate_maybecomment; no_comments = true; continue; - } else if (c == '#' && - ((lex->comments & ISC_LEXCOMMENT_SHELL) - != 0)) { + } else if (c == '#' && ((lex->comments & + ISC_LEXCOMMENT_SHELL) != 0)) { saved_state = state; state = lexstate_eatline; no_comments = true; @@ -532,8 +517,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { done = true; } else if (c == ' ' || c == '\t') { if (lex->last_was_eol && - (options & ISC_LEXOPT_INITIALWS) - != 0) { + (options & ISC_LEXOPT_INITIALWS) != 0) { lex->last_was_eol = false; tokenp->type = isc_tokentype_initialws; tokenp->value.as_char = c; @@ -546,8 +530,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } lex->last_was_eol = true; } else if (c == '\r') { - if ((options & ISC_LEXOPT_EOL) != 0) + if ((options & ISC_LEXOPT_EOL) != 0) { state = lexstate_crlf; + } } else if (c == '"' && (options & ISC_LEXOPT_QSTRING) != 0) { lex->last_was_eol = false; @@ -556,26 +541,26 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } else if (lex->specials[c]) { lex->last_was_eol = false; if ((c == '(' || c == ')') && - (options & ISC_LEXOPT_DNSMULTILINE) != 0) - { + (options & ISC_LEXOPT_DNSMULTILINE) != 0) { if (c == '(') { - if (lex->paren_count == 0) + if (lex->paren_count == 0) { options &= ~IWSEOL; + } lex->paren_count++; } else { if (lex->paren_count == 0) { result = - ISC_R_UNBALANCED; + ISC_R_UNBALANCED; goto done; } lex->paren_count--; - if (lex->paren_count == 0) + if (lex->paren_count == 0) { options = saved_options; + } } continue; } else if (c == '{' && - (options & ISC_LEXOPT_BTEXT) != 0) - { + (options & ISC_LEXOPT_BTEXT) != 0) { if (lex->brace_count != 0) { result = ISC_R_UNBALANCED; goto done; @@ -593,10 +578,11 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { (options & ISC_LEXOPT_NUMBER) != 0) { lex->last_was_eol = false; if ((options & ISC_LEXOPT_OCTAL) != 0 && - (c == '8' || c == '9')) + (c == '8' || c == '9')) { state = lexstate_string; - else + } else { state = lexstate_number; + } goto no_read; } else { lex->last_was_eol = false; @@ -605,8 +591,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } break; case lexstate_crlf: - if (c != '\n') + if (c != '\n') { pushback(source, c); + } tokenp->type = isc_tokentype_eol; done = true; lex->last_was_eol = true; @@ -614,20 +601,21 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { case lexstate_number: if (c == EOF || !isdigit((unsigned char)c)) { if (c == ' ' || c == '\t' || c == '\r' || - c == '\n' || c == EOF || - lex->specials[c]) { + c == '\n' || c == EOF || lex->specials[c]) + { int base; - if ((options & ISC_LEXOPT_OCTAL) != 0) + if ((options & ISC_LEXOPT_OCTAL) != 0) { base = 8; - else if ((options & ISC_LEXOPT_CNUMBER) != 0) + } else if ((options & + ISC_LEXOPT_CNUMBER) != 0) { base = 0; - else + } else { base = 10; + } pushback(source, c); - result = isc_parse_uint32(&as_ulong, - lex->data, - base); + result = isc_parse_uint32( + &as_ulong, lex->data, base); if (result == ISC_R_SUCCESS) { tokenp->type = isc_tokentype_number; @@ -642,17 +630,19 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { v->as_textregion.base = lex->data; v->as_textregion.length = - (unsigned int) - (lex->max_token - - remaining); - } else + (unsigned int)(lex->max_token - + remaining); + } else { goto done; + } done = true; continue; - } else if ((options & ISC_LEXOPT_CNUMBER) == 0 || + } else if ((options & ISC_LEXOPT_CNUMBER) == + 0 || ((c != 'x' && c != 'X') || (curr != &lex->data[1]) || - (lex->data[0] != '0'))) { + (lex->data[0] != '0'))) + { /* Above test supports hex numbers */ state = lexstate_string; } @@ -661,10 +651,11 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { state = lexstate_string; } if (remaining == 0U) { - result = grow_data(lex, &remaining, - &curr, &prev); - if (result != ISC_R_SUCCESS) + result = grow_data(lex, &remaining, &curr, + &prev); + if (result != ISC_R_SUCCESS) { goto done; + } } INSIST(remaining > 0U); *curr++ = c; @@ -678,7 +669,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { */ if (c == '\r' || c == '\n' || c == EOF || (!escaped && - (c == ' ' || c == '\t' || lex->specials[c]))) { + (c == ' ' || c == '\t' || lex->specials[c]))) + { pushback(source, c); if (source->result != ISC_R_SUCCESS) { result = source->result; @@ -687,19 +679,21 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { tokenp->type = isc_tokentype_string; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = - (unsigned int) - (lex->max_token - remaining); + (unsigned int)(lex->max_token - + remaining); done = true; continue; } - if ((options & ISC_LEXOPT_ESCAPE) != 0) - escaped = (!escaped && c == '\\') ? - true : false; + if ((options & ISC_LEXOPT_ESCAPE) != 0) { + escaped = (!escaped && c == '\\') ? true + : false; + } if (remaining == 0U) { - result = grow_data(lex, &remaining, - &curr, &prev); - if (result != ISC_R_SUCCESS) + result = grow_data(lex, &remaining, &curr, + &prev); + if (result != ISC_R_SUCCESS) { goto done; + } } INSIST(remaining > 0U); *curr++ = c; @@ -707,12 +701,13 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { remaining--; break; case lexstate_maybecomment: - if (c == '*' && - (lex->comments & ISC_LEXCOMMENT_C) != 0) { + if (c == '*' && (lex->comments & ISC_LEXCOMMENT_C) != 0) + { state = lexstate_ccomment; continue; - } else if (c == '/' && - (lex->comments & ISC_LEXCOMMENT_CPLUSPLUS) != 0) { + } else if (c == '/' && (lex->comments & + ISC_LEXCOMMENT_CPLUSPLUS) != 0) + { state = lexstate_eatline; continue; } @@ -726,8 +721,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { result = ISC_R_UNEXPECTEDEND; goto done; } - if (c == '*') + if (c == '*') { state = lexstate_ccommentend; + } break; case lexstate_ccommentend: if (c == EOF) { @@ -745,8 +741,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { no_comments = false; state = saved_state; goto no_read; - } else if (c != '*') + } else if (c != '*') { state = lexstate_ccomment; + } break; case lexstate_eatline: if ((c == '\n') || (c == EOF)) { @@ -773,27 +770,30 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = - (unsigned int) - (lex->max_token - remaining); + (unsigned int)(lex->max_token - + remaining); no_comments = false; done = true; } } else { if (c == '\n' && !escaped && - (options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) { + (options & ISC_LEXOPT_QSTRINGMULTILINE) == + 0) { pushback(source, c); result = ISC_R_UNBALANCEDQUOTES; goto done; } - if (c == '\\' && !escaped) + if (c == '\\' && !escaped) { escaped = true; - else + } else { escaped = false; + } if (remaining == 0U) { result = grow_data(lex, &remaining, &curr, &prev); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { goto done; + } } INSIST(remaining > 0U); prev = curr; @@ -826,24 +826,26 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = - (unsigned int) (lex->max_token - - remaining); + (unsigned int)(lex->max_token - + remaining); no_comments = false; done = true; break; } } - if (c == '\\' && !escaped) + if (c == '\\' && !escaped) { escaped = true; - else + } else { escaped = false; + } if (remaining == 0U) { - result = grow_data(lex, &remaining, - &curr, &prev); - if (result != ISC_R_SUCCESS) + result = grow_data(lex, &remaining, &curr, + &prev); + if (result != ISC_R_SUCCESS) { goto done; + } } INSIST(remaining > 0U); prev = curr; @@ -852,81 +854,90 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { remaining--; break; default: - FATAL_ERROR(__FILE__, __LINE__, - "Unexpected state %d", + FATAL_ERROR(__FILE__, __LINE__, "Unexpected state %d", state); - ISC_UNREACHABLE(); } - } while (!done); result = ISC_R_SUCCESS; - done: +done: #ifdef HAVE_FLOCKFILE - if (source->is_file) + if (source->is_file) { funlockfile(source->input); -#endif + } +#endif /* ifdef HAVE_FLOCKFILE */ return (result); } isc_result_t isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token, - isc_tokentype_t expect, bool eol) -{ + isc_tokentype_t expect, bool eol) { unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; isc_result_t result; - if (expect == isc_tokentype_qstring) + if (expect == isc_tokentype_qstring) { options |= ISC_LEXOPT_QSTRING; - else if (expect == isc_tokentype_number) + } else if (expect == isc_tokentype_number) { options |= ISC_LEXOPT_NUMBER; + } result = isc_lex_gettoken(lex, options, token); - if (result == ISC_R_RANGE) + if (result == ISC_R_RANGE) { isc_lex_ungettoken(lex, token); - if (result != ISC_R_SUCCESS) + } + if (result != ISC_R_SUCCESS) { return (result); + } if (eol && ((token->type == isc_tokentype_eol) || (token->type == isc_tokentype_eof))) + { return (ISC_R_SUCCESS); + } if (token->type == isc_tokentype_string && - expect == isc_tokentype_qstring) + expect == isc_tokentype_qstring) { return (ISC_R_SUCCESS); + } if (token->type != expect) { isc_lex_ungettoken(lex, token); if (token->type == isc_tokentype_eol || - token->type == isc_tokentype_eof) + token->type == isc_tokentype_eof) { return (ISC_R_UNEXPECTEDEND); - if (expect == isc_tokentype_number) + } + if (expect == isc_tokentype_number) { return (ISC_R_BADNUMBER); + } return (ISC_R_UNEXPECTEDTOKEN); } return (ISC_R_SUCCESS); } isc_result_t -isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, bool eol) -{ +isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, bool eol) { unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | - ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE| + ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE | ISC_LEXOPT_NUMBER | ISC_LEXOPT_OCTAL; isc_result_t result; result = isc_lex_gettoken(lex, options, token); - if (result == ISC_R_RANGE) + if (result == ISC_R_RANGE) { isc_lex_ungettoken(lex, token); - if (result != ISC_R_SUCCESS) + } + if (result != ISC_R_SUCCESS) { return (result); + } if (eol && ((token->type == isc_tokentype_eol) || (token->type == isc_tokentype_eof))) + { return (ISC_R_SUCCESS); + } if (token->type != isc_tokentype_number) { isc_lex_ungettoken(lex, token); if (token->type == isc_tokentype_eol || - token->type == isc_tokentype_eof) + token->type == isc_tokentype_eof) { return (ISC_R_UNEXPECTEDEND); + } return (ISC_R_BADNUMBER); } return (ISC_R_SUCCESS); @@ -955,8 +966,7 @@ isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp) { } void -isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r) -{ +isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r) { inputsource *source; REQUIRE(VALID_LEX(lex)); @@ -982,8 +992,9 @@ isc_lex_getsourcename(isc_lex_t *lex) { REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (NULL); + } return (source->name); } @@ -995,8 +1006,9 @@ isc_lex_getsourceline(isc_lex_t *lex) { REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (0); + } return (source->line); } @@ -1009,11 +1021,10 @@ isc_lex_setsourcename(isc_lex_t *lex, const char *name) { REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (ISC_R_NOTFOUND); + } newname = isc_mem_strdup(lex->mctx, name); - if (newname == NULL) - return (ISC_R_NOMEMORY); isc_mem_free(lex->mctx, source->name); source->name = newname; return (ISC_R_SUCCESS); @@ -1026,8 +1037,9 @@ isc_lex_setsourceline(isc_lex_t *lex, unsigned long line) { REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (ISC_R_NOTFOUND); + } source->line = line; return (ISC_R_SUCCESS); @@ -1041,8 +1053,9 @@ isc_lex_isfile(isc_lex_t *lex) { source = HEAD(lex->sources); - if (source == NULL) + if (source == NULL) { return (false); + } return (source->is_file); } diff --git a/lib/isc/lfsr.c b/lib/isc/lfsr.c index 3b0b47fe..0900c5cf 100644 --- a/lib/isc/lfsr.c +++ b/lib/isc/lfsr.c @@ -3,32 +3,27 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <stddef.h> #include <inttypes.h> +#include <stddef.h> #include <stdlib.h> #include <isc/assertions.h> #include <isc/lfsr.h> #include <isc/util.h> -#define VALID_LFSR(x) (x != NULL) +#define VALID_LFSR(x) (x != NULL) void -isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, - uint32_t tap, unsigned int count, - isc_lfsrreseed_t reseed, void *arg) -{ +isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, uint32_t tap, + unsigned int count, isc_lfsrreseed_t reseed, void *arg) { REQUIRE(VALID_LFSR(lfsr)); REQUIRE(8 <= bits && bits <= 32); REQUIRE(tap != 0); @@ -40,19 +35,19 @@ isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, lfsr->reseed = reseed; lfsr->arg = arg; - if (count == 0 && reseed != NULL) + if (count == 0 && reseed != NULL) { reseed(lfsr, arg); - if (lfsr->state == 0) + } + if (lfsr->state == 0) { lfsr->state = 0xffffffffU >> (32 - lfsr->bits); + } } /*! * Return the next state of the lfsr. */ static inline uint32_t -lfsr_generate(isc_lfsr_t *lfsr) -{ - +lfsr_generate(isc_lfsr_t *lfsr) { /* * If the previous state is zero, we must fill it with something * here, or we will begin to generate an extremely predictable output. @@ -61,10 +56,12 @@ lfsr_generate(isc_lfsr_t *lfsr) * still 0, set it to all ones. */ if (lfsr->state == 0) { - if (lfsr->reseed != NULL) + if (lfsr->reseed != NULL) { lfsr->reseed(lfsr, lfsr->arg); - if (lfsr->state == 0) + } + if (lfsr->state == 0) { lfsr->state = 0xffffffffU >> (32 - lfsr->bits); + } } if (lfsr->state & 0x01) { @@ -77,8 +74,7 @@ lfsr_generate(isc_lfsr_t *lfsr) } void -isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count) -{ +isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count) { unsigned char *p; unsigned int bit; unsigned int byte; @@ -101,18 +97,19 @@ isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count) } if (lfsr->count != 0 && lfsr->reseed != NULL) { - if (lfsr->count <= count * 8) + if (lfsr->count <= count * 8) { lfsr->reseed(lfsr, lfsr->arg); - else + } else { lfsr->count -= (count * 8); + } } } static inline uint32_t -lfsr_skipgenerate(isc_lfsr_t *lfsr, unsigned int skip) -{ - while (skip--) +lfsr_skipgenerate(isc_lfsr_t *lfsr, unsigned int skip) { + while (skip--) { (void)lfsr_generate(lfsr); + } (void)lfsr_generate(lfsr); @@ -123,12 +120,12 @@ lfsr_skipgenerate(isc_lfsr_t *lfsr, unsigned int skip) * Skip "skip" states in "lfsr". */ void -isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip) -{ +isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip) { REQUIRE(VALID_LFSR(lfsr)); - while (skip--) + while (skip--) { (void)lfsr_generate(lfsr); + } } /* @@ -136,8 +133,7 @@ isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip) * Return the final state of lfsr1 ^ lfsr2. */ uint32_t -isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2) -{ +isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2) { uint32_t state1, state2; uint32_t skip1, skip2; diff --git a/lib/isc/lib.c b/lib/isc/lib.c index 45198be3..8bee4c21 100644 --- a/lib/isc/lib.c +++ b/lib/isc/lib.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <isc/bind9.h> #include <isc/lib.h> diff --git a/lib/isc/log.c b/lib/isc/log.c index 2312ff0a..4657d9c3 100644 --- a/lib/isc/log.c +++ b/lib/isc/log.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,43 +11,44 @@ /*! \file */ -#include <config.h> - #include <errno.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <stdlib.h> -#include <limits.h> +#include <sys/types.h> /* dev_t FreeBSD 2.1 */ #include <time.h> -#include <sys/types.h> /* dev_t FreeBSD 2.1 */ - +#include <isc/atomic.h> #include <isc/dir.h> #include <isc/file.h> #include <isc/log.h> #include <isc/magic.h> #include <isc/mem.h> +#include <isc/platform.h> #include <isc/print.h> +#include <isc/rwlock.h> #include <isc/stat.h> #include <isc/stdio.h> #include <isc/string.h> #include <isc/time.h> #include <isc/util.h> -#define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x') -#define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC) +#define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x') +#define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC) + +#define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g') +#define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC) -#define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g') -#define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC) +#define RDLOCK(lp) RWLOCK(lp, isc_rwlocktype_read); +#define WRLOCK(lp) RWLOCK(lp, isc_rwlocktype_write); +#define RDUNLOCK(lp) RWUNLOCK(lp, isc_rwlocktype_read); +#define WRUNLOCK(lp) RWUNLOCK(lp, isc_rwlocktype_write); /* * XXXDCL make dynamic? */ -#define LOG_BUFFER_SIZE (8 * 1024) - -#ifndef PATH_MAX -#define PATH_MAX 1024 /* WIN32 and others don't define this. */ -#endif +#define LOG_BUFFER_SIZE (8 * 1024) /*! * This is the structure that holds each named channel. A simple linked @@ -61,12 +62,12 @@ typedef struct isc_logchannel isc_logchannel_t; struct isc_logchannel { - char * name; - unsigned int type; - int level; - unsigned int flags; - isc_logdestination_t destination; - ISC_LINK(isc_logchannel_t) link; + char *name; + unsigned int type; + int level; + unsigned int flags; + isc_logdestination_t destination; + ISC_LINK(isc_logchannel_t) link; }; /*! @@ -80,9 +81,9 @@ struct isc_logchannel { typedef struct isc_logchannellist isc_logchannellist_t; struct isc_logchannellist { - const isc_logmodule_t * module; - isc_logchannel_t * channel; - ISC_LINK(isc_logchannellist_t) link; + const isc_logmodule_t *module; + isc_logchannel_t *channel; + ISC_LINK(isc_logchannellist_t) link; }; /*! @@ -92,9 +93,9 @@ struct isc_logchannellist { typedef struct isc_logmessage isc_logmessage_t; struct isc_logmessage { - char * text; - isc_time_t time; - ISC_LINK(isc_logmessage_t) link; + char *text; + isc_time_t time; + ISC_LINK(isc_logmessage_t) link; }; /*! @@ -105,15 +106,15 @@ struct isc_logmessage { * into a program, or the debug_level which is dynamic state information. */ struct isc_logconfig { - unsigned int magic; - isc_log_t * lctx; - ISC_LIST(isc_logchannel_t) channels; - ISC_LIST(isc_logchannellist_t) *channellists; - unsigned int channellist_count; - unsigned int duplicate_interval; - int highest_level; - char * tag; - bool dynamic; + unsigned int magic; + isc_log_t *lctx; + ISC_LIST(isc_logchannel_t) channels; + ISC_LIST(isc_logchannellist_t) * channellists; + unsigned int channellist_count; + unsigned int duplicate_interval; + int_fast32_t highest_level; + char *tag; + bool dynamic; }; /*! @@ -135,44 +136,36 @@ struct isc_logconfig { */ struct isc_log { /* Not locked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_logcategory_t * categories; - unsigned int category_count; - isc_logmodule_t * modules; - unsigned int module_count; - int debug_level; - isc_mutex_t lock; + unsigned int magic; + isc_mem_t *mctx; + isc_logcategory_t *categories; + unsigned int category_count; + isc_logmodule_t *modules; + unsigned int module_count; + atomic_int_fast32_t debug_level; + isc_rwlock_t lcfg_rwl; + /* Locked by isc_log lcfg_rwl */ + isc_logconfig_t *logconfig; + isc_mutex_t lock; /* Locked by isc_log lock. */ - isc_logconfig_t * logconfig; - char buffer[LOG_BUFFER_SIZE]; - ISC_LIST(isc_logmessage_t) messages; + char buffer[LOG_BUFFER_SIZE]; + ISC_LIST(isc_logmessage_t) messages; + atomic_bool dynamic; + atomic_int_fast32_t highest_level; }; /*! * Used when ISC_LOG_PRINTLEVEL is enabled for a channel. */ -static const char *log_level_strings[] = { - "debug", - "info", - "notice", - "warning", - "error", - "critical" -}; +static const char *log_level_strings[] = { "debug", "info", "notice", + "warning", "error", "critical" }; /*! * Used to convert ISC_LOG_* priorities into syslog priorities. * XXXDCL This will need modification for NT. */ -static const int syslog_map[] = { - LOG_DEBUG, - LOG_INFO, - LOG_NOTICE, - LOG_WARNING, - LOG_ERR, - LOG_CRIT -}; +static const int syslog_map[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, + LOG_WARNING, LOG_ERR, LOG_CRIT }; /*! * When adding new categories, a corresponding ISC_LOGCATEGORY_foo @@ -182,23 +175,20 @@ static const int syslog_map[] = { * be overridden. Since the default is always looked up as the first * channellist in the log context, it must come first in isc_categories[]. */ -LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = { - { "default", 0 }, /* "default" must come first. */ - { "general", 0 }, - { NULL, 0 } -}; +LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = { { "default", + 0 }, /* "default + must come + first. */ + { "general", 0 }, + { NULL, 0 } }; /*! - * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules. + * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to + * modules. */ LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = { - { "socket", 0 }, - { "time", 0 }, - { "interface", 0 }, - { "timer", 0 }, - { "file", 0 }, - { "other", 0 }, - { NULL, 0 } + { "socket", 0 }, { "time", 0 }, { "interface", 0 }, { "timer", 0 }, + { "file", 0 }, { "netmgr", 0 }, { "other", 0 }, { NULL, 0 } }; /*! @@ -216,21 +206,23 @@ LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL; /*! * Forward declarations. */ -static isc_result_t +static void assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, const isc_logmodule_t *module, isc_logchannel_t *channel); -static isc_result_t +static void sync_channellist(isc_logconfig_t *lcfg); +static void +sync_highest_level(isc_log_t *lctx, isc_logconfig_t *lcfg); + static isc_result_t greatest_version(isc_logfile_t *file, int versions, int *greatest); static void isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, bool write_once, - const char *format, va_list args) - ISC_FORMAT_PRINTF(6, 0); + const char *format, va_list args) ISC_FORMAT_PRINTF(6, 0); /*@{*/ /*! @@ -247,77 +239,65 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, /*@}*/ /**** - **** Public interfaces. - ****/ +**** Public interfaces. +****/ /* * Establish a new logging context, with default channels. */ -isc_result_t +void isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) { isc_log_t *lctx; isc_logconfig_t *lcfg = NULL; - isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(lctxp != NULL && *lctxp == NULL); REQUIRE(lcfgp == NULL || *lcfgp == NULL); lctx = isc_mem_get(mctx, sizeof(*lctx)); - if (lctx != NULL) { - lctx->mctx = NULL; - isc_mem_attach(mctx, &lctx->mctx); - lctx->categories = NULL; - lctx->category_count = 0; - lctx->modules = NULL; - lctx->module_count = 0; - lctx->debug_level = 0; - - ISC_LIST_INIT(lctx->messages); + lctx->mctx = NULL; + isc_mem_attach(mctx, &lctx->mctx); + lctx->categories = NULL; + lctx->category_count = 0; + lctx->modules = NULL; + lctx->module_count = 0; + atomic_init(&lctx->debug_level, 0); - isc_mutex_init(&lctx->lock); + ISC_LIST_INIT(lctx->messages); - /* - * Normally setting the magic number is the last step done - * in a creation function, but a valid log context is needed - * by isc_log_registercategories and isc_logconfig_create. - * If either fails, the lctx is destroyed and not returned - * to the caller. - */ - lctx->magic = LCTX_MAGIC; + isc_mutex_init(&lctx->lock); + isc_rwlock_init(&lctx->lcfg_rwl, 0, 0); - isc_log_registercategories(lctx, isc_categories); - isc_log_registermodules(lctx, isc_modules); - result = isc_logconfig_create(lctx, &lcfg); + /* + * Normally setting the magic number is the last step done + * in a creation function, but a valid log context is needed + * by isc_log_registercategories and isc_logconfig_create. + * If either fails, the lctx is destroyed and not returned + * to the caller. + */ + lctx->magic = LCTX_MAGIC; - } else - result = ISC_R_NOMEMORY; + isc_log_registercategories(lctx, isc_categories); + isc_log_registermodules(lctx, isc_modules); + isc_logconfig_create(lctx, &lcfg); - if (result == ISC_R_SUCCESS) - result = sync_channellist(lcfg); + sync_channellist(lcfg); - if (result == ISC_R_SUCCESS) { - lctx->logconfig = lcfg; + lctx->logconfig = lcfg; - *lctxp = lctx; - if (lcfgp != NULL) - *lcfgp = lcfg; + atomic_init(&lctx->highest_level, lcfg->highest_level); + atomic_init(&lctx->dynamic, lcfg->dynamic); - } else { - if (lcfg != NULL) - isc_logconfig_destroy(&lcfg); - if (lctx != NULL) - isc_log_destroy(&lctx); + *lctxp = lctx; + if (lcfgp != NULL) { + *lcfgp = lcfg; } - - return (result); } -isc_result_t +void isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) { isc_logconfig_t *lcfg; isc_logdestination_t destination; - isc_result_t result = ISC_R_SUCCESS; int level = ISC_LOG_INFO; REQUIRE(lcfgp != NULL && *lcfgp == NULL); @@ -325,101 +305,56 @@ isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) { lcfg = isc_mem_get(lctx->mctx, sizeof(*lcfg)); - if (lcfg != NULL) { - lcfg->lctx = lctx; - lcfg->channellists = NULL; - lcfg->channellist_count = 0; - lcfg->duplicate_interval = 0; - lcfg->highest_level = level; - lcfg->tag = NULL; - lcfg->dynamic = false; - - ISC_LIST_INIT(lcfg->channels); - - /* - * Normally the magic number is the last thing set in the - * structure, but isc_log_createchannel() needs a valid - * config. If the channel creation fails, the lcfg is not - * returned to the caller. - */ - lcfg->magic = LCFG_MAGIC; - - } else - result = ISC_R_NOMEMORY; + lcfg->lctx = lctx; + lcfg->channellists = NULL; + lcfg->channellist_count = 0; + lcfg->duplicate_interval = 0; + lcfg->highest_level = level; + lcfg->tag = NULL; + lcfg->dynamic = false; + ISC_LIST_INIT(lcfg->channels); + lcfg->magic = LCFG_MAGIC; /* * Create the default channels: - * default_syslog, default_stderr, default_debug and null. + * default_syslog, default_stderr, default_debug and null. */ - if (result == ISC_R_SUCCESS) { - destination.facility = LOG_DAEMON; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, level, - &destination, 0); - } - - if (result == ISC_R_SUCCESS) { - destination.file.stream = stderr; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.suffix = isc_log_rollsuffix_increment; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_stderr", - ISC_LOG_TOFILEDESC, - level, - &destination, - ISC_LOG_PRINTTIME); - } + destination.facility = LOG_DAEMON; + isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, level, + &destination, 0); + + destination.file.stream = stderr; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.suffix = isc_log_rollsuffix_increment; + destination.file.maximum_size = 0; + isc_log_createchannel(lcfg, "default_stderr", ISC_LOG_TOFILEDESC, level, + &destination, ISC_LOG_PRINTTIME); - if (result == ISC_R_SUCCESS) { - /* - * Set the default category's channel to default_stderr, - * which is at the head of the channels list because it was - * just created. - */ - default_channel.channel = ISC_LIST_HEAD(lcfg->channels); - - destination.file.stream = stderr; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.suffix = isc_log_rollsuffix_increment; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TOFILEDESC, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME); - } - - if (result == ISC_R_SUCCESS) - result = isc_log_createchannel(lcfg, "null", - ISC_LOG_TONULL, - ISC_LOG_DYNAMIC, - NULL, 0); - - if (result == ISC_R_SUCCESS) - *lcfgp = lcfg; - - else - if (lcfg != NULL) - isc_logconfig_destroy(&lcfg); - - return (result); -} + /* + * Set the default category's channel to default_stderr, + * which is at the head of the channels list because it was + * just created. + */ + default_channel.channel = ISC_LIST_HEAD(lcfg->channels); -isc_logconfig_t * -isc_logconfig_get(isc_log_t *lctx) { - REQUIRE(VALID_CONTEXT(lctx)); + destination.file.stream = stderr; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.suffix = isc_log_rollsuffix_increment; + destination.file.maximum_size = 0; + isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TOFILEDESC, + ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME); - ENSURE(lctx->logconfig != NULL); + isc_log_createchannel(lcfg, "null", ISC_LOG_TONULL, ISC_LOG_DYNAMIC, + NULL, 0); - return (lctx->logconfig); + *lcfgp = lcfg; } -isc_result_t +void isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) { isc_logconfig_t *old_cfg; - isc_result_t result; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(VALID_CONFIG(lcfg)); @@ -430,20 +365,15 @@ isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) { * They won't be equal if isc_log_usechannel has not been called * since any call to isc_log_registercategories. */ - result = sync_channellist(lcfg); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&lctx->lock); + sync_channellist(lcfg); + WRLOCK(&lctx->lcfg_rwl); old_cfg = lctx->logconfig; lctx->logconfig = lcfg; - - UNLOCK(&lctx->lock); + sync_highest_level(lctx, lcfg); + WRUNLOCK(&lctx->lcfg_rwl); isc_logconfig_destroy(&old_cfg); - - return (ISC_R_SUCCESS); } void @@ -456,14 +386,24 @@ isc_log_destroy(isc_log_t **lctxp) { REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp)); lctx = *lctxp; + *lctxp = NULL; mctx = lctx->mctx; - if (lctx->logconfig != NULL) { - lcfg = lctx->logconfig; - lctx->logconfig = NULL; + /* Stop the logging as a first thing */ + atomic_store_release(&lctx->debug_level, 0); + atomic_store_release(&lctx->highest_level, 0); + atomic_store_release(&lctx->dynamic, false); + + WRLOCK(&lctx->lcfg_rwl); + lcfg = lctx->logconfig; + lctx->logconfig = NULL; + WRUNLOCK(&lctx->lcfg_rwl); + + if (lcfg != NULL) { isc_logconfig_destroy(&lcfg); } + isc_rwlock_destroy(&lctx->lcfg_rwl); isc_mutex_destroy(&lctx->lock); while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) { @@ -474,7 +414,6 @@ isc_log_destroy(isc_log_t **lctxp) { } lctx->buffer[0] = '\0'; - lctx->debug_level = 0; lctx->categories = NULL; lctx->category_count = 0; lctx->modules = NULL; @@ -483,8 +422,6 @@ isc_log_destroy(isc_log_t **lctxp) { lctx->magic = 0; isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx)); - - *lctxp = NULL; } void @@ -492,19 +429,23 @@ isc_logconfig_destroy(isc_logconfig_t **lcfgp) { isc_logconfig_t *lcfg; isc_mem_t *mctx; isc_logchannel_t *channel; - isc_logchannellist_t *item; char *filename; unsigned int i; REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp)); lcfg = *lcfgp; + *lcfgp = NULL; /* * This function cannot be called with a logconfig that is in * use by a log context. */ - REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg); + REQUIRE(lcfg->lctx != NULL); + + RDLOCK(&lcfg->lctx->lcfg_rwl); + REQUIRE(lcfg->lctx->logconfig != lcfg); + RDUNLOCK(&lcfg->lctx->lcfg_rwl); mctx = lcfg->lctx->mctx; @@ -521,36 +462,39 @@ isc_logconfig_destroy(isc_logconfig_t **lcfgp) { DE_CONST(FILE_NAME(channel), filename); isc_mem_free(mctx, filename); - if (FILE_STREAM(channel) != NULL) + if (FILE_STREAM(channel) != NULL) { (void)fclose(FILE_STREAM(channel)); + } } isc_mem_free(mctx, channel->name); isc_mem_put(mctx, channel, sizeof(*channel)); } - for (i = 0; i < lcfg->channellist_count; i++) + for (i = 0; i < lcfg->channellist_count; i++) { + isc_logchannellist_t *item; while ((item = ISC_LIST_HEAD(lcfg->channellists[i])) != NULL) { ISC_LIST_UNLINK(lcfg->channellists[i], item, link); isc_mem_put(mctx, item, sizeof(*item)); } + } - if (lcfg->channellist_count > 0) + if (lcfg->channellist_count > 0) { isc_mem_put(mctx, lcfg->channellists, lcfg->channellist_count * - sizeof(ISC_LIST(isc_logchannellist_t))); + sizeof(ISC_LIST(isc_logchannellist_t))); + } lcfg->dynamic = false; - if (lcfg->tag != NULL) + if (lcfg->tag != NULL) { isc_mem_free(lcfg->lctx->mctx, lcfg->tag); + } lcfg->tag = NULL; lcfg->highest_level = 0; lcfg->duplicate_interval = 0; lcfg->magic = 0; isc_mem_put(mctx, lcfg, sizeof(*lcfg)); - - *lcfgp = NULL; } void @@ -568,23 +512,24 @@ isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) { * It would need to do that if it had to allocate memory to store * pointers to each array passed in. */ - if (lctx->categories == NULL) + if (lctx->categories == NULL) { lctx->categories = categories; - - else { + } else { /* * Adjust the last (NULL) pointer of the already registered * categories to point to the incoming array. */ - for (catp = lctx->categories; catp->name != NULL; ) - if (catp->id == UINT_MAX) + for (catp = lctx->categories; catp->name != NULL;) { + if (catp->id == UINT_MAX) { /* * The name pointer points to the next array. * Ick. */ DE_CONST(catp->name, catp); - else + } else { catp++; + } + } catp->name = (void *)categories; catp->id = UINT_MAX; @@ -593,8 +538,9 @@ isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) { /* * Update the id number of the category with its new global id. */ - for (catp = categories; catp->name != NULL; catp++) + for (catp = categories; catp->name != NULL; catp++) { catp->id = lctx->category_count++; + } } isc_logcategory_t * @@ -604,18 +550,20 @@ isc_log_categorybyname(isc_log_t *lctx, const char *name) { REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(name != NULL); - for (catp = lctx->categories; catp->name != NULL; ) - if (catp->id == UINT_MAX) + for (catp = lctx->categories; catp->name != NULL;) { + if (catp->id == UINT_MAX) { /* * catp is neither modified nor returned to the * caller, so removing its const qualifier is ok. */ DE_CONST(catp->name, catp); - else { - if (strcmp(catp->name, name) == 0) + } else { + if (strcmp(catp->name, name) == 0) { return (catp); + } catp++; } + } return (NULL); } @@ -635,23 +583,24 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) { * It would need to do that if it had to allocate memory to store * pointers to each array passed in. */ - if (lctx->modules == NULL) + if (lctx->modules == NULL) { lctx->modules = modules; - - else { + } else { /* * Adjust the last (NULL) pointer of the already registered * modules to point to the incoming array. */ - for (modp = lctx->modules; modp->name != NULL; ) - if (modp->id == UINT_MAX) + for (modp = lctx->modules; modp->name != NULL;) { + if (modp->id == UINT_MAX) { /* * The name pointer points to the next array. * Ick. */ DE_CONST(modp->name, modp); - else + } else { modp++; + } + } modp->name = (void *)modules; modp->id = UINT_MAX; @@ -660,8 +609,9 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) { /* * Update the id number of the module with its new global id. */ - for (modp = modules; modp->name != NULL; modp++) + for (modp = modules; modp->name != NULL; modp++) { modp->id = lctx->module_count++; + } } isc_logmodule_t * @@ -671,28 +621,29 @@ isc_log_modulebyname(isc_log_t *lctx, const char *name) { REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(name != NULL); - for (modp = lctx->modules; modp->name != NULL; ) - if (modp->id == UINT_MAX) + for (modp = lctx->modules; modp->name != NULL;) { + if (modp->id == UINT_MAX) { /* * modp is neither modified nor returned to the * caller, so removing its const qualifier is ok. */ DE_CONST(modp->name, modp); - else { - if (strcmp(modp->name, name) == 0) + } else { + if (strcmp(modp->name, name) == 0) { return (modp); + } modp++; } + } return (NULL); } -isc_result_t +void isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, unsigned int type, int level, const isc_logdestination_t *destination, - unsigned int flags) -{ + unsigned int flags) { isc_logchannel_t *channel; isc_mem_t *mctx; unsigned int permitted = ISC_LOG_PRINTALL | ISC_LOG_DEBUGONLY | @@ -701,7 +652,7 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, REQUIRE(VALID_CONFIG(lcfg)); REQUIRE(name != NULL); - REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE || + REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE || type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL); REQUIRE(destination != NULL || type == ISC_LOG_TONULL); REQUIRE(level >= ISC_LOG_CRITICAL); @@ -712,14 +663,8 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, mctx = lcfg->lctx->mctx; channel = isc_mem_get(mctx, sizeof(*channel)); - if (channel == NULL) - return (ISC_R_NOMEMORY); channel->name = isc_mem_strdup(mctx, name); - if (channel->name == NULL) { - isc_mem_put(mctx, channel, sizeof(*channel)); - return (ISC_R_NOMEMORY); - } channel->type = type; channel->level = level; @@ -737,8 +682,8 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, * to scribble on it, so it needs to be definitely in * writable memory. */ - FILE_NAME(channel) = - isc_mem_strdup(mctx, destination->file.name); + FILE_NAME(channel) = isc_mem_strdup(mctx, + destination->file.name); FILE_STREAM(channel) = NULL; FILE_VERSIONS(channel) = destination->file.versions; FILE_SUFFIX(channel) = destination->file.suffix; @@ -759,9 +704,8 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, break; default: - isc_mem_free(mctx, channel->name); - isc_mem_put(mctx, channel, sizeof(*channel)); - return (ISC_R_UNEXPECTED); + INSIST(0); + ISC_UNREACHABLE(); } ISC_LIST_PREPEND(lcfg->channels, channel, link); @@ -770,21 +714,17 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, * If default_stderr was redefined, make the default category * point to the new default_stderr. */ - if (strcmp(name, "default_stderr") == 0) + if (strcmp(name, "default_stderr") == 0) { default_channel.channel = channel; - - return (ISC_R_SUCCESS); + } } isc_result_t isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, const isc_logcategory_t *category, - const isc_logmodule_t *module) -{ + const isc_logmodule_t *module) { isc_log_t *lctx; isc_logchannel_t *channel; - isc_result_t result = ISC_R_SUCCESS; - unsigned int i; REQUIRE(VALID_CONFIG(lcfg)); REQUIRE(name != NULL); @@ -796,33 +736,41 @@ isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL; channel = ISC_LIST_NEXT(channel, link)) - if (strcmp(name, channel->name) == 0) + { + if (strcmp(name, channel->name) == 0) { break; + } + } - if (channel == NULL) + if (channel == NULL) { return (ISC_R_NOTFOUND); + } - if (category != NULL) - result = assignchannel(lcfg, category->id, module, channel); - - else + if (category != NULL) { + assignchannel(lcfg, category->id, module, channel); + } else { /* * Assign to all categories. Note that this includes * the default channel. */ - for (i = 0; i < lctx->category_count; i++) { - result = assignchannel(lcfg, i, module, channel); - if (result != ISC_R_SUCCESS) - break; + for (size_t i = 0; i < lctx->category_count; i++) { + assignchannel(lcfg, i, module, channel); } + } - return (result); + /* + * Update the highest logging level, if the current lcfg is in use. + */ + if (lcfg->lctx->logconfig == lcfg) { + sync_highest_level(lctx, lcfg); + } + + return (ISC_R_SUCCESS); } void isc_log_write(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *format, ...) -{ + isc_logmodule_t *module, int level, const char *format, ...) { va_list args; /* @@ -830,27 +778,23 @@ isc_log_write(isc_log_t *lctx, isc_logcategory_t *category, */ va_start(args, format); - isc_log_doit(lctx, category, module, level, false, - format, args); + isc_log_doit(lctx, category, module, level, false, format, args); va_end(args); } void isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *format, va_list args) -{ + isc_logmodule_t *module, int level, const char *format, + va_list args) { /* * Contract checking is done in isc_log_doit(). */ - isc_log_doit(lctx, category, module, level, false, - format, args); + isc_log_doit(lctx, category, module, level, false, format, args); } void isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *format, ...) -{ + isc_logmodule_t *module, int level, const char *format, ...) { va_list args; /* @@ -858,21 +802,18 @@ isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category, */ va_start(args, format); - isc_log_doit(lctx, category, module, level, true, - format, args); + isc_log_doit(lctx, category, module, level, true, format, args); va_end(args); } void isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *format, va_list args) -{ + isc_logmodule_t *module, int level, const char *format, + va_list args) { /* * Contract checking is done in isc_log_doit(). */ - isc_log_doit(lctx, category, module, level, true, - format, args); + isc_log_doit(lctx, category, module, level, true, format, args); } void @@ -882,34 +823,41 @@ isc_log_setcontext(isc_log_t *lctx) { void isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) { - isc_logchannel_t *channel; - REQUIRE(VALID_CONTEXT(lctx)); - LOCK(&lctx->lock); - - lctx->debug_level = level; + atomic_store_release(&lctx->debug_level, level); /* * Close ISC_LOG_DEBUGONLY channels if level is zero. */ - if (lctx->debug_level == 0) - for (channel = ISC_LIST_HEAD(lctx->logconfig->channels); - channel != NULL; - channel = ISC_LIST_NEXT(channel, link)) - if (channel->type == ISC_LOG_TOFILE && - (channel->flags & ISC_LOG_DEBUGONLY) != 0 && - FILE_STREAM(channel) != NULL) { - (void)fclose(FILE_STREAM(channel)); - FILE_STREAM(channel) = NULL; + if (level == 0) { + RDLOCK(&lctx->lcfg_rwl); + isc_logconfig_t *lcfg = lctx->logconfig; + if (lcfg != NULL) { + LOCK(&lctx->lock); + for (isc_logchannel_t *channel = + ISC_LIST_HEAD(lcfg->channels); + channel != NULL; + channel = ISC_LIST_NEXT(channel, link)) + { + if (channel->type == ISC_LOG_TOFILE && + (channel->flags & ISC_LOG_DEBUGONLY) != 0 && + FILE_STREAM(channel) != NULL) + { + (void)fclose(FILE_STREAM(channel)); + FILE_STREAM(channel) = NULL; + } } - UNLOCK(&lctx->lock); + UNLOCK(&lctx->lock); + } + RDUNLOCK(&lctx->lcfg_rwl); + } } unsigned int isc_log_getdebuglevel(isc_log_t *lctx) { REQUIRE(VALID_CONTEXT(lctx)); - return (lctx->debug_level); + return (atomic_load_acquire(&lctx->debug_level)); } void @@ -926,24 +874,21 @@ isc_log_getduplicateinterval(isc_logconfig_t *lcfg) { return (lcfg->duplicate_interval); } -isc_result_t +void isc_log_settag(isc_logconfig_t *lcfg, const char *tag) { REQUIRE(VALID_CONFIG(lcfg)); if (tag != NULL && *tag != '\0') { - if (lcfg->tag != NULL) + if (lcfg->tag != NULL) { isc_mem_free(lcfg->lctx->mctx, lcfg->tag); + } lcfg->tag = isc_mem_strdup(lcfg->lctx->mctx, tag); - if (lcfg->tag == NULL) - return (ISC_R_NOMEMORY); - } else { - if (lcfg->tag != NULL) + if (lcfg->tag != NULL) { isc_mem_free(lcfg->lctx->mctx, lcfg->tag); + } lcfg->tag = NULL; } - - return (ISC_R_SUCCESS); } char * @@ -961,34 +906,35 @@ isc_log_opensyslog(const char *tag, int options, int facility) { void isc_log_closefilelogs(isc_log_t *lctx) { - isc_logchannel_t *channel; - REQUIRE(VALID_CONTEXT(lctx)); - LOCK(&lctx->lock); - for (channel = ISC_LIST_HEAD(lctx->logconfig->channels); - channel != NULL; - channel = ISC_LIST_NEXT(channel, link)) - - if (channel->type == ISC_LOG_TOFILE && - FILE_STREAM(channel) != NULL) { - (void)fclose(FILE_STREAM(channel)); - FILE_STREAM(channel) = NULL; + RDLOCK(&lctx->lcfg_rwl); + isc_logconfig_t *lcfg = lctx->logconfig; + if (lcfg != NULL) { + LOCK(&lctx->lock); + for (isc_logchannel_t *channel = ISC_LIST_HEAD(lcfg->channels); + channel != NULL; channel = ISC_LIST_NEXT(channel, link)) + { + if (channel->type == ISC_LOG_TOFILE && + FILE_STREAM(channel) != NULL) { + (void)fclose(FILE_STREAM(channel)); + FILE_STREAM(channel) = NULL; + } } - UNLOCK(&lctx->lock); + UNLOCK(&lctx->lock); + } + RDUNLOCK(&lctx->lcfg_rwl); } /**** - **** Internal functions - ****/ +**** Internal functions +****/ -static isc_result_t +static void assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, - const isc_logmodule_t *module, isc_logchannel_t *channel) -{ + const isc_logmodule_t *module, isc_logchannel_t *channel) { isc_logchannellist_t *new_item; isc_log_t *lctx; - isc_result_t result; REQUIRE(VALID_CONFIG(lcfg)); @@ -1001,18 +947,14 @@ assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, /* * Ensure lcfg->channellist_count == lctx->category_count. */ - result = sync_channellist(lcfg); - if (result != ISC_R_SUCCESS) - return (result); + sync_channellist(lcfg); new_item = isc_mem_get(lctx->mctx, sizeof(*new_item)); - if (new_item == NULL) - return (ISC_R_NOMEMORY); new_item->channel = channel; new_item->module = module; - ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id], - new_item, link); + ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id], new_item, + link); /* * Remember the highest logging level set by any channel in the @@ -1020,20 +962,20 @@ assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, * message is too high to be logged by any channel. */ if (channel->type != ISC_LOG_TONULL) { - if (lcfg->highest_level < channel->level) + if (lcfg->highest_level < channel->level) { lcfg->highest_level = channel->level; - if (channel->level == ISC_LOG_DYNAMIC) + } + if (channel->level == ISC_LOG_DYNAMIC) { lcfg->dynamic = true; + } } - - return (ISC_R_SUCCESS); } /* * This would ideally be part of isc_log_registercategories(), except then * that function would have to return isc_result_t instead of void. */ -static isc_result_t +static void sync_channellist(isc_logconfig_t *lcfg) { unsigned int bytes; isc_log_t *lctx; @@ -1045,16 +987,14 @@ sync_channellist(isc_logconfig_t *lcfg) { REQUIRE(lctx->category_count != 0); - if (lctx->category_count == lcfg->channellist_count) - return (ISC_R_SUCCESS); + if (lctx->category_count == lcfg->channellist_count) { + return; + } bytes = lctx->category_count * sizeof(ISC_LIST(isc_logchannellist_t)); lists = isc_mem_get(lctx->mctx, bytes); - if (lists == NULL) - return (ISC_R_NOMEMORY); - memset(lists, 0, bytes); if (lcfg->channellist_count != 0) { @@ -1066,8 +1006,12 @@ sync_channellist(isc_logconfig_t *lcfg) { lcfg->channellists = lists; lcfg->channellist_count = lctx->category_count; +} - return (ISC_R_SUCCESS); +static void +sync_highest_level(isc_log_t *lctx, isc_logconfig_t *lcfg) { + atomic_store(&lctx->highest_level, lcfg->highest_level); + atomic_store(&lctx->dynamic, lcfg->dynamic); } static isc_result_t @@ -1081,7 +1025,7 @@ greatest_version(isc_logfile_t *file, int versions, int *greatestp) { char sep = '/'; #ifdef _WIN32 char *bname2; -#endif +#endif /* ifdef _WIN32 */ /* * It is safe to DE_CONST the file.name because it was copied @@ -1091,11 +1035,12 @@ greatest_version(isc_logfile_t *file, int versions, int *greatestp) { #ifdef _WIN32 bname2 = strrchr(file->name, '\\'); if ((bname != NULL && bname2 != NULL && bname2 > bname) || - (bname == NULL && bname2 != NULL)) { + (bname == NULL && bname2 != NULL)) + { bname = bname2; sep = '\\'; } -#endif +#endif /* ifdef _WIN32 */ if (bname != NULL) { *bname++ = '\0'; dirname = file->name; @@ -1111,14 +1056,16 @@ greatest_version(isc_logfile_t *file, int versions, int *greatestp) { /* * Replace the file separator if it was taken out. */ - if (bname != file->name) + if (bname != file->name) { *(bname - 1) = sep; + } /* * Return if the directory open failed. */ - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } while (isc_dir_read(&dir) == ISC_R_SUCCESS) { if (dir.entry.length > bnamelen && @@ -1133,13 +1080,16 @@ greatest_version(isc_logfile_t *file, int versions, int *greatestp) { if (*digit_end == '\0' && version >= versions) { result = isc_file_remove(dir.entry.name); if (result != ISC_R_SUCCESS && - result != ISC_R_FILENOTFOUND) - syslog(LOG_ERR, "unable to remove " + result != ISC_R_FILENOTFOUND) { + syslog(LOG_ERR, + "unable to remove " "log file '%s': %s", dir.entry.name, isc_result_totext(result)); - } else if (*digit_end == '\0' && version > greatest) + } + } else if (*digit_end == '\0' && version > greatest) { greatest = version; + } } } isc_dir_close(&dir); @@ -1149,19 +1099,73 @@ greatest_version(isc_logfile_t *file, int versions, int *greatestp) { return (ISC_R_SUCCESS); } +static void +insert_sort(int64_t to_keep[], int64_t versions, int version) { + int i = 0; + while (i < versions && version < to_keep[i]) { + i++; + } + if (i == versions) { + return; + } + if (i < versions - 1) { + memmove(&to_keep[i + 1], &to_keep[i], + sizeof(to_keep[0]) * (versions - i - 1)); + } + to_keep[i] = version; +} + +static int64_t +last_to_keep(int64_t versions, isc_dir_t *dirp, char *bname, size_t bnamelen) { + if (versions <= 0) { + return INT64_MAX; + } + + int64_t to_keep[ISC_LOG_MAX_VERSIONS] = { 0 }; + int64_t version = 0; + if (versions > ISC_LOG_MAX_VERSIONS) { + versions = ISC_LOG_MAX_VERSIONS; + } + /* + * First we fill 'to_keep' structure using insertion sort + */ + memset(to_keep, 0, sizeof(to_keep)); + while (isc_dir_read(dirp) == ISC_R_SUCCESS) { + if (dirp->entry.length <= bnamelen || + strncmp(dirp->entry.name, bname, bnamelen) != 0 || + dirp->entry.name[bnamelen] != '.') + { + continue; + } + + char *digit_end; + char *ename = &dirp->entry.name[bnamelen + 1]; + version = strtoull(ename, &digit_end, 10); + if (*digit_end == '\0') { + insert_sort(to_keep, versions, version); + } + } + + isc_dir_reset(dirp); + + /* + * to_keep[versions - 1] is the last one we want to keep + */ + return (to_keep[versions - 1]); +} + static isc_result_t remove_old_tsversions(isc_logfile_t *file, int versions) { isc_result_t result; char *bname, *digit_end; const char *dirname; int64_t version, last = INT64_MAX; - int64_t to_keep[ISC_LOG_MAX_VERSIONS]; size_t bnamelen; isc_dir_t dir; char sep = '/'; #ifdef _WIN32 char *bname2; -#endif +#endif /* ifdef _WIN32 */ /* * It is safe to DE_CONST the file.name because it was copied * with isc_mem_strdup(). @@ -1170,11 +1174,12 @@ remove_old_tsversions(isc_logfile_t *file, int versions) { #ifdef _WIN32 bname2 = strrchr(file->name, '\\'); if ((bname != NULL && bname2 != NULL && bname2 > bname) || - (bname == NULL && bname2 != NULL)) { + (bname == NULL && bname2 != NULL)) + { bname = bname2; sep = '\\'; } -#endif +#endif /* ifdef _WIN32 */ if (bname != NULL) { *bname++ = '\0'; dirname = file->name; @@ -1197,46 +1202,12 @@ remove_old_tsversions(isc_logfile_t *file, int versions) { /* * Return if the directory open failed. */ - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); - - if (versions > 0) { - /* - * First we fill 'to_keep' structure using insertion sort - */ - memset(to_keep, 0, versions * sizeof(long long)); - while (isc_dir_read(&dir) == ISC_R_SUCCESS) { - if (dir.entry.length > bnamelen && - strncmp(dir.entry.name, bname, bnamelen) == 0 && - dir.entry.name[bnamelen] == '.') - { - char *ename = &dir.entry.name[bnamelen + 1]; - version = strtoull(ename, &digit_end, 10); - if (*digit_end == '\0') { - int i = 0; - while (i < versions && - version < to_keep[i]) - { - i++; - } - if (i < versions) { - memmove(&to_keep[i + 1], - &to_keep[i], - sizeof(long long) * - versions - i - 1); - to_keep[i] = version; - } - } - } - } - - /* - * to_keep[versions - 1] is the last one we want to keep - */ - last = to_keep[versions - 1]; - isc_dir_reset(&dir); } + last = last_to_keep(versions, &dir, bname, bnamelen); + /* * Then we remove all files that we don't want to_keep */ @@ -1253,11 +1224,13 @@ remove_old_tsversions(isc_logfile_t *file, int versions) { if (*digit_end == '\0' && version < last) { result = isc_file_remove(dir.entry.name); if (result != ISC_R_SUCCESS && - result != ISC_R_FILENOTFOUND) - syslog(LOG_ERR, "unable to remove " + result != ISC_R_FILENOTFOUND) { + syslog(LOG_ERR, + "unable to remove " "log file '%s': %s", dir.entry.name, isc_result_totext(result)); + } } } } @@ -1285,11 +1258,10 @@ roll_increment(isc_logfile_t *file) { * Find the first missing entry in the log file sequence. */ for (greatest = 0; greatest < INT_MAX; greatest++) { - n = snprintf(current, sizeof(current), - "%s.%u", path, (unsigned)greatest) ; + n = snprintf(current, sizeof(current), "%s.%u", path, + (unsigned)greatest); if (n >= (int)sizeof(current) || n < 0 || - !isc_file_exists(current)) - { + !isc_file_exists(current)) { break; } } @@ -1319,8 +1291,8 @@ roll_increment(isc_logfile_t *file) { result = ISC_R_NOSPACE; } if (result == ISC_R_SUCCESS) { - n = snprintf(newpath, sizeof(newpath), "%s.%u", - path, (unsigned)i); + n = snprintf(newpath, sizeof(newpath), "%s.%u", path, + (unsigned)i); if (n >= (int)sizeof(newpath) || n < 0) { result = ISC_R_NOSPACE; } @@ -1331,8 +1303,8 @@ roll_increment(isc_logfile_t *file) { if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { syslog(LOG_ERR, "unable to rename log file '%s.%u' to " - "'%s.%u': %s", path, i - 1, path, i, - isc_result_totext(result)); + "'%s.%u': %s", + path, i - 1, path, i, isc_result_totext(result)); } } @@ -1343,8 +1315,7 @@ roll_increment(isc_logfile_t *file) { result = isc_file_rename(path, newpath); } if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - syslog(LOG_ERR, - "unable to rename log file '%s' to '%s.0': %s", + syslog(LOG_ERR, "unable to rename log file '%s' to '%s.0': %s", path, path, isc_result_totext(result)); } @@ -1384,15 +1355,13 @@ roll_timestamp(isc_logfile_t *file) { result = isc_file_rename(path, newpath); } if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - syslog(LOG_ERR, - "unable to rename log file '%s' to '%s.0': %s", + syslog(LOG_ERR, "unable to rename log file '%s' to '%s.0': %s", path, path, isc_result_totext(result)); } return (ISC_R_SUCCESS); } - isc_result_t isc_logfile_roll(isc_logfile_t *file) { isc_result_t result; @@ -1408,10 +1377,10 @@ isc_logfile_roll(isc_logfile_t *file) { return (ISC_R_SUCCESS); } else if (file->versions == 0) { result = isc_file_remove(file->name); - if (result != ISC_R_SUCCESS && - result != ISC_R_FILENOTFOUND) + if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { syslog(LOG_ERR, "unable to remove log file '%s': %s", file->name, isc_result_totext(result)); + } return (ISC_R_SUCCESS); } @@ -1452,19 +1421,23 @@ isc_log_open(isc_logchannel_t *channel) { FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) || (FILE_MAXSIZE(channel) > 0 && statbuf.st_size >= FILE_MAXSIZE(channel))) + { roll = regular_file; + } } else if (errno == ENOENT) { regular_file = true; POST(regular_file); - } else + } else { result = ISC_R_INVALIDFILE; + } /* * Version control. */ if (result == ISC_R_SUCCESS && roll) { - if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER) + if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER) { return (ISC_R_MAXSIZE); + } result = isc_logfile_roll(&channel->destination.file); if (result != ISC_R_SUCCESS) { if ((channel->flags & ISC_LOG_OPENERR) == 0) { @@ -1484,7 +1457,7 @@ isc_log_open(isc_logchannel_t *channel) { return (result); } -bool +ISC_NO_SANITIZE_THREAD bool isc_log_wouldlog(isc_log_t *lctx, int level) { /* * Try to avoid locking the mutex for messages which can't @@ -1495,26 +1468,29 @@ isc_log_wouldlog(isc_log_t *lctx, int level) { * highest_level, or if there is a dynamic channel and the level is * less than or equal to the debug level, the main loop must be * entered to see if the message should really be output. - * - * NOTE: this is UNLOCKED access to the logconfig. However, - * the worst thing that can happen is that a bad decision is made - * about returning without logging, and that's not a big concern, - * because that's a risk anyway if the logconfig is being - * dynamically changed. */ - - if (lctx == NULL || lctx->logconfig == NULL) + if (lctx == NULL) { return (false); + } - return (level <= lctx->logconfig->highest_level || - (lctx->logconfig->dynamic && level <= lctx->debug_level)); + int highest_level = atomic_load_acquire(&lctx->highest_level); + if (level <= highest_level) { + return (true); + } + if (atomic_load_acquire(&lctx->dynamic)) { + int debug_level = atomic_load_acquire(&lctx->debug_level); + if (level <= debug_level) { + return (true); + } + } + + return (false); } static void isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, bool write_once, - const char *format, va_list args) -{ + const char *format, va_list args) { int syslog_level; const char *time_string; char local_time[64]; @@ -1525,7 +1501,6 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, bool matched = false; bool printtime, iso8601, utc, printtag, printcolon; bool printcategory, printmodule, printlevel, buffered; - isc_logconfig_t *lcfg; isc_logchannel_t *channel; isc_logchannellist_t *category_channels; isc_result_t result; @@ -1541,55 +1516,62 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, * wanting to do any logging, thus the log context is allowed to * be non-existent. */ - if (lctx == NULL) + if (lctx == NULL) { return; + } REQUIRE(category->id < lctx->category_count); REQUIRE(module->id < lctx->module_count); - if (! isc_log_wouldlog(lctx, level)) + if (!isc_log_wouldlog(lctx, level)) { return; + } local_time[0] = '\0'; iso8601l_string[0] = '\0'; iso8601z_string[0] = '\0'; + RDLOCK(&lctx->lcfg_rwl); LOCK(&lctx->lock); lctx->buffer[0] = '\0'; - lcfg = lctx->logconfig; + isc_logconfig_t *lcfg = lctx->logconfig; category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]); /* - * XXXDCL add duplicate filtering? (To not write multiple times to - * the same source via various channels). + * XXXDCL add duplicate filtering? (To not write multiple times + * to the same source via various channels). */ do { /* - * If the channel list end was reached and a match was made, - * everything is finished. + * If the channel list end was reached and a match was + * made, everything is finished. */ - if (category_channels == NULL && matched) + if (category_channels == NULL && matched) { break; + } - if (category_channels == NULL && ! matched && + if (category_channels == NULL && !matched && category_channels != ISC_LIST_HEAD(lcfg->channellists[0])) + { /* - * No category/module pair was explicitly configured. - * Try the category named "default". + * No category/module pair was explicitly + * configured. Try the category named "default". */ category_channels = ISC_LIST_HEAD(lcfg->channellists[0]); + } - if (category_channels == NULL && ! matched) + if (category_channels == NULL && !matched) { /* * No matching module was explicitly configured - * for the category named "default". Use the internal - * default channel. + * for the category named "default". Use the + * internal default channel. */ category_channels = &default_channel; + } if (category_channels->module != NULL && category_channels->module != module) { @@ -1603,31 +1585,31 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, channel = category_channels->channel; category_channels = ISC_LIST_NEXT(category_channels, link); - if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) && - lctx->debug_level == 0) + int_fast32_t dlevel = atomic_load_acquire(&lctx->debug_level); + if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) && dlevel == 0) + { continue; + } if (channel->level == ISC_LOG_DYNAMIC) { - if (lctx->debug_level < level) + if (dlevel < level) { continue; - } else if (channel->level < level) + } + } else if (channel->level < level) { continue; + } if ((channel->flags & ISC_LOG_PRINTTIME) != 0 && - local_time[0] == '\0') - { + local_time[0] == '\0') { isc_time_t isctime; TIME_NOW(&isctime); - isc_time_formattimestamp(&isctime, - local_time, + isc_time_formattimestamp(&isctime, local_time, sizeof(local_time)); - isc_time_formatISO8601ms(&isctime, - iso8601z_string, + isc_time_formatISO8601ms(&isctime, iso8601z_string, sizeof(iso8601z_string)); - isc_time_formatISO8601Lms(&isctime, - iso8601l_string, + isc_time_formatISO8601Lms(&isctime, iso8601l_string, sizeof(iso8601l_string)); } @@ -1666,36 +1648,41 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, lcfg->duplicate_interval, 0); /* - * 'oldest' is the age of the oldest messages - * which fall within the duplicate_interval - * range. + * 'oldest' is the age of the oldest + * messages which fall within the + * duplicate_interval range. */ TIME_NOW(&oldest); if (isc_time_subtract(&oldest, &interval, - &oldest) - != ISC_R_SUCCESS) + &oldest) != ISC_R_SUCCESS) + { /* - * Can't effectively do the checking - * without having a valid time. + * Can't effectively do the + * checking without having a + * valid time. */ message = NULL; - else + } else { message = ISC_LIST_HEAD(lctx->messages); + } while (message != NULL) { if (isc_time_compare(&message->time, &oldest) < 0) { /* * This message is older - * than the duplicate_interval, - * so it should be dropped from - * the history. + * than the + * duplicate_interval, + * so it should be + * dropped from the + * history. * - * Setting the interval to be - * to be longer will obviously - * not cause the expired - * message to spring back into - * existence. + * Setting the interval + * to be to be longer + * will obviously not + * cause the expired + * message to spring + * back into existence. */ next = ISC_LIST_NEXT(message, link); @@ -1703,28 +1690,29 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, ISC_LIST_UNLINK(lctx->messages, message, link); - isc_mem_put(lctx->mctx, - message, + isc_mem_put( + lctx->mctx, message, sizeof(*message) + 1 + - strlen(message->text)); + strlen(message->text)); message = next; continue; } /* - * This message is in the duplicate - * filtering interval ... + * This message is in the + * duplicate filtering interval + * ... */ - if (strcmp(lctx->buffer, message->text) - == 0) { + if (strcmp(lctx->buffer, + message->text) == 0) { /* - * ... and it is a duplicate. - * Unlock the mutex and - * get the hell out of Dodge. + * ... and it is a + * duplicate. Unlock the + * mutex and get the + * hell out of Dodge. */ - UNLOCK(&lctx->lock); - return; + goto unlock; } message = ISC_LIST_NEXT(message, link); @@ -1737,37 +1725,27 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, size = sizeof(isc_logmessage_t) + strlen(lctx->buffer) + 1; message = isc_mem_get(lctx->mctx, size); - if (message != NULL) { - /* - * Put the text immediately after - * the struct. The strcpy is safe. - */ - message->text = (char *)(message + 1); - size -= sizeof(isc_logmessage_t); - strlcpy(message->text, lctx->buffer, - size); - - TIME_NOW(&message->time); - - ISC_LINK_INIT(message, link); - ISC_LIST_APPEND(lctx->messages, - message, link); - } + message->text = (char *)(message + 1); + size -= sizeof(isc_logmessage_t); + strlcpy(message->text, lctx->buffer, size); + TIME_NOW(&message->time); + ISC_LINK_INIT(message, link); + ISC_LIST_APPEND(lctx->messages, message, link); } } - utc = ((channel->flags & ISC_LOG_UTC) != 0); - iso8601 = ((channel->flags & ISC_LOG_ISO8601) != 0); - printtime = ((channel->flags & ISC_LOG_PRINTTIME) != 0); - printtag = ((channel->flags & - (ISC_LOG_PRINTTAG|ISC_LOG_PRINTPREFIX)) != 0 && - lcfg->tag != NULL); - printcolon = ((channel->flags & ISC_LOG_PRINTTAG) != 0 && - lcfg->tag != NULL); + utc = ((channel->flags & ISC_LOG_UTC) != 0); + iso8601 = ((channel->flags & ISC_LOG_ISO8601) != 0); + printtime = ((channel->flags & ISC_LOG_PRINTTIME) != 0); + printtag = ((channel->flags & + (ISC_LOG_PRINTTAG | ISC_LOG_PRINTPREFIX)) != 0 && + lcfg->tag != NULL); + printcolon = ((channel->flags & ISC_LOG_PRINTTAG) != 0 && + lcfg->tag != NULL); printcategory = ((channel->flags & ISC_LOG_PRINTCATEGORY) != 0); - printmodule = ((channel->flags & ISC_LOG_PRINTMODULE) != 0); - printlevel = ((channel->flags & ISC_LOG_PRINTLEVEL) != 0); - buffered = ((channel->flags & ISC_LOG_BUFFERED) != 0); + printmodule = ((channel->flags & ISC_LOG_PRINTMODULE) != 0); + printlevel = ((channel->flags & ISC_LOG_PRINTLEVEL) != 0); + buffered = ((channel->flags & ISC_LOG_BUFFERED) != 0); if (printtime) { if (iso8601) { @@ -1779,8 +1757,9 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, } else { time_string = local_time; } - } else + } else { time_string = ""; + } switch (channel->type) { case ISC_LOG_TOFILE: @@ -1788,67 +1767,71 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, /* * If the file can be rolled, OR * If the file no longer exists, OR - * If the file is less than the maximum size, - * (such as if it had been renamed and - * a new one touched, or it was truncated - * in place) - * ... then close it to trigger reopening. + * If the file is less than the maximum + * size, (such as if it had been renamed + * and a new one touched, or it was + * truncated in place) + * ... then close it to trigger + * reopening. */ if (FILE_VERSIONS(channel) != - ISC_LOG_ROLLNEVER || + ISC_LOG_ROLLNEVER || (stat(FILE_NAME(channel), &statbuf) != 0 && errno == ENOENT) || - statbuf.st_size < FILE_MAXSIZE(channel)) { + statbuf.st_size < FILE_MAXSIZE(channel)) + { (void)fclose(FILE_STREAM(channel)); FILE_STREAM(channel) = NULL; FILE_MAXREACHED(channel) = false; - } else + } else { /* * Eh, skip it. */ break; + } } if (FILE_STREAM(channel) == NULL) { result = isc_log_open(channel); if (result != ISC_R_SUCCESS && result != ISC_R_MAXSIZE && - (channel->flags & ISC_LOG_OPENERR) == 0) { + (channel->flags & ISC_LOG_OPENERR) == 0) + { syslog(LOG_ERR, - "isc_log_open '%s' failed: %s", + "isc_log_open '%s' " + "failed: %s", FILE_NAME(channel), isc_result_totext(result)); channel->flags |= ISC_LOG_OPENERR; } - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { break; + } channel->flags &= ~ISC_LOG_OPENERR; } /* FALLTHROUGH */ case ISC_LOG_TOFILEDESC: - fprintf(FILE_STREAM(channel), - "%s%s%s%s%s%s%s%s%s%s\n", - printtime ? time_string : "", - printtime ? " " : "", - printtag ? lcfg->tag : "", - printcolon ? ": " : "", - printcategory ? category->name : "", - printcategory ? ": " : "", - printmodule ? (module != NULL ? module->name - : "no_module") - : "", - printmodule ? ": " : "", - printlevel ? level_string : "", - lctx->buffer); - - if (!buffered) + fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n", + printtime ? time_string : "", + printtime ? " " : "", printtag ? lcfg->tag : "", + printcolon ? ": " : "", + printcategory ? category->name : "", + printcategory ? ": " : "", + printmodule ? (module != NULL ? module->name + : "no_module") + : "", + printmodule ? ": " : "", + printlevel ? level_string : "", lctx->buffer); + + if (!buffered) { fflush(FILE_STREAM(channel)); + } /* * If the file now exceeds its maximum size - * threshold, note it so that it will not be logged - * to any more. + * threshold, note it so that it will not be + * logged to any more. */ if (FILE_MAXSIZE(channel) > 0) { INSIST(channel->type == ISC_LOG_TOFILE); @@ -1858,42 +1841,43 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, if (fstat(fileno(FILE_STREAM(channel)), &statbuf) >= 0 && statbuf.st_size > FILE_MAXSIZE(channel)) + { FILE_MAXREACHED(channel) = true; + } } break; case ISC_LOG_TOSYSLOG: - if (level > 0) + if (level > 0) { syslog_level = LOG_DEBUG; - else if (level < ISC_LOG_CRITICAL) + } else if (level < ISC_LOG_CRITICAL) { syslog_level = LOG_CRIT; - else + } else { syslog_level = syslog_map[-level]; + } - (void)syslog(FACILITY(channel) | syslog_level, - "%s%s%s%s%s%s%s%s%s%s", - printtime ? time_string : "", - printtime ? " " : "", - printtag ? lcfg->tag : "", - printcolon ? ": " : "", - printcategory ? category->name : "", - printcategory ? ": " : "", - printmodule ? (module != NULL - ? module->name - : "no_module") - : "", - printmodule ? ": " : "", - printlevel ? level_string : "", - lctx->buffer); + (void)syslog( + FACILITY(channel) | syslog_level, + "%s%s%s%s%s%s%s%s%s%s", + printtime ? time_string : "", + printtime ? " " : "", printtag ? lcfg->tag : "", + printcolon ? ": " : "", + printcategory ? category->name : "", + printcategory ? ": " : "", + printmodule ? (module != NULL ? module->name + : "no_module") + : "", + printmodule ? ": " : "", + printlevel ? level_string : "", lctx->buffer); break; case ISC_LOG_TONULL: break; - } - } while (1); +unlock: UNLOCK(&lctx->lock); + RDUNLOCK(&lctx->lcfg_rwl); } diff --git a/lib/isc/md.c b/lib/isc/md.c index ba310d3c..dbe64ac6 100644 --- a/lib/isc/md.c +++ b/lib/isc/md.c @@ -3,23 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <stdio.h> -#include <isc/md.h> -#include <isc/util.h> - -#include <openssl/evp.h> #include <openssl/err.h> +#include <openssl/evp.h> #include <openssl/opensslv.h> +#include <isc/md.h> +#include <isc/util.h> + #include "openssl_shim.h" isc_md_t * @@ -39,7 +37,7 @@ isc_md_free(isc_md_t *md) { } isc_result_t -isc_md_init(isc_md_t *md, const isc_md_type_t md_type) { +isc_md_init(isc_md_t *md, const isc_md_type_t *md_type) { REQUIRE(md != NULL); if (md_type == NULL) { @@ -91,7 +89,7 @@ isc_md_final(isc_md_t *md, unsigned char *digest, unsigned int *digestlen) { return (ISC_R_SUCCESS); } -isc_md_type_t +const isc_md_type_t * isc_md_get_md_type(isc_md_t *md) { REQUIRE(md != NULL); @@ -113,7 +111,10 @@ isc_md_get_block_size(isc_md_t *md) { } size_t -isc_md_type_get_size(isc_md_type_t md_type) { +isc_md_type_get_size(const isc_md_type_t *md_type) { + STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE, + "Change ISC_MAX_MD_SIZE to be greater than or equal to " + "EVP_MAX_MD_SIZE"); if (md_type != NULL) { return ((size_t)EVP_MD_size(md_type)); } @@ -122,7 +123,10 @@ isc_md_type_get_size(isc_md_type_t md_type) { } size_t -isc_md_type_get_block_size(isc_md_type_t md_type) { +isc_md_type_get_block_size(const isc_md_type_t *md_type) { + STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE, + "Change ISC_MAX_MD_SIZE to be greater than or equal to " + "EVP_MAX_MD_SIZE"); if (md_type != NULL) { return ((size_t)EVP_MD_block_size(md_type)); } @@ -131,9 +135,8 @@ isc_md_type_get_block_size(isc_md_type_t md_type) { } isc_result_t -isc_md(isc_md_type_t md_type, const unsigned char *buf, const size_t len, - unsigned char *digest, unsigned int *digestlen) -{ +isc_md(const isc_md_type_t *md_type, const unsigned char *buf, const size_t len, + unsigned char *digest, unsigned int *digestlen) { isc_md_t *md; isc_result_t res; @@ -153,8 +156,18 @@ isc_md(isc_md_type_t md_type, const unsigned char *buf, const size_t len, if (res != ISC_R_SUCCESS) { goto end; } - end: +end: isc_md_free(md); return (res); } + +#define md_register_algorithm(alg) \ + const isc_md_type_t *isc__md_##alg(void) { return (EVP_##alg()); } + +md_register_algorithm(md5); +md_register_algorithm(sha1); +md_register_algorithm(sha224); +md_register_algorithm(sha256); +md_register_algorithm(sha384); +md_register_algorithm(sha512); diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 01a42a4e..71894af0 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,19 +11,16 @@ /*! \file */ -#include <config.h> - -#include <inttypes.h> #include <errno.h> +#include <inttypes.h> +#include <limits.h> #include <stdbool.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> -#include <stddef.h> -#include <limits.h> #include <isc/bind9.h> #include <isc/hash.h> -#include <isc/json.h> #include <isc/magic.h> #include <isc/mem.h> #include <isc/mutex.h> @@ -33,16 +30,24 @@ #include <isc/strerr.h> #include <isc/string.h> #include <isc/util.h> -#include <isc/xml.h> + +#ifdef HAVE_LIBXML2 +#include <libxml/xmlwriter.h> +#define ISC_XMLCHAR (const xmlChar *) +#endif /* HAVE_LIBXML2 */ + +#ifdef HAVE_JSON_C +#include <json_object.h> +#endif /* HAVE_JSON_C */ #include "mem_p.h" -#define MCTXLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) LOCK(l) -#define MCTXUNLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) UNLOCK(l) +#define MCTXLOCK(m) LOCK(&m->lock) +#define MCTXUNLOCK(m) UNLOCK(&m->lock) #ifndef ISC_MEM_DEBUGGING #define ISC_MEM_DEBUGGING 0 -#endif +#endif /* ifndef ISC_MEM_DEBUGGING */ LIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING; LIBISC_EXTERNAL_DATA unsigned int isc_mem_defaultflags = ISC_MEMFLAG_DEFAULT; @@ -50,12 +55,12 @@ LIBISC_EXTERNAL_DATA unsigned int isc_mem_defaultflags = ISC_MEMFLAG_DEFAULT; * Constants. */ -#define DEF_MAX_SIZE 1100 -#define DEF_MEM_TARGET 4096 -#define ALIGNMENT_SIZE 8U /*%< must be a power of 2 */ -#define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */ -#define TABLE_INCREMENT 1024 -#define DEBUG_TABLE_COUNT 512U +#define DEF_MAX_SIZE 1100 +#define DEF_MEM_TARGET 4096 +#define ALIGNMENT_SIZE 8U /*%< must be a power of 2 */ +#define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */ +#define TABLE_INCREMENT 1024 +#define DEBUG_TABLE_COUNT 512U /* * Types. @@ -66,25 +71,25 @@ typedef struct isc__mempool isc__mempool_t; #if ISC_MEM_TRACKLINES typedef struct debuglink debuglink_t; struct debuglink { - ISC_LINK(debuglink_t) link; - const void *ptr; - size_t size; - const char *file; - unsigned int line; + ISC_LINK(debuglink_t) link; + const void *ptr; + size_t size; + const char *file; + unsigned int line; }; -typedef ISC_LIST(debuglink_t) debuglist_t; +typedef ISC_LIST(debuglink_t) debuglist_t; -#define FLARG_PASS , file, line -#define FLARG , const char *file, unsigned int line -#else +#define FLARG_PASS , file, line +#define FLARG , const char *file, unsigned int line +#else /* if ISC_MEM_TRACKLINES */ #define FLARG_PASS #define FLARG -#endif +#endif /* if ISC_MEM_TRACKLINES */ typedef struct element element; struct element { - element * next; + element *next; }; typedef struct { @@ -92,128 +97,135 @@ typedef struct { * This structure must be ALIGNMENT_SIZE bytes. */ union { - size_t size; - isc__mem_t *ctx; - char bytes[ALIGNMENT_SIZE]; + size_t size; + isc__mem_t *ctx; + char bytes[ALIGNMENT_SIZE]; } u; } size_info; struct stats { - unsigned long gets; - unsigned long totalgets; - unsigned long blocks; - unsigned long freefrags; + unsigned long gets; + unsigned long totalgets; + unsigned long blocks; + unsigned long freefrags; }; -#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C') -#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC) +#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C') +#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC) /* List of all active memory contexts. */ -static ISC_LIST(isc__mem_t) contexts; +static ISC_LIST(isc__mem_t) contexts; -static isc_once_t once = ISC_ONCE_INIT; -static isc_mutex_t contextslock; +static isc_once_t once = ISC_ONCE_INIT; +static isc_mutex_t contextslock; /*% * Total size of lost memory due to a bug of external library. * Locked by the global lock. */ -static uint64_t totallost; +static uint64_t totallost; + +/*% + * Memory allocation and free function definitions. + * isc__memalloc_t must deal with memory allocation failure + * and must never return NULL. + */ +typedef void *(*isc__memalloc_t)(size_t); +typedef void (*isc__memfree_t)(void *); struct isc__mem { - isc_mem_t common; - unsigned int flags; - isc_mutex_t lock; - isc_memalloc_t memalloc; - isc_memfree_t memfree; - void * arg; - size_t max_size; - bool checkfree; - struct stats * stats; - isc_refcount_t references; - char name[16]; - void * tag; - size_t total; - size_t inuse; - size_t maxinuse; - size_t malloced; - size_t maxmalloced; - size_t hi_water; - size_t lo_water; - bool hi_called; - bool is_overmem; - isc_mem_water_t water; - void * water_arg; + isc_mem_t common; + unsigned int flags; + isc_mutex_t lock; + isc__memalloc_t memalloc; + isc__memfree_t memfree; + size_t max_size; + bool checkfree; + struct stats *stats; + isc_refcount_t references; + char name[16]; + void *tag; + size_t total; + size_t inuse; + size_t maxinuse; + size_t malloced; + size_t maxmalloced; + size_t hi_water; + size_t lo_water; + bool hi_called; + bool is_overmem; + isc_mem_water_t water; + void *water_arg; ISC_LIST(isc__mempool_t) pools; - unsigned int poolcnt; + unsigned int poolcnt; /* ISC_MEMFLAG_INTERNAL */ - size_t mem_target; - element ** freelists; - element * basic_blocks; - unsigned char ** basic_table; - unsigned int basic_table_count; - unsigned int basic_table_size; - unsigned char * lowest; - unsigned char * highest; + size_t mem_target; + element **freelists; + element *basic_blocks; + unsigned char **basic_table; + unsigned int basic_table_count; + unsigned int basic_table_size; + unsigned char *lowest; + unsigned char *highest; #if ISC_MEM_TRACKLINES - debuglist_t * debuglist; - size_t debuglistcnt; -#endif + debuglist_t *debuglist; + size_t debuglistcnt; +#endif /* if ISC_MEM_TRACKLINES */ - ISC_LINK(isc__mem_t) link; + ISC_LINK(isc__mem_t) link; }; -#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p') -#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC) +#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p') +#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC) struct isc__mempool { /* always unlocked */ - isc_mempool_t common; /*%< common header of mempool's */ - isc_mutex_t *lock; /*%< optional lock */ - isc__mem_t *mctx; /*%< our memory context */ + isc_mempool_t common; /*%< common header of mempool's */ + isc_mutex_t *lock; /*%< optional lock */ + isc__mem_t *mctx; /*%< our memory context */ /*%< locked via the memory context's lock */ - ISC_LINK(isc__mempool_t) link; /*%< next pool in this mem context */ + ISC_LINK(isc__mempool_t) link; /*%< next pool in this mem context */ /*%< optionally locked from here down */ - element *items; /*%< low water item list */ - size_t size; /*%< size of each item on this pool */ - unsigned int maxalloc; /*%< max number of items allowed */ - unsigned int allocated; /*%< # of items currently given out */ - unsigned int freecount; /*%< # of items on reserved list */ - unsigned int freemax; /*%< # of items allowed on free list */ - unsigned int fillcount; /*%< # of items to fetch on each fill */ + element *items; /*%< low water item list */ + size_t size; /*%< size of each item on this pool */ + unsigned int maxalloc; /*%< max number of items allowed */ + unsigned int allocated; /*%< # of items currently given out */ + unsigned int freecount; /*%< # of items on reserved list */ + unsigned int freemax; /*%< # of items allowed on free list */ + unsigned int fillcount; /*%< # of items to fetch on each fill */ /*%< Stats only. */ - unsigned int gets; /*%< # of requests to this pool */ - /*%< Debugging only. */ + unsigned int gets; /*%< # of requests to this pool */ + /*%< Debugging only. */ #if ISC_MEMPOOL_NAMES - char name[16]; /*%< printed name in stats reports */ -#endif + char name[16]; /*%< printed name in stats reports */ +#endif /* if ISC_MEMPOOL_NAMES */ }; /* * Private Inline-able. */ -#if ! ISC_MEM_TRACKLINES +#if !ISC_MEM_TRACKLINES #define ADD_TRACE(a, b, c, d, e) #define DELETE_TRACE(a, b, c, d, e) #define ISC_MEMFUNC_SCOPE -#else -#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE|ISC_MEM_DEBUGRECORD) -#define ADD_TRACE(a, b, c, d, e) \ - do { \ +#else /* if !ISC_MEM_TRACKLINES */ +#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE | ISC_MEM_DEBUGRECORD) +#define ADD_TRACE(a, b, c, d, e) \ + do { \ if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \ - b != NULL)) \ - add_trace_entry(a, b, c, d, e); \ + b != NULL)) \ + add_trace_entry(a, b, c, d, e); \ } while (0) -#define DELETE_TRACE(a, b, c, d, e) \ - do { \ +#define DELETE_TRACE(a, b, c, d, e) \ + do { \ if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \ - b != NULL)) \ - delete_trace_entry(a, b, c, d, e); \ - } while(0) + b != NULL)) \ + delete_trace_entry(a, b, c, d, e); \ + } while (0) static void print_active(isc__mem_t *ctx, FILE *out); @@ -236,12 +248,8 @@ static void isc___mem_free(isc_mem_t *ctx, void *ptr FLARG); static isc_memmethods_t memmethods = { - isc___mem_get, - isc___mem_put, - isc___mem_putanddetach, - isc___mem_allocate, - isc___mem_reallocate, - isc___mem_strdup, + isc___mem_get, isc___mem_put, isc___mem_putanddetach, + isc___mem_allocate, isc___mem_reallocate, isc___mem_strdup, isc___mem_free, }; @@ -260,17 +268,27 @@ add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) { ptr, size, file, line, mctx); } - if (mctx->debuglist == NULL) + if (mctx->debuglist == NULL) { return; + } - hash = isc_hash_function(&ptr, sizeof(ptr), true, NULL); +#ifdef __COVERITY__ + /* + * Use simple conversion from pointer to hash to avoid + * tainting 'ptr' due to byte swap in isc_hash_function. + */ + hash = (uintptr_t)ptr >> 3; +#else + hash = isc_hash_function(&ptr, sizeof(ptr), true); +#endif idx = hash % DEBUG_TABLE_COUNT; dl = malloc(sizeof(debuglink_t)); INSIST(dl != NULL); mctx->malloced += sizeof(debuglink_t); - if (mctx->malloced > mctx->maxmalloced) + if (mctx->malloced > mctx->maxmalloced) { mctx->maxmalloced = mctx->malloced; + } ISC_LINK_INIT(dl, link); dl->ptr = ptr; @@ -284,8 +302,7 @@ add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) { static void delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size, - const char *file, unsigned int line) -{ + const char *file, unsigned int line) { debuglink_t *dl; uint32_t hash; uint32_t idx; @@ -295,10 +312,19 @@ delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size, ptr, size, file, line, mctx); } - if (mctx->debuglist == NULL) + if (mctx->debuglist == NULL) { return; + } - hash = isc_hash_function(&ptr, sizeof(ptr), true, NULL); +#ifdef __COVERITY__ + /* + * Use simple conversion from pointer to hash to avoid + * tainting 'ptr' due to byte swap in isc_hash_function. + */ + hash = (uintptr_t)ptr >> 3; +#else + hash = isc_hash_function(&ptr, sizeof(ptr), true); +#endif idx = hash % DEBUG_TABLE_COUNT; dl = ISC_LIST_HEAD(mctx->debuglist[idx]); @@ -337,36 +363,35 @@ quantize(size_t size) { * byte boundaries. */ - if (size == 0U) + if (size == 0U) { return (ALIGNMENT_SIZE); + } return ((size + ALIGNMENT_SIZE - 1) & (~(ALIGNMENT_SIZE - 1))); } -static inline bool +static inline void more_basic_blocks(isc__mem_t *ctx) { void *tmp; unsigned char *curr, *next; unsigned char *first, *last; unsigned char **table; unsigned int table_size; - int i; /* Require: we hold the context lock. */ INSIST(ctx->basic_table_count <= ctx->basic_table_size); if (ctx->basic_table_count == ctx->basic_table_size) { table_size = ctx->basic_table_size + TABLE_INCREMENT; - table = (ctx->memalloc)(ctx->arg, - table_size * sizeof(unsigned char *)); - RUNTIME_CHECK(table != NULL); + table = (ctx->memalloc)(table_size * sizeof(unsigned char *)); ctx->malloced += table_size * sizeof(unsigned char *); - if (ctx->malloced > ctx->maxmalloced) + if (ctx->malloced > ctx->maxmalloced) { ctx->maxmalloced = ctx->malloced; + } if (ctx->basic_table_size != 0) { memmove(table, ctx->basic_table, ctx->basic_table_size * - sizeof(unsigned char *)); - (ctx->memfree)(ctx->arg, ctx->basic_table); + sizeof(unsigned char *)); + (ctx->memfree)(ctx->basic_table); ctx->malloced -= ctx->basic_table_size * sizeof(unsigned char *); } @@ -374,18 +399,18 @@ more_basic_blocks(isc__mem_t *ctx) { ctx->basic_table_size = table_size; } - tmp = (ctx->memalloc)(ctx->arg, NUM_BASIC_BLOCKS * ctx->mem_target); - RUNTIME_CHECK(tmp != NULL); - ctx->total += NUM_BASIC_BLOCKS * ctx->mem_target;; + tmp = (ctx->memalloc)(NUM_BASIC_BLOCKS * ctx->mem_target); + ctx->total += NUM_BASIC_BLOCKS * ctx->mem_target; ctx->basic_table[ctx->basic_table_count] = tmp; ctx->basic_table_count++; ctx->malloced += NUM_BASIC_BLOCKS * ctx->mem_target; - if (ctx->malloced > ctx->maxmalloced) - ctx->maxmalloced = ctx->malloced; + if (ctx->malloced > ctx->maxmalloced) { + ctx->maxmalloced = ctx->malloced; + } curr = tmp; next = curr + ctx->mem_target; - for (i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) { + for (int i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) { ((element *)curr)->next = (element *)next; curr = next; next += ctx->mem_target; @@ -397,18 +422,18 @@ more_basic_blocks(isc__mem_t *ctx) { ((element *)curr)->next = NULL; first = tmp; last = first + NUM_BASIC_BLOCKS * ctx->mem_target - 1; - if (first < ctx->lowest || ctx->lowest == NULL) + if (first < ctx->lowest || ctx->lowest == NULL) { ctx->lowest = first; - if (last > ctx->highest) + } + if (last > ctx->highest) { ctx->highest = last; + } ctx->basic_blocks = tmp; - - return (true); } -static inline bool +static inline void more_frags(isc__mem_t *ctx, size_t new_size) { - int i, frags; + int frags; size_t total_size; void *tmp; unsigned char *curr, *next; @@ -418,17 +443,9 @@ more_frags(isc__mem_t *ctx, size_t new_size) { */ if (ctx->basic_blocks == NULL) { - if (!more_basic_blocks(ctx)) { - /* - * We can't get more memory from the OS, or we've - * hit the quota for this context. - */ - /* - * XXXRTH "At quota" notification here. - */ - return (false); - } + more_basic_blocks(ctx); } + INSIST(ctx->basic_blocks != NULL); total_size = ctx->mem_target; tmp = ctx->basic_blocks; @@ -443,7 +460,7 @@ more_frags(isc__mem_t *ctx, size_t new_size) { curr = tmp; next = curr + new_size; total_size -= new_size; - for (i = 0; i < (frags - 1); i++) { + for (int i = 0; i < (frags - 1); i++) { ((element *)curr)->next = (element *)next; curr = next; next += new_size; @@ -464,8 +481,6 @@ more_frags(isc__mem_t *ctx, size_t new_size) { */ ((element *)curr)->next = NULL; ctx->freelists[new_size] = tmp; - - return (true); } static inline void * @@ -477,15 +492,15 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) { /* * memget() was called on something beyond our upper limit. */ - ret = (ctx->memalloc)(ctx->arg, size); - RUNTIME_CHECK(ret != NULL); + ret = (ctx->memalloc)(size); ctx->total += size; ctx->inuse += size; ctx->stats[ctx->max_size].gets++; ctx->stats[ctx->max_size].totalgets++; ctx->malloced += size; - if (ctx->malloced > ctx->maxmalloced) + if (ctx->malloced > ctx->maxmalloced) { ctx->maxmalloced = ctx->malloced; + } /* * If we don't set new_size to size, then the * ISC_MEMFLAG_FILL code might write over bytes we don't @@ -499,8 +514,10 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) { * of memory and then break it up into "new_size"-sized blocks, adding * them to the free list. */ - if (ctx->freelists[new_size] == NULL && !more_frags(ctx, new_size)) - return (NULL); + if (ctx->freelists[new_size] == NULL) { + more_frags(ctx, new_size); + } + INSIST(ctx->freelists[new_size] != NULL); /* * The free list uses the "rounded-up" size "new_size". @@ -509,7 +526,6 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) { ret = ctx->freelists[new_size]; ctx->freelists[new_size] = ctx->freelists[new_size]->next; - /* * The stats[] uses the _actual_ "size" requested by the * caller, with the caveat (in the code above) that "size" >= the @@ -521,10 +537,12 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) { ctx->stats[new_size].freefrags--; ctx->inuse += new_size; - done: +done: if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0) && ISC_LIKELY(ret != NULL)) + { memset(ret, 0xbe, new_size); /* Mnemonic for "beef". */ + } return (ret); } @@ -542,7 +560,7 @@ check_overrun(void *mem, size_t size, size_t new_size) { size++; } } -#endif +#endif /* if ISC_MEM_CHECKOVERRUN */ /* coverity[+free : arg-1] */ static inline void @@ -553,10 +571,11 @@ mem_putunlocked(isc__mem_t *ctx, void *mem, size_t size) { /* * memput() called on something beyond our upper limit. */ - if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) + if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) { memset(mem, 0xde, size); /* Mnemonic for "dead". */ + } - (ctx->memfree)(ctx->arg, mem); + (ctx->memfree)(mem); INSIST(ctx->stats[ctx->max_size].gets != 0U); ctx->stats[ctx->max_size].gets--; INSIST(size <= ctx->inuse); @@ -568,7 +587,7 @@ mem_putunlocked(isc__mem_t *ctx, void *mem, size_t size) { if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) { #if ISC_MEM_CHECKOVERRUN check_overrun(mem, size, new_size); -#endif +#endif /* if ISC_MEM_CHECKOVERRUN */ memset(mem, 0xde, new_size); /* Mnemonic for "dead". */ } @@ -599,20 +618,22 @@ mem_get(isc__mem_t *ctx, size_t size) { #if ISC_MEM_CHECKOVERRUN size += 1; -#endif - ret = (ctx->memalloc)(ctx->arg, size); - RUNTIME_CHECK(ret != NULL); +#endif /* if ISC_MEM_CHECKOVERRUN */ + ret = (ctx->memalloc)(size); if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) { - if (ISC_LIKELY(ret != NULL)) + if (ISC_LIKELY(ret != NULL)) { memset(ret, 0xbe, size); /* Mnemonic for "beef". */ + } } #if ISC_MEM_CHECKOVERRUN - else { - if (ISC_LIKELY(ret != NULL)) - ret[size-1] = 0xbe; + else + { + if (ISC_LIKELY(ret != NULL)) { + ret[size - 1] = 0xbe; + } } -#endif +#endif /* if ISC_MEM_CHECKOVERRUN */ return (ret); } @@ -626,10 +647,11 @@ mem_put(isc__mem_t *ctx, void *mem, size_t size) { #if ISC_MEM_CHECKOVERRUN INSIST(((unsigned char *)mem)[size] == 0xbe); size += 1; -#endif - if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) +#endif /* if ISC_MEM_CHECKOVERRUN */ + if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) { memset(mem, 0xde, size); /* Mnemonic for "dead". */ - (ctx->memfree)(ctx->arg, mem); + } + (ctx->memfree)(mem); } /*! @@ -650,10 +672,11 @@ mem_getstats(isc__mem_t *ctx, size_t size) { #if ISC_MEM_CHECKOVERRUN size += 1; -#endif +#endif /* if ISC_MEM_CHECKOVERRUN */ ctx->malloced += size; - if (ctx->malloced > ctx->maxmalloced) + if (ctx->malloced > ctx->maxmalloced) { ctx->maxmalloced = ctx->malloced; + } } /*! @@ -675,7 +698,7 @@ mem_putstats(isc__mem_t *ctx, void *ptr, size_t size) { } #if ISC_MEM_CHECKOVERRUN size += 1; -#endif +#endif /* if ISC_MEM_CHECKOVERRUN */ ctx->malloced -= size; } @@ -684,9 +707,8 @@ mem_putstats(isc__mem_t *ctx, void *ptr, size_t size) { */ static void * -default_memalloc(void *arg, size_t size) { +default_memalloc(size_t size) { void *ptr; - UNUSED(arg); ptr = malloc(size); @@ -700,7 +722,8 @@ default_memalloc(void *arg, size_t size) { * * [ISO9899] * ISO/IEC WG 9899:2011: Programming languages - C. - * International Organization for Standardization, Geneva, Switzerland. + * International Organization for Standardization, Geneva, + * Switzerland. * http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf */ @@ -715,8 +738,7 @@ default_memalloc(void *arg, size_t size) { } static void -default_memfree(void *arg, void *ptr) { - UNUSED(arg); +default_memfree(void *ptr) { free(ptr); } @@ -727,37 +749,22 @@ initialize_action(void) { totallost = 0; } -/* - * Public. - */ +static void +mem_create(isc_mem_t **ctxp, unsigned int flags) { + REQUIRE(ctxp != NULL && *ctxp == NULL); -isc_result_t -isc_mem_createx(size_t init_max_size, size_t target_size, - isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg, - isc_mem_t **ctxp, unsigned int flags) -{ isc__mem_t *ctx; - REQUIRE(ctxp != NULL && *ctxp == NULL); - REQUIRE(memalloc != NULL); - REQUIRE(memfree != NULL); - STATIC_ASSERT((ALIGNMENT_SIZE & (ALIGNMENT_SIZE - 1)) == 0, "wrong alignment size"); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); - ctx = (memalloc)(arg, sizeof(*ctx)); - RUNTIME_CHECK(ctx != NULL); + ctx = (default_memalloc)(sizeof(*ctx)); - if ((flags & ISC_MEMFLAG_NOLOCK) == 0) { - isc_mutex_init(&ctx->lock); - } + isc_mutex_init(&ctx->lock); - if (init_max_size == 0U) - ctx->max_size = DEF_MAX_SIZE; - else - ctx->max_size = init_max_size; + ctx->max_size = DEF_MAX_SIZE; ctx->flags = flags; isc_refcount_init(&ctx->references, 1); memset(ctx->name, 0, sizeof(ctx->name)); @@ -776,15 +783,14 @@ isc_mem_createx(size_t init_max_size, size_t target_size, ctx->common.impmagic = MEM_MAGIC; ctx->common.magic = ISCAPI_MCTX_MAGIC; ctx->common.methods = (isc_memmethods_t *)&memmethods; - ctx->memalloc = memalloc; - ctx->memfree = memfree; - ctx->arg = arg; + ctx->memalloc = default_memalloc; + ctx->memfree = default_memfree; ctx->stats = NULL; ctx->checkfree = true; #if ISC_MEM_TRACKLINES ctx->debuglist = NULL; ctx->debuglistcnt = 0; -#endif +#endif /* if ISC_MEM_TRACKLINES */ ISC_LIST_INIT(ctx->pools); ctx->poolcnt = 0; ctx->freelists = NULL; @@ -795,24 +801,18 @@ isc_mem_createx(size_t init_max_size, size_t target_size, ctx->lowest = NULL; ctx->highest = NULL; - ctx->stats = (memalloc)(arg, - (ctx->max_size+1) * sizeof(struct stats)); - RUNTIME_CHECK(ctx->stats != NULL); + ctx->stats = + (ctx->memalloc)((ctx->max_size + 1) * sizeof(struct stats)); memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats)); - ctx->malloced += (ctx->max_size+1) * sizeof(struct stats); - ctx->maxmalloced += (ctx->max_size+1) * sizeof(struct stats); + ctx->malloced += (ctx->max_size + 1) * sizeof(struct stats); + ctx->maxmalloced += (ctx->max_size + 1) * sizeof(struct stats); if ((flags & ISC_MEMFLAG_INTERNAL) != 0) { - if (target_size == 0U) - ctx->mem_target = DEF_MEM_TARGET; - else - ctx->mem_target = target_size; - ctx->freelists = (memalloc)(arg, ctx->max_size * - sizeof(element *)); - RUNTIME_CHECK(ctx->freelists != NULL); - memset(ctx->freelists, 0, - ctx->max_size * sizeof(element *)); + ctx->mem_target = DEF_MEM_TARGET; + ctx->freelists = + (ctx->memalloc)(ctx->max_size * sizeof(element *)); + memset(ctx->freelists, 0, ctx->max_size * sizeof(element *)); ctx->malloced += ctx->max_size * sizeof(element *); ctx->maxmalloced += ctx->max_size * sizeof(element *); } @@ -821,25 +821,27 @@ isc_mem_createx(size_t init_max_size, size_t target_size, if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0)) { unsigned int i; - ctx->debuglist = (memalloc)(arg, (DEBUG_TABLE_COUNT * - sizeof(debuglist_t))); - RUNTIME_CHECK(ctx->debuglist != NULL); - for (i = 0; i < DEBUG_TABLE_COUNT; i++) + ctx->debuglist = (ctx->memalloc)( + (DEBUG_TABLE_COUNT * sizeof(debuglist_t))); + for (i = 0; i < DEBUG_TABLE_COUNT; i++) { ISC_LIST_INIT(ctx->debuglist[i]); + } ctx->malloced += DEBUG_TABLE_COUNT * sizeof(debuglist_t); ctx->maxmalloced += DEBUG_TABLE_COUNT * sizeof(debuglist_t); } -#endif +#endif /* if ISC_MEM_TRACKLINES */ LOCK(&contextslock); ISC_LIST_INITANDAPPEND(contexts, ctx, link); UNLOCK(&contextslock); *ctxp = (isc_mem_t *)ctx; - - return (ISC_R_SUCCESS); } +/* + * Public. + */ + static void destroy(isc__mem_t *ctx) { unsigned int i; @@ -857,24 +859,25 @@ destroy(isc__mem_t *ctx) { #if ISC_MEM_TRACKLINES if (ISC_UNLIKELY(ctx->debuglist != NULL)) { debuglink_t *dl; - for (i = 0; i < DEBUG_TABLE_COUNT; i++) - for (dl = ISC_LIST_HEAD(ctx->debuglist[i]); - dl != NULL; - dl = ISC_LIST_HEAD(ctx->debuglist[i])) { - if (ctx->checkfree && dl->ptr != NULL) + for (i = 0; i < DEBUG_TABLE_COUNT; i++) { + for (dl = ISC_LIST_HEAD(ctx->debuglist[i]); dl != NULL; + dl = ISC_LIST_HEAD(ctx->debuglist[i])) + { + if (ctx->checkfree && dl->ptr != NULL) { print_active(ctx, stderr); - INSIST (!ctx->checkfree || dl->ptr == NULL); + } + INSIST(!ctx->checkfree || dl->ptr == NULL); - ISC_LIST_UNLINK(ctx->debuglist[i], - dl, link); + ISC_LIST_UNLINK(ctx->debuglist[i], dl, link); free(dl); ctx->malloced -= sizeof(*dl); } + } - (ctx->memfree)(ctx->arg, ctx->debuglist); + (ctx->memfree)(ctx->debuglist); ctx->malloced -= DEBUG_TABLE_COUNT * sizeof(debuglist_t); } -#endif +#endif /* if ISC_MEM_TRACKLINES */ if (ctx->checkfree) { for (i = 0; i <= ctx->max_size; i++) { @@ -886,44 +889,45 @@ destroy(isc__mem_t *ctx) { ctx, ctx->name, i, ctx->stats[i].gets); #if ISC_MEM_TRACKLINES print_active(ctx, stderr); -#endif +#endif /* if ISC_MEM_TRACKLINES */ INSIST(ctx->stats[i].gets == 0U); } } } - (ctx->memfree)(ctx->arg, ctx->stats); - ctx->malloced -= (ctx->max_size+1) * sizeof(struct stats); + (ctx->memfree)(ctx->stats); + ctx->malloced -= (ctx->max_size + 1) * sizeof(struct stats); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { for (i = 0; i < ctx->basic_table_count; i++) { - (ctx->memfree)(ctx->arg, ctx->basic_table[i]); + (ctx->memfree)(ctx->basic_table[i]); ctx->malloced -= NUM_BASIC_BLOCKS * ctx->mem_target; } - (ctx->memfree)(ctx->arg, ctx->freelists); + (ctx->memfree)(ctx->freelists); ctx->malloced -= ctx->max_size * sizeof(element *); if (ctx->basic_table != NULL) { - (ctx->memfree)(ctx->arg, ctx->basic_table); + (ctx->memfree)(ctx->basic_table); ctx->malloced -= ctx->basic_table_size * sizeof(unsigned char *); } } - if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0) - isc_mutex_destroy(&ctx->lock); + isc_mutex_destroy(&ctx->lock); + ctx->malloced -= sizeof(*ctx); - if (ctx->checkfree) + if (ctx->checkfree) { INSIST(ctx->malloced == 0); - (ctx->memfree)(ctx->arg, ctx); + } + (ctx->memfree)(ctx); } void isc_mem_attach(isc_mem_t *source0, isc_mem_t **targetp) { - isc__mem_t *source = (isc__mem_t *)source0; - - REQUIRE(VALID_CONTEXT(source)); + REQUIRE(VALID_CONTEXT(source0)); REQUIRE(targetp != NULL && *targetp == NULL); + isc__mem_t *source = (isc__mem_t *)source0; + isc_refcount_increment(&source->references); *targetp = (isc_mem_t *)source; @@ -932,6 +936,7 @@ isc_mem_attach(isc_mem_t *source0, isc_mem_t **targetp) { void isc_mem_detach(isc_mem_t **ctxp) { REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); + isc__mem_t *ctx = (isc__mem_t *)*ctxp; *ctxp = NULL; @@ -955,17 +960,19 @@ void isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); REQUIRE(ptr != NULL); + isc__mem_t *ctx = (isc__mem_t *)*ctxp; *ctxp = NULL; if (ISC_UNLIKELY((isc_mem_debugging & - (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)) + (ISC_MEM_DEBUGSIZE | ISC_MEM_DEBUGCTX)) != 0)) { if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { size_info *si = &(((size_info *)ptr)[-1]); size_t oldsize = si->u.size - ALIGNMENT_SIZE; - if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { oldsize -= ALIGNMENT_SIZE; + } INSIST(oldsize == size); } isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); @@ -973,7 +980,7 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { goto destroy; } - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); DELETE_TRACE(ctx, ptr, size, file, line); @@ -983,7 +990,7 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { mem_putstats(ctx, ptr, size); mem_put(ctx, ptr, size); } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); destroy: if (isc_refcount_decrement(&ctx->references) == 1) { @@ -994,24 +1001,22 @@ destroy: void isc_mem_destroy(isc_mem_t **ctxp) { - isc__mem_t *ctx; - /* * This routine provides legacy support for callers who use mctxs * without attaching/detaching. */ - REQUIRE(ctxp != NULL); - ctx = (isc__mem_t *)*ctxp; - REQUIRE(VALID_CONTEXT(ctx)); + REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); + + isc__mem_t *ctx = (isc__mem_t *)*ctxp; #if ISC_MEM_TRACKLINES - if (isc_refcount_decrement(&ctx->references) != 1) { + if (isc_refcount_decrement(&ctx->references) > 1) { print_active(ctx, stderr); } -#else - INSIST(isc_refcount_decrement(&ctx->references) == 1); -#endif +#else /* if ISC_MEM_TRACKLINES */ + isc_refcount_decrementz(&ctx->references); +#endif /* if ISC_MEM_TRACKLINES */ isc_refcount_destroy(&ctx->references); destroy(ctx); @@ -1020,73 +1025,81 @@ isc_mem_destroy(isc_mem_t **ctxp) { void * isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; void *ptr; bool call_water = false; - REQUIRE(VALID_CONTEXT(ctx)); - if (ISC_UNLIKELY((isc_mem_debugging & - (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)) + (ISC_MEM_DEBUGSIZE | ISC_MEM_DEBUGCTX)) != 0)) + { return (isc__mem_allocate(ctx0, size FLARG_PASS)); + } if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); ptr = mem_getunlocked(ctx, size); } else { ptr = mem_get(ctx, size); - MCTXLOCK(ctx, &ctx->lock); - if (ptr != NULL) + MCTXLOCK(ctx); + if (ptr != NULL) { mem_getstats(ctx, size); + } } ADD_TRACE(ctx, ptr, size, file, line); if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) { ctx->is_overmem = true; - if (!ctx->hi_called) + if (!ctx->hi_called) { call_water = true; + } } if (ctx->inuse > ctx->maxinuse) { ctx->maxinuse = ctx->inuse; if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0) + { fprintf(stderr, "maxinuse = %lu\n", (unsigned long)ctx->inuse); + } } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); - if (call_water && (ctx->water != NULL)) + if (call_water && (ctx->water != NULL)) { (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); + } return (ptr); } void isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { + REQUIRE(VALID_CONTEXT(ctx0)); + REQUIRE(ptr != NULL); + isc__mem_t *ctx = (isc__mem_t *)ctx0; bool call_water = false; size_info *si; size_t oldsize; - REQUIRE(VALID_CONTEXT(ctx)); - REQUIRE(ptr != NULL); - if (ISC_UNLIKELY((isc_mem_debugging & - (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)) + (ISC_MEM_DEBUGSIZE | ISC_MEM_DEBUGCTX)) != 0)) { if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { si = &(((size_info *)ptr)[-1]); oldsize = si->u.size - ALIGNMENT_SIZE; - if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { oldsize -= ALIGNMENT_SIZE; + } INSIST(oldsize == size); } isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); return; } - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); DELETE_TRACE(ctx, ptr, size, file, line); @@ -1104,28 +1117,31 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { */ if ((ctx->inuse < ctx->lo_water) || (ctx->lo_water == 0U)) { ctx->is_overmem = false; - if (ctx->hi_called) + if (ctx->hi_called) { call_water = true; + } } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); - if (call_water && (ctx->water != NULL)) + if (call_water && (ctx->water != NULL)) { (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); + } } void isc_mem_waterack(isc_mem_t *ctx0, int flag) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); - REQUIRE(VALID_CONTEXT(ctx)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; - MCTXLOCK(ctx, &ctx->lock); - if (flag == ISC_MEM_LOWATER) + MCTXLOCK(ctx); + if (flag == ISC_MEM_LOWATER) { ctx->hi_called = false; - else if (flag == ISC_MEM_HIWATER) + } else if (flag == ISC_MEM_HIWATER) { ctx->hi_called = true; - MCTXUNLOCK(ctx, &ctx->lock); + } + MCTXUNLOCK(ctx); } #if ISC_MEM_TRACKLINES @@ -1148,9 +1164,10 @@ print_active(isc__mem_t *mctx, FILE *out) { while (dl != NULL) { if (dl->ptr != NULL) { fprintf(out, - "\tptr %p size %zu file %s line %u\n", - dl->ptr, dl->size, - dl->file, dl->line); + "\tptr %p size %zu file %s " + "line %u\n", + dl->ptr, dl->size, dl->file, + dl->line); } dl = ISC_LIST_NEXT(dl, link); } @@ -1161,33 +1178,37 @@ print_active(isc__mem_t *mctx, FILE *out) { } } } -#endif +#endif /* if ISC_MEM_TRACKLINES */ /* * Print the stats[] on the stream "out" with suitable formatting. */ void isc_mem_stats(isc_mem_t *ctx0, FILE *out) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t i; const struct stats *s; const isc__mempool_t *pool; - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); for (i = 0; i <= ctx->max_size; i++) { s = &ctx->stats[i]; - if (s->totalgets == 0U && s->gets == 0U) + if (s->totalgets == 0U && s->gets == 0U) { continue; + } fprintf(out, "%s%5lu: %11lu gets, %11lu rem", - (i == ctx->max_size) ? ">=" : " ", - (unsigned long) i, s->totalgets, s->gets); + (i == ctx->max_size) ? ">=" : " ", (unsigned long)i, + s->totalgets, s->gets); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0 && (s->blocks != 0U || s->freefrags != 0U)) - fprintf(out, " (%lu bl, %lu ff)", - s->blocks, s->freefrags); + { + fprintf(out, " (%lu bl, %lu ff)", s->blocks, + s->freefrags); + } fputc('\n', out); } @@ -1209,10 +1230,10 @@ isc_mem_stats(isc_mem_t *ctx0, FILE *out) { fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n", #if ISC_MEMPOOL_NAMES pool->name, -#else +#else /* if ISC_MEMPOOL_NAMES */ "(not tracked)", -#endif - (unsigned long) pool->size, pool->maxalloc, +#endif /* if ISC_MEMPOOL_NAMES */ + (unsigned long)pool->size, pool->maxalloc, pool->allocated, pool->freecount, pool->freemax, pool->fillcount, pool->gets, (pool->lock == NULL ? "N" : "Y")); @@ -1221,9 +1242,9 @@ isc_mem_stats(isc_mem_t *ctx0, FILE *out) { #if ISC_MEM_TRACKLINES print_active(ctx, out); -#endif +#endif /* if ISC_MEM_TRACKLINES */ - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); } /* @@ -1237,16 +1258,16 @@ mem_allocateunlocked(isc_mem_t *ctx0, size_t size) { size_info *si; size += ALIGNMENT_SIZE; - if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) + if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) { size += ALIGNMENT_SIZE; + } - if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) + if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { si = mem_getunlocked(ctx, size); - else + } else { si = mem_get(ctx, size); + } - if (si == NULL) - return (NULL); if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) { si->u.ctx = ctx; si++; @@ -1257,16 +1278,17 @@ mem_allocateunlocked(isc_mem_t *ctx0, size_t size) { void * isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_info *si; bool call_water = false; - REQUIRE(VALID_CONTEXT(ctx)); - - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); si = mem_allocateunlocked((isc_mem_t *)ctx, size); - if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0) && (si != NULL)) + if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0)) { mem_getstats(ctx, si[-1].u.size); + } ADD_TRACE(ctx, si, si[-1].u.size, file, line); if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && @@ -1284,25 +1306,27 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) { if (ISC_UNLIKELY(ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0)) + { fprintf(stderr, "maxinuse = %lu\n", (unsigned long)ctx->inuse); + } } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); - if (call_water) + if (call_water) { (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); + } return (si); } void * isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); + void *new_ptr = NULL; size_t oldsize, copysize; - REQUIRE(VALID_CONTEXT(ctx)); - /* * This function emulates the realloc(3) standard library function: * - if size > 0, allocate new memory; and if ptr is non NULL, copy @@ -1321,8 +1345,7 @@ isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { INSIST(oldsize >= ALIGNMENT_SIZE); oldsize -= ALIGNMENT_SIZE; if (ISC_UNLIKELY((isc_mem_debugging & - ISC_MEM_DEBUGCTX) != 0)) - { + ISC_MEM_DEBUGCTX) != 0)) { INSIST(oldsize >= ALIGNMENT_SIZE); oldsize -= ALIGNMENT_SIZE; } @@ -1330,21 +1353,22 @@ isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { memmove(new_ptr, ptr, copysize); isc__mem_free(ctx0, ptr FLARG_PASS); } - } else if (ptr != NULL) + } else if (ptr != NULL) { isc__mem_free(ctx0, ptr FLARG_PASS); + } return (new_ptr); } void isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) { + REQUIRE(VALID_CONTEXT(ctx0)); + REQUIRE(ptr != NULL); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_info *si; size_t size; - bool call_water= false; - - REQUIRE(VALID_CONTEXT(ctx)); - REQUIRE(ptr != NULL); + bool call_water = false; if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) { si = &(((size_info *)ptr)[-2]); @@ -1355,7 +1379,7 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) { size = si->u.size; } - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); DELETE_TRACE(ctx, ptr, size, file, line); @@ -1380,109 +1404,114 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) { (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { ctx->hi_called = false; - if (ctx->water != NULL) + if (ctx->water != NULL) { call_water = true; + } } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); - if (call_water) + if (call_water) { (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); + } } - /* * Other useful things. */ char * isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) { + REQUIRE(VALID_CONTEXT(mctx0)); + REQUIRE(s != NULL); + isc__mem_t *mctx = (isc__mem_t *)mctx0; size_t len; char *ns; - REQUIRE(VALID_CONTEXT(mctx)); - REQUIRE(s != NULL); - len = strlen(s) + 1; ns = isc__mem_allocate((isc_mem_t *)mctx, len FLARG_PASS); - if (ns != NULL) + if (ns != NULL) { strlcpy(ns, s, len); + } return (ns); } void isc_mem_setdestroycheck(isc_mem_t *ctx0, bool flag) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); ctx->checkfree = flag; - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); } size_t isc_mem_inuse(isc_mem_t *ctx0) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t inuse; - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); inuse = ctx->inuse; - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); return (inuse); } size_t isc_mem_maxinuse(isc_mem_t *ctx0) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t maxinuse; - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); maxinuse = ctx->maxinuse; - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); return (maxinuse); } size_t isc_mem_total(isc_mem_t *ctx0) { + REQUIRE(VALID_CONTEXT(ctx0)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t total; - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); total = ctx->total; - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); return (total); } void isc_mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg, - size_t hiwater, size_t lowater) -{ + size_t hiwater, size_t lowater) { + REQUIRE(VALID_CONTEXT(ctx0)); + REQUIRE(hiwater >= lowater); + isc__mem_t *ctx = (isc__mem_t *)ctx0; bool callwater = false; isc_mem_water_t oldwater; void *oldwater_arg; - REQUIRE(VALID_CONTEXT(ctx)); - REQUIRE(hiwater >= lowater); - - MCTXLOCK(ctx, &ctx->lock); + MCTXLOCK(ctx); oldwater = ctx->water; oldwater_arg = ctx->water_arg; if (water == NULL) { @@ -1495,23 +1524,26 @@ isc_mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg, if (ctx->hi_called && (ctx->water != water || ctx->water_arg != water_arg || ctx->inuse < lowater || lowater == 0U)) + { callwater = true; + } ctx->water = water; ctx->water_arg = water_arg; ctx->hi_water = hiwater; ctx->lo_water = lowater; } - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); - if (callwater && oldwater != NULL) + if (callwater && oldwater != NULL) { (oldwater)(oldwater_arg, ISC_MEM_LOWATER); + } } -bool +ISC_NO_SANITIZE_THREAD bool isc_mem_isovermem(isc_mem_t *ctx0) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); - REQUIRE(VALID_CONTEXT(ctx)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; /* * We don't bother to lock the context because 100% accuracy isn't @@ -1523,9 +1555,9 @@ isc_mem_isovermem(isc_mem_t *ctx0) { void isc_mem_setname(isc_mem_t *ctx0, const char *name, void *tag) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); - REQUIRE(VALID_CONTEXT(ctx)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; LOCK(&ctx->lock); strlcpy(ctx->name, name, sizeof(ctx->name)); @@ -1535,21 +1567,22 @@ isc_mem_setname(isc_mem_t *ctx0, const char *name, void *tag) { const char * isc_mem_getname(isc_mem_t *ctx0) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); - REQUIRE(VALID_CONTEXT(ctx)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; - if (ctx->name[0] == 0) + if (ctx->name[0] == 0) { return (""); + } return (ctx->name); } void * isc_mem_gettag(isc_mem_t *ctx0) { - isc__mem_t *ctx = (isc__mem_t *)ctx0; + REQUIRE(VALID_CONTEXT(ctx0)); - REQUIRE(VALID_CONTEXT(ctx)); + isc__mem_t *ctx = (isc__mem_t *)ctx0; return (ctx->tag); } @@ -1558,21 +1591,20 @@ isc_mem_gettag(isc_mem_t *ctx0) { * Memory pool stuff */ -isc_result_t +void isc_mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) { - isc__mem_t *mctx = (isc__mem_t *)mctx0; - isc__mempool_t *mpctx; - - REQUIRE(VALID_CONTEXT(mctx)); + REQUIRE(VALID_CONTEXT(mctx0)); REQUIRE(size > 0U); REQUIRE(mpctxp != NULL && *mpctxp == NULL); + isc__mem_t *mctx = (isc__mem_t *)mctx0; + isc__mempool_t *mpctx; + /* * Allocate space for this pool, initialize values, and if all works * well, attach to the memory context. */ mpctx = isc_mem_get((isc_mem_t *)mctx, sizeof(isc__mempool_t)); - RUNTIME_CHECK(mpctx != NULL); mpctx->common.impmagic = MEMPOOL_MAGIC; mpctx->common.magic = ISCAPI_MPOOL_MAGIC; @@ -1593,70 +1625,73 @@ isc_mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) { mpctx->gets = 0; #if ISC_MEMPOOL_NAMES mpctx->name[0] = 0; -#endif +#endif /* if ISC_MEMPOOL_NAMES */ mpctx->items = NULL; *mpctxp = (isc_mempool_t *)mpctx; - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link); mctx->poolcnt++; - MCTXUNLOCK(mctx, &mctx->lock); - - return (ISC_R_SUCCESS); + MCTXUNLOCK(mctx); } void isc_mempool_setname(isc_mempool_t *mpctx0, const char *name) { - isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - + REQUIRE(VALID_MEMPOOL(mpctx0)); REQUIRE(name != NULL); - REQUIRE(VALID_MEMPOOL(mpctx)); + + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; #if ISC_MEMPOOL_NAMES - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } strlcpy(mpctx->name, name, sizeof(mpctx->name)); - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); -#else + } +#else /* if ISC_MEMPOOL_NAMES */ UNUSED(mpctx); UNUSED(name); -#endif +#endif /* if ISC_MEMPOOL_NAMES */ } void isc_mempool_destroy(isc_mempool_t **mpctxp) { + REQUIRE(mpctxp != NULL); + REQUIRE(VALID_MEMPOOL(*mpctxp)); + isc__mempool_t *mpctx; isc__mem_t *mctx; isc_mutex_t *lock; element *item; - REQUIRE(mpctxp != NULL); mpctx = (isc__mempool_t *)*mpctxp; - REQUIRE(VALID_MEMPOOL(mpctx)); #if ISC_MEMPOOL_NAMES - if (mpctx->allocated > 0) + if (mpctx->allocated > 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mempool_destroy(): mempool %s " "leaked memory", mpctx->name); -#endif + } +#endif /* if ISC_MEMPOOL_NAMES */ REQUIRE(mpctx->allocated == 0); mctx = mpctx->mctx; lock = mpctx->lock; - if (lock != NULL) + if (lock != NULL) { LOCK(lock); + } /* * Return any items on the free list */ - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); while (mpctx->items != NULL) { INSIST(mpctx->freecount > 0); mpctx->freecount--; @@ -1670,51 +1705,54 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) { mem_put(mctx, item, mpctx->size); } } - MCTXUNLOCK(mctx, &mctx->lock); + MCTXUNLOCK(mctx); /* * Remove our linked list entry from the memory context. */ - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); ISC_LIST_UNLINK(mctx->pools, mpctx, link); mctx->poolcnt--; - MCTXUNLOCK(mctx, &mctx->lock); + MCTXUNLOCK(mctx); mpctx->common.impmagic = 0; mpctx->common.magic = 0; isc_mem_put((isc_mem_t *)mpctx->mctx, mpctx, sizeof(isc__mempool_t)); - if (lock != NULL) + if (lock != NULL) { UNLOCK(lock); + } *mpctxp = NULL; } void isc_mempool_associatelock(isc_mempool_t *mpctx0, isc_mutex_t *lock) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + REQUIRE(lock != NULL); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(mpctx->lock == NULL); - REQUIRE(lock != NULL); mpctx->lock = lock; } void * isc__mempool_get(isc_mempool_t *mpctx0 FLARG) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; element *item; isc__mem_t *mctx; unsigned int i; - REQUIRE(VALID_MEMPOOL(mpctx)); - mctx = mpctx->mctx; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } /* * Don't let the caller go over quota @@ -1729,30 +1767,33 @@ isc__mempool_get(isc_mempool_t *mpctx0 FLARG) { * We need to dip into the well. Lock the memory context * here and fill up our free list. */ - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); for (i = 0; i < mpctx->fillcount; i++) { if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { item = mem_getunlocked(mctx, mpctx->size); } else { item = mem_get(mctx, mpctx->size); - if (item != NULL) + if (item != NULL) { mem_getstats(mctx, mpctx->size); + } } - if (ISC_UNLIKELY(item == NULL)) + if (ISC_UNLIKELY(item == NULL)) { break; + } item->next = mpctx->items; mpctx->items = item; mpctx->freecount++; } - MCTXUNLOCK(mctx, &mctx->lock); + MCTXUNLOCK(mctx); } /* * If we didn't get any items, return NULL. */ item = mpctx->items; - if (ISC_UNLIKELY(item == NULL)) + if (ISC_UNLIKELY(item == NULL)) { goto out; + } mpctx->items = item->next; INSIST(mpctx->freecount > 0); @@ -1760,17 +1801,17 @@ isc__mempool_get(isc_mempool_t *mpctx0 FLARG) { mpctx->gets++; mpctx->allocated++; - out: - if (mpctx->lock != NULL) +out: + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } #if ISC_MEM_TRACKLINES if (ISC_UNLIKELY(((isc_mem_debugging & TRACE_OR_RECORD) != 0) && - item != NULL)) - { - MCTXLOCK(mctx, &mctx->lock); + item != NULL)) { + MCTXLOCK(mctx); ADD_TRACE(mctx, item, mpctx->size, file, line); - MCTXUNLOCK(mctx, &mctx->lock); + MCTXUNLOCK(mctx); } #endif /* ISC_MEM_TRACKLINES */ @@ -1780,26 +1821,25 @@ isc__mempool_get(isc_mempool_t *mpctx0 FLARG) { /* coverity[+free : arg-1] */ void isc__mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) { - isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - isc__mem_t *mctx; - element *item; - - REQUIRE(VALID_MEMPOOL(mpctx)); + REQUIRE(VALID_MEMPOOL(mpctx0)); REQUIRE(mem != NULL); - mctx = mpctx->mctx; + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; + isc__mem_t *mctx = mpctx->mctx; + element *item; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } INSIST(mpctx->allocated > 0); mpctx->allocated--; #if ISC_MEM_TRACKLINES if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0)) { - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); DELETE_TRACE(mctx, mem, mpctx->size, file, line); - MCTXUNLOCK(mctx, &mctx->lock); + MCTXUNLOCK(mctx); } #endif /* ISC_MEM_TRACKLINES */ @@ -1807,16 +1847,17 @@ isc__mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) { * If our free list is full, return this to the mctx directly. */ if (mpctx->freecount >= mpctx->freemax) { - MCTXLOCK(mctx, &mctx->lock); + MCTXLOCK(mctx); if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(mctx, mem, mpctx->size); } else { mem_putstats(mctx, mem, mpctx->size); mem_put(mctx, mem, mpctx->size); } - MCTXUNLOCK(mctx, &mctx->lock); - if (mpctx->lock != NULL) + MCTXUNLOCK(mctx); + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return; } @@ -1828,8 +1869,9 @@ isc__mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) { item->next = mpctx->items; mpctx->items = item; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } } /* @@ -1838,139 +1880,154 @@ isc__mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) { void isc_mempool_setfreemax(isc_mempool_t *mpctx0, unsigned int limit) { - isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; + REQUIRE(VALID_MEMPOOL(mpctx0)); - REQUIRE(VALID_MEMPOOL(mpctx)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } mpctx->freemax = limit; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } } unsigned int isc_mempool_getfreemax(isc_mempool_t *mpctx0) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int freemax; - REQUIRE(VALID_MEMPOOL(mpctx)); - - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } freemax = mpctx->freemax; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return (freemax); } unsigned int isc_mempool_getfreecount(isc_mempool_t *mpctx0) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int freecount; - REQUIRE(VALID_MEMPOOL(mpctx)); - - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } freecount = mpctx->freecount; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return (freecount); } void isc_mempool_setmaxalloc(isc_mempool_t *mpctx0, unsigned int limit) { - isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - + REQUIRE(VALID_MEMPOOL(mpctx0)); REQUIRE(limit > 0); - REQUIRE(VALID_MEMPOOL(mpctx)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } mpctx->maxalloc = limit; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } } unsigned int isc_mempool_getmaxalloc(isc_mempool_t *mpctx0) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int maxalloc; - REQUIRE(VALID_MEMPOOL(mpctx)); - - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } maxalloc = mpctx->maxalloc; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return (maxalloc); } unsigned int isc_mempool_getallocated(isc_mempool_t *mpctx0) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int allocated; - REQUIRE(VALID_MEMPOOL(mpctx)); - - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } allocated = mpctx->allocated; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return (allocated); } void isc_mempool_setfillcount(isc_mempool_t *mpctx0, unsigned int limit) { - isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; - + REQUIRE(VALID_MEMPOOL(mpctx0)); REQUIRE(limit > 0); - REQUIRE(VALID_MEMPOOL(mpctx)); - if (mpctx->lock != NULL) + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; + + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } mpctx->fillcount = limit; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } } unsigned int isc_mempool_getfillcount(isc_mempool_t *mpctx0) { + REQUIRE(VALID_MEMPOOL(mpctx0)); + isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int fillcount; - REQUIRE(VALID_MEMPOOL(mpctx)); - - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { LOCK(mpctx->lock); + } fillcount = mpctx->fillcount; - if (mpctx->lock != NULL) + if (mpctx->lock != NULL) { UNLOCK(mpctx->lock); + } return (fillcount); } @@ -1982,13 +2039,10 @@ static void print_contexts(FILE *file) { isc__mem_t *ctx; - for (ctx = ISC_LIST_HEAD(contexts); - ctx != NULL; - ctx = ISC_LIST_NEXT(ctx, link)) - { + for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; + ctx = ISC_LIST_NEXT(ctx, link)) { fprintf(file, "context: %p (%s): %" PRIuFAST32 " references\n", - ctx, - ctx->name[0] == 0 ? "<unknown>" : ctx->name, + ctx, ctx->name[0] == 0 ? "<unknown>" : ctx->name, isc_refcount_current(&ctx->references)); print_active(ctx, file); } @@ -1999,7 +2053,7 @@ void isc_mem_checkdestroyed(FILE *file) { #if !ISC_MEM_TRACKLINES UNUSED(file); -#endif +#endif /* if !ISC_MEM_TRACKLINES */ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2009,7 +2063,7 @@ isc_mem_checkdestroyed(FILE *file) { if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0)) { print_contexts(file); } -#endif +#endif /* if ISC_MEM_TRACKLINES */ INSIST(0); ISC_UNREACHABLE(); } @@ -2023,24 +2077,28 @@ isc_mem_references(isc_mem_t *ctx0) { } typedef struct summarystat { - uint64_t total; - uint64_t inuse; - uint64_t malloced; - uint64_t blocksize; - uint64_t contextsize; + uint64_t total; + uint64_t inuse; + uint64_t malloced; + uint64_t blocksize; + uint64_t contextsize; } summarystat_t; #ifdef HAVE_LIBXML2 -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +#define TRY0(a) \ + do { \ + xmlrc = (a); \ + if (xmlrc < 0) \ + goto error; \ + } while (0) static int xml_renderctx(isc__mem_t *ctx, summarystat_t *summary, - xmlTextWriterPtr writer) -{ - int xmlrc; - + xmlTextWriterPtr writer) { REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); + int xmlrc; + + MCTXLOCK(ctx); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "context")); @@ -2055,66 +2113,61 @@ xml_renderctx(isc__mem_t *ctx, summarystat_t *summary, } summary->contextsize += sizeof(*ctx) + - (ctx->max_size + 1) * sizeof(struct stats) + - ctx->max_size * sizeof(element *) + - ctx->basic_table_count * sizeof(char *); + (ctx->max_size + 1) * sizeof(struct stats) + + ctx->max_size * sizeof(element *) + + ctx->basic_table_count * sizeof(char *); #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) { - summary->contextsize += - DEBUG_TABLE_COUNT * sizeof(debuglist_t) + - ctx->debuglistcnt * sizeof(debuglink_t); + summary->contextsize += DEBUG_TABLE_COUNT * + sizeof(debuglist_t) + + ctx->debuglistcnt * sizeof(debuglink_t); } -#endif +#endif /* if ISC_MEM_TRACKLINES */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); - TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIuFAST32, - isc_refcount_current(&ctx->references))); + TRY0(xmlTextWriterWriteFormatString( + writer, "%" PRIuFAST32, + isc_refcount_current(&ctx->references))); TRY0(xmlTextWriterEndElement(writer)); /* references */ summary->total += ctx->total; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "total")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->total)); TRY0(xmlTextWriterEndElement(writer)); /* total */ summary->inuse += ctx->inuse; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->inuse)); TRY0(xmlTextWriterEndElement(writer)); /* inuse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->maxinuse)); TRY0(xmlTextWriterEndElement(writer)); /* maxinuse */ summary->malloced += ctx->malloced; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "malloced")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->malloced)); TRY0(xmlTextWriterEndElement(writer)); /* malloced */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxmalloced")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->maxmalloced)); TRY0(xmlTextWriterEndElement(writer)); /* maxmalloced */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize")); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { summary->blocksize += ctx->basic_table_count * - NUM_BASIC_BLOCKS * ctx->mem_target; - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", - (uint64_t) - ctx->basic_table_count * - NUM_BASIC_BLOCKS * - ctx->mem_target)); - } else + NUM_BASIC_BLOCKS * ctx->mem_target; + TRY0(xmlTextWriterWriteFormatString( + writer, "%" PRIu64 "", + (uint64_t)ctx->basic_table_count * NUM_BASIC_BLOCKS * + ctx->mem_target)); + } else { TRY0(xmlTextWriterWriteFormatString(writer, "%s", "-")); + } TRY0(xmlTextWriterEndElement(writer)); /* blocksize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools")); @@ -2123,31 +2176,30 @@ xml_renderctx(isc__mem_t *ctx, summarystat_t *summary, summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->hi_water)); TRY0(xmlTextWriterEndElement(writer)); /* hiwater */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", (uint64_t)ctx->lo_water)); TRY0(xmlTextWriterEndElement(writer)); /* lowater */ TRY0(xmlTextWriterEndElement(writer)); /* context */ - error: - MCTXUNLOCK(ctx, &ctx->lock); +error: + MCTXUNLOCK(ctx); return (xmlrc); } int -isc_mem_renderxml(xmlTextWriterPtr writer) { +isc_mem_renderxml(void *writer0) { isc__mem_t *ctx; summarystat_t summary; uint64_t lost; int xmlrc; + xmlTextWriterPtr writer = (xmlTextWriterPtr)writer0; memset(&summary, 0, sizeof(summary)); @@ -2157,8 +2209,7 @@ isc_mem_renderxml(xmlTextWriterPtr writer) { LOCK(&contextslock); lost = totallost; - for (ctx = ISC_LIST_HEAD(contexts); - ctx != NULL; + for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { xmlrc = xml_renderctx(ctx, &summary, writer); if (xmlrc < 0) { @@ -2173,79 +2224,73 @@ isc_mem_renderxml(xmlTextWriterPtr writer) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", summary.total)); TRY0(xmlTextWriterEndElement(writer)); /* TotalUse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", summary.inuse)); TRY0(xmlTextWriterEndElement(writer)); /* InUse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Malloced")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", summary.malloced)); TRY0(xmlTextWriterEndElement(writer)); /* InUse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", summary.blocksize)); TRY0(xmlTextWriterEndElement(writer)); /* BlockSize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", summary.contextsize)); TRY0(xmlTextWriterEndElement(writer)); /* ContextSize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64 "", - lost)); + TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64 "", lost)); TRY0(xmlTextWriterEndElement(writer)); /* Lost */ TRY0(xmlTextWriterEndElement(writer)); /* summary */ - error: +error: return (xmlrc); } #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C #define CHECKMEM(m) RUNTIME_CHECK(m != NULL) static isc_result_t json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) { - json_object *ctxobj, *obj; - char buf[1024]; - REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(summary != NULL); REQUIRE(array != NULL); - MCTXLOCK(ctx, &ctx->lock); + json_object *ctxobj, *obj; + char buf[1024]; + + MCTXLOCK(ctx); summary->contextsize += sizeof(*ctx) + - (ctx->max_size + 1) * sizeof(struct stats) + - ctx->max_size * sizeof(element *) + - ctx->basic_table_count * sizeof(char *); + (ctx->max_size + 1) * sizeof(struct stats) + + ctx->max_size * sizeof(element *) + + ctx->basic_table_count * sizeof(char *); summary->total += ctx->total; summary->inuse += ctx->inuse; summary->malloced += ctx->malloced; - if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) + if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { summary->blocksize += ctx->basic_table_count * - NUM_BASIC_BLOCKS * ctx->mem_target; + NUM_BASIC_BLOCKS * ctx->mem_target; + } #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) { - summary->contextsize += - DEBUG_TABLE_COUNT * sizeof(debuglist_t) + - ctx->debuglistcnt * sizeof(debuglink_t); + summary->contextsize += DEBUG_TABLE_COUNT * + sizeof(debuglist_t) + + ctx->debuglistcnt * sizeof(debuglink_t); } -#endif +#endif /* if ISC_MEM_TRACKLINES */ ctxobj = json_object_new_object(); CHECKMEM(ctxobj); @@ -2288,7 +2333,7 @@ json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { uint64_t blocksize; blocksize = ctx->basic_table_count * NUM_BASIC_BLOCKS * - ctx->mem_target; + ctx->mem_target; obj = json_object_new_int64(blocksize); CHECKMEM(obj); json_object_object_add(ctxobj, "blocksize", obj); @@ -2308,18 +2353,19 @@ json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) { CHECKMEM(obj); json_object_object_add(ctxobj, "lowater", obj); - MCTXUNLOCK(ctx, &ctx->lock); + MCTXUNLOCK(ctx); json_object_array_add(array, ctxobj); return (ISC_R_SUCCESS); } isc_result_t -isc_mem_renderjson(json_object *memobj) { +isc_mem_renderjson(void *memobj0) { isc_result_t result = ISC_R_SUCCESS; isc__mem_t *ctx; summarystat_t summary; uint64_t lost; json_object *ctxarray, *obj; + json_object *memobj = (json_object *)memobj0; memset(&summary, 0, sizeof(summary)); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2329,8 +2375,7 @@ isc_mem_renderjson(json_object *memobj) { LOCK(&contextslock); lost = totallost; - for (ctx = ISC_LIST_HEAD(contexts); - ctx != NULL; + for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { result = json_renderctx(ctx, &summary, ctxarray); if (result != ISC_R_SUCCESS) { @@ -2367,18 +2412,17 @@ isc_mem_renderjson(json_object *memobj) { json_object_object_add(memobj, "contexts", ctxarray); return (ISC_R_SUCCESS); - error: - if (ctxarray != NULL) +error: + if (ctxarray != NULL) { json_object_put(ctxarray); + } return (result); } -#endif /* HAVE_JSON */ +#endif /* HAVE_JSON_C */ -isc_result_t -isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) { - return (isc_mem_createx(init_max_size, target_size, - default_memalloc, default_memfree, - NULL, mctxp, isc_mem_defaultflags)); +void +isc_mem_create(isc_mem_t **mctxp) { + mem_create(mctxp, isc_mem_defaultflags); } void * @@ -2386,7 +2430,6 @@ isc__mem_get(isc_mem_t *mctx, size_t size FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); return (mctx->methods->memget(mctx, size FLARG_PASS)); - } void @@ -2434,14 +2477,14 @@ isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) { void isc__mem_printactive(isc_mem_t *ctx0, FILE *file) { #if ISC_MEM_TRACKLINES - isc__mem_t *ctx = (isc__mem_t *)ctx0; - - REQUIRE(VALID_CONTEXT(ctx)); + REQUIRE(VALID_CONTEXT(ctx0)); REQUIRE(file != NULL); + isc__mem_t *ctx = (isc__mem_t *)ctx0; + print_active(ctx, file); -#else +#else /* if ISC_MEM_TRACKLINES */ UNUSED(ctx0); UNUSED(file); -#endif +#endif /* if ISC_MEM_TRACKLINES */ } diff --git a/lib/isc/mem_p.h b/lib/isc/mem_p.h index fe27521b..f1889c66 100644 --- a/lib/isc/mem_p.h +++ b/lib/isc/mem_p.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/mutexblock.c b/lib/isc/mutexblock.c index 95d262a8..e4693443 100644 --- a/lib/isc/mutexblock.c +++ b/lib/isc/mutexblock.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <isc/mutexblock.h> #include <isc/util.h> diff --git a/lib/isc/netaddr.c b/lib/isc/netaddr.c index 7d94697a..cbe9c6b1 100644 --- a/lib/isc/netaddr.c +++ b/lib/isc/netaddr.c @@ -3,20 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - +#include <inttypes.h> #include <stdbool.h> #include <stdio.h> -#include <inttypes.h> #include <isc/buffer.h> #include <isc/net.h> @@ -30,29 +27,35 @@ bool isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) { REQUIRE(a != NULL && b != NULL); - if (a->family != b->family) + if (a->family != b->family) { return (false); + } - if (a->zone != b->zone) + if (a->zone != b->zone) { return (false); + } switch (a->family) { case AF_INET: - if (a->type.in.s_addr != b->type.in.s_addr) + if (a->type.in.s_addr != b->type.in.s_addr) { return (false); + } break; case AF_INET6: - if (memcmp(&a->type.in6, &b->type.in6, - sizeof(a->type.in6)) != 0 || + if (memcmp(&a->type.in6, &b->type.in6, sizeof(a->type.in6)) != + 0 || a->zone != b->zone) + { return (false); + } break; #ifdef ISC_PLATFORM_HAVESYSUNH case AF_UNIX: - if (strcmp(a->type.un, b->type.un) != 0) + if (strcmp(a->type.un, b->type.un) != 0) { return (false); + } break; -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ default: return (false); } @@ -61,30 +64,31 @@ isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) { bool isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b, - unsigned int prefixlen) -{ + unsigned int prefixlen) { const unsigned char *pa = NULL, *pb = NULL; unsigned int ipabytes = 0; /* Length of whole IP address in bytes */ - unsigned int nbytes; /* Number of significant whole bytes */ - unsigned int nbits; /* Number of significant leftover bits */ + unsigned int nbytes; /* Number of significant whole bytes */ + unsigned int nbits; /* Number of significant leftover bits */ REQUIRE(a != NULL && b != NULL); - if (a->family != b->family) + if (a->family != b->family) { return (false); + } - if (a->zone != b->zone && b->zone != 0) + if (a->zone != b->zone && b->zone != 0) { return (false); + } switch (a->family) { case AF_INET: - pa = (const unsigned char *) &a->type.in; - pb = (const unsigned char *) &b->type.in; + pa = (const unsigned char *)&a->type.in; + pb = (const unsigned char *)&b->type.in; ipabytes = 4; break; case AF_INET6: - pa = (const unsigned char *) &a->type.in6; - pb = (const unsigned char *) &b->type.in6; + pa = (const unsigned char *)&a->type.in6; + pb = (const unsigned char *)&b->type.in6; ipabytes = 16; break; default: @@ -94,15 +98,17 @@ isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b, /* * Don't crash if we get a pattern like 10.0.0.1/9999999. */ - if (prefixlen > ipabytes * 8) + if (prefixlen > ipabytes * 8) { prefixlen = ipabytes * 8; + } nbytes = prefixlen / 8; nbits = prefixlen % 8; if (nbytes > 0) { - if (memcmp(pa, pb, nbytes) != 0) + if (memcmp(pa, pb, nbytes) != 0) { return (false); + } } if (nbits > 0) { unsigned int bytea, byteb, mask; @@ -110,9 +116,10 @@ isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b, INSIST(nbits < 8); bytea = pa[nbytes]; byteb = pb[nbytes]; - mask = (0xFF << (8-nbits)) & 0xFF; - if ((bytea & mask) != (byteb & mask)) + mask = (0xFF << (8 - nbits)) & 0xFF; + if ((bytea & mask) != (byteb & mask)) { return (false); + } } return (true); } @@ -138,19 +145,21 @@ isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) { #ifdef ISC_PLATFORM_HAVESYSUNH case AF_UNIX: alen = strlen(netaddr->type.un); - if (alen > isc_buffer_availablelength(target)) + if (alen > isc_buffer_availablelength(target)) { return (ISC_R_NOSPACE); + } isc_buffer_putmem(target, (const unsigned char *)(netaddr->type.un), alen); return (ISC_R_SUCCESS); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ default: return (ISC_R_FAILURE); } r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf)); - if (r == NULL) + if (r == NULL) { return (ISC_R_FAILURE); + } alen = strlen(abuf); INSIST(alen < sizeof(abuf)); @@ -158,13 +167,15 @@ isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) { zlen = 0; if (netaddr->family == AF_INET6 && netaddr->zone != 0) { zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone); - if (zlen < 0) + if (zlen < 0) { return (ISC_R_FAILURE); + } INSIST((unsigned int)zlen < sizeof(zbuf)); } - if (alen + zlen > isc_buffer_availablelength(target)) + if (alen + zlen > isc_buffer_availablelength(target)) { return (ISC_R_NOSPACE); + } isc_buffer_putmem(target, (unsigned char *)abuf, alen); isc_buffer_putmem(target, (unsigned char *)zbuf, (unsigned int)zlen); @@ -180,28 +191,28 @@ isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) { isc_buffer_init(&buf, array, size); result = isc_netaddr_totext(na, &buf); - if (size == 0) + if (size == 0) { return; + } /* * Null terminate. */ if (result == ISC_R_SUCCESS) { - if (isc_buffer_availablelength(&buf) >= 1) + if (isc_buffer_availablelength(&buf) >= 1) { isc_buffer_putuint8(&buf, 0); - else + } else { result = ISC_R_NOSPACE; + } } if (result != ISC_R_SUCCESS) { - snprintf(array, size, - "<unknown address, family %u>", + snprintf(array, size, "<unknown address, family %u>", na->family); array[size - 1] = '\0'; } } - isc_result_t isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) { static const unsigned char zeros[16]; @@ -210,16 +221,18 @@ isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) { switch (na->family) { case AF_INET: - p = (const unsigned char *) &na->type.in; + p = (const unsigned char *)&na->type.in; ipbytes = 4; - if (prefixlen > 32) + if (prefixlen > 32) { return (ISC_R_RANGE); + } break; case AF_INET6: - p = (const unsigned char *) &na->type.in6; + p = (const unsigned char *)&na->type.in6; ipbytes = 16; - if (prefixlen > 128) + if (prefixlen > 128) { return (ISC_R_RANGE); + } break; default: return (ISC_R_NOTIMPLEMENTED); @@ -228,12 +241,15 @@ isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) { nbits = prefixlen % 8; if (nbits != 0) { INSIST(nbytes < ipbytes); - if ((p[nbytes] & (0xff>>nbits)) != 0U) + if ((p[nbytes] & (0xff >> nbits)) != 0U) { return (ISC_R_FAILURE); + } nbytes++; } - if (nbytes < ipbytes && memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0) + if (nbytes < ipbytes && + memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0) { return (ISC_R_FAILURE); + } return (ISC_R_SUCCESS); } @@ -244,33 +260,37 @@ isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) { switch (s->family) { case AF_INET: - p = (const unsigned char *) &s->type.in; + p = (const unsigned char *)&s->type.in; ipbytes = 4; break; case AF_INET6: - p = (const unsigned char *) &s->type.in6; + p = (const unsigned char *)&s->type.in6; ipbytes = 16; break; default: return (ISC_R_NOTIMPLEMENTED); } for (i = 0; i < ipbytes; i++) { - if (p[i] != 0xFF) + if (p[i] != 0xFF) { break; + } } nbytes = i; if (i < ipbytes) { unsigned int c = p[nbytes]; while ((c & 0x80) != 0 && nbits < 8) { - c <<= 1; nbits++; + c <<= 1; + nbits++; } - if ((c & 0xFF) != 0) + if ((c & 0xFF) != 0) { return (ISC_R_MASKNONCONTIG); + } i++; } for (; i < ipbytes; i++) { - if (p[i] != 0) + if (p[i] != 0) { return (ISC_R_MASKNONCONTIG); + } } *lenp = nbytes * 8 + nbits; return (ISC_R_SUCCESS); @@ -293,22 +313,22 @@ isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) { isc_result_t isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) { #ifdef ISC_PLATFORM_HAVESYSUNH - if (strlen(path) > sizeof(netaddr->type.un) - 1) + if (strlen(path) > sizeof(netaddr->type.un) - 1) { return (ISC_R_NOSPACE); + } memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_UNIX; strlcpy(netaddr->type.un, path, sizeof(netaddr->type.un)); netaddr->zone = 0; return (ISC_R_SUCCESS); -#else +#else /* ifdef ISC_PLATFORM_HAVESYSUNH */ UNUSED(netaddr); UNUSED(path); return (ISC_R_NOTIMPLEMENTED); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ } - void isc_netaddr_setzone(isc_netaddr_t *netaddr, uint32_t zone) { /* we currently only support AF_INET6. */ @@ -340,7 +360,7 @@ isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) { memmove(t->type.un, s->type.sunix.sun_path, sizeof(t->type.un)); t->zone = 0; break; -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ default: INSIST(0); ISC_UNREACHABLE(); @@ -375,7 +395,7 @@ isc_netaddr_ismulticast(const isc_netaddr_t *na) { case AF_INET6: return (IN6_IS_ADDR_MULTICAST(&na->type.in6)); default: - return (false); /* XXXMLG ? */ + return (false); /* XXXMLG ? */ } } @@ -385,7 +405,7 @@ isc_netaddr_isexperimental(const isc_netaddr_t *na) { case AF_INET: return (ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr)); default: - return (false); /* XXXMLG ? */ + return (false); /* XXXMLG ? */ } } @@ -414,8 +434,7 @@ isc_netaddr_issitelocal(const isc_netaddr_t *na) { } #define ISC_IPADDR_ISNETZERO(i) \ - (((uint32_t)(i) & ISC__IPADDR(0xff000000)) \ - == ISC__IPADDR(0x00000000)) + (((uint32_t)(i)&ISC__IPADDR(0xff000000)) == ISC__IPADDR(0x00000000)) bool isc_netaddr_isnetzero(const isc_netaddr_t *na) { @@ -433,7 +452,7 @@ void isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) { isc_netaddr_t *src; - DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */ + DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */ REQUIRE(s->family == AF_INET6); REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6)); @@ -449,7 +468,7 @@ isc_netaddr_isloopback(const isc_netaddr_t *na) { switch (na->family) { case AF_INET: return (((ntohl(na->type.in.s_addr) & 0xff000000U) == - 0x7f000000U)); + 0x7f000000U)); case AF_INET6: return (IN6_IS_ADDR_LOOPBACK(&na->type.in6)); default: diff --git a/lib/isc/netmgr/Makefile.in b/lib/isc/netmgr/Makefile.in new file mode 100644 index 00000000..d017d10e --- /dev/null +++ b/lib/isc/netmgr/Makefile.in @@ -0,0 +1,36 @@ +# 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 http://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +CINCLUDES = -I${srcdir}/include \ + -I${srcdir}/../unix/include \ + -I${srcdir}/../pthreads/include \ + -I../include \ + -I${srcdir}/../include \ + -I${srcdir}/.. \ + ${OPENSSL_CFLAGS} \ + ${JSON_C_CFLAGS} \ + ${LIBUV_CFLAGS} \ + ${LIBXML2_CFLAGS} + +CDEFINES = +CWARNINGS = + +# Alphabetically +OBJS = netmgr.@O@ tcp.@O@ udp.@O@ tcpdns.@O@ uverr2result.@O@ uv-compat.@O@ + +# Alphabetically +SRCS = netmgr.c tcp.c udp.c tcpdns.c uverr2result.c uv-compat.c + +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h new file mode 100644 index 00000000..4d6ef881 --- /dev/null +++ b/lib/isc/netmgr/netmgr-int.h @@ -0,0 +1,867 @@ +/* + * 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 + +#include <unistd.h> +#include <uv.h> + +#include <isc/astack.h> +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/condition.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/queue.h> +#include <isc/quota.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/sockaddr.h> +#include <isc/stats.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include "uv-compat.h" + +#define ISC_NETMGR_TID_UNKNOWN -1 + +#if !defined(WIN32) +/* + * New versions of libuv support recvmmsg on unices. + * Since recvbuf is only allocated per worker allocating a bigger one is not + * that wasteful. + * 20 here is UV__MMSG_MAXWIDTH taken from the current libuv source, nothing + * will break if the original value changes. + */ +#define ISC_NETMGR_RECVBUF_SIZE (20 * 65536) +#else +#define ISC_NETMGR_RECVBUF_SIZE (65536) +#endif + +/* + * Define NETMGR_TRACE to activate tracing of handles and sockets. + * This will impair performance but enables us to quickly determine, + * if netmgr resources haven't been cleaned up on shutdown, which ones + * are still in use. + */ +#ifdef NETMGR_TRACE +#define TRACE_SIZE 8 + +void +isc__nm_dump_active(isc_nm_t *nm); + +#endif + +/* + * Single network event loop worker. + */ +typedef struct isc__networker { + isc_nm_t *mgr; + int id; /* thread id */ + uv_loop_t loop; /* libuv loop structure */ + uv_async_t async; /* async channel to send + * data to this networker */ + isc_mutex_t lock; + isc_condition_t cond; + bool paused; + bool finished; + isc_thread_t thread; + isc_queue_t *ievents; /* incoming async events */ + isc_queue_t *ievents_prio; /* priority async events + * used for listening etc. + * can be processed while + * worker is paused */ + isc_refcount_t references; + atomic_int_fast64_t pktcount; + char *recvbuf; + bool recvbuf_inuse; +} isc__networker_t; + +/* + * A general handle for a connection bound to a networker. For UDP + * connections we have peer address here, so both TCP and UDP can be + * handled with a simple send-like function + */ +#define NMHANDLE_MAGIC ISC_MAGIC('N', 'M', 'H', 'D') +#define VALID_NMHANDLE(t) \ + (ISC_MAGIC_VALID(t, NMHANDLE_MAGIC) && \ + atomic_load(&(t)->references) > 0) + +typedef void (*isc__nm_closecb)(isc_nmhandle_t *); + +struct isc_nmhandle { + int magic; + isc_refcount_t references; + + /* + * The socket is not 'attached' in the traditional + * reference-counting sense. Instead, we keep all handles in an + * array in the socket object. This way, we don't have circular + * dependencies and we can close all handles when we're destroying + * the socket. + */ + isc_nmsocket_t *sock; + size_t ah_pos; /* Position in the socket's 'active handles' array */ + + isc_sockaddr_t peer; + isc_sockaddr_t local; + isc_nm_opaquecb_t doreset; /* reset extra callback, external */ + isc_nm_opaquecb_t dofree; /* free extra callback, external */ +#ifdef NETMGR_TRACE + void *backtrace[TRACE_SIZE]; + int backtrace_size; + LINK(isc_nmhandle_t) active_link; +#endif + void *opaque; + char extra[]; +}; + +/* + * An interface - an address we can listen on. + */ +struct isc_nmiface { + isc_sockaddr_t addr; +}; + +typedef enum isc__netievent_type { + netievent_udpsend, + netievent_udpstop, + + netievent_tcpconnect, + netievent_tcpsend, + netievent_tcpstartread, + netievent_tcppauseread, + netievent_tcpchildaccept, + netievent_tcpaccept, + netievent_tcpstop, + netievent_tcpclose, + + netievent_tcpdnssend, + netievent_tcpdnsclose, + netievent_tcpdnsstop, + + netievent_closecb, + netievent_shutdown, + netievent_stop, + netievent_pause, + + netievent_prio = 0xff, /* event type values higher than this + * will be treated as high-priority + * events, which can be processed + * while the netmgr is paused. + */ + netievent_udplisten, + netievent_tcplisten, + netievent_resume, +} isc__netievent_type; + +typedef union { + isc_nm_recv_cb_t recv; + isc_nm_cb_t send; + isc_nm_cb_t connect; +} isc__nm_cb_t; + +/* + * Wrapper around uv_req_t with 'our' fields in it. req->data should + * always point to its parent. Note that we always allocate more than + * sizeof(struct) because we make room for different req types; + */ +#define UVREQ_MAGIC ISC_MAGIC('N', 'M', 'U', 'R') +#define VALID_UVREQ(t) ISC_MAGIC_VALID(t, UVREQ_MAGIC) + +typedef struct isc__nm_uvreq { + int magic; + isc_nmsocket_t *sock; + isc_nmhandle_t *handle; + uv_buf_t uvbuf; /* translated isc_region_t, to be + * sent or received */ + isc_sockaddr_t local; /* local address */ + isc_sockaddr_t peer; /* peer address */ + isc__nm_cb_t cb; /* callback */ + void *cbarg; /* callback argument */ + uv_pipe_t ipc; /* used for sending socket + * uv_handles to other threads */ + union { + uv_req_t req; + uv_getaddrinfo_t getaddrinfo; + uv_getnameinfo_t getnameinfo; + uv_shutdown_t shutdown; + uv_write_t write; + uv_connect_t connect; + uv_udp_send_t udp_send; + uv_fs_t fs; + uv_work_t work; + } uv_req; +} isc__nm_uvreq_t; + +typedef struct isc__netievent__socket { + isc__netievent_type type; + isc_nmsocket_t *sock; +} isc__netievent__socket_t; + +typedef isc__netievent__socket_t isc__netievent_udplisten_t; +typedef isc__netievent__socket_t isc__netievent_udpstop_t; +typedef isc__netievent__socket_t isc__netievent_tcpstop_t; +typedef isc__netievent__socket_t isc__netievent_tcpclose_t; +typedef isc__netievent__socket_t isc__netievent_startread_t; +typedef isc__netievent__socket_t isc__netievent_pauseread_t; +typedef isc__netievent__socket_t isc__netievent_closecb_t; +typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t; +typedef isc__netievent__socket_t isc__netievent_tcpdnsstop_t; + +typedef struct isc__netievent__socket_req { + isc__netievent_type type; + isc_nmsocket_t *sock; + isc__nm_uvreq_t *req; +} isc__netievent__socket_req_t; + +typedef isc__netievent__socket_req_t isc__netievent_tcpconnect_t; +typedef isc__netievent__socket_req_t isc__netievent_tcplisten_t; +typedef isc__netievent__socket_req_t isc__netievent_tcpsend_t; +typedef isc__netievent__socket_req_t isc__netievent_tcpdnssend_t; + +typedef struct isc__netievent__socket_streaminfo_quota { + isc__netievent_type type; + isc_nmsocket_t *sock; + isc_uv_stream_info_t streaminfo; + isc_quota_t *quota; +} isc__netievent__socket_streaminfo_quota_t; + +typedef isc__netievent__socket_streaminfo_quota_t + isc__netievent_tcpchildaccept_t; + +typedef struct isc__netievent__socket_handle { + isc__netievent_type type; + isc_nmsocket_t *sock; + isc_nmhandle_t *handle; +} isc__netievent__socket_handle_t; + +typedef struct isc__netievent__socket_quota { + isc__netievent_type type; + isc_nmsocket_t *sock; + isc_quota_t *quota; +} isc__netievent__socket_quota_t; + +typedef isc__netievent__socket_quota_t isc__netievent_tcpaccept_t; + +typedef struct isc__netievent_udpsend { + isc__netievent_type type; + isc_nmsocket_t *sock; + isc_sockaddr_t peer; + isc__nm_uvreq_t *req; +} isc__netievent_udpsend_t; + +typedef struct isc__netievent { + isc__netievent_type type; +} isc__netievent_t; + +typedef isc__netievent_t isc__netievent_shutdown_t; +typedef isc__netievent_t isc__netievent_stop_t; + +typedef union { + isc__netievent_t ni; + isc__netievent__socket_t nis; + isc__netievent__socket_req_t nisr; + isc__netievent_udpsend_t nius; + isc__netievent__socket_quota_t nisq; + isc__netievent__socket_streaminfo_quota_t nissq; +} isc__netievent_storage_t; + +/* + * Network manager + */ +#define NM_MAGIC ISC_MAGIC('N', 'E', 'T', 'M') +#define VALID_NM(t) ISC_MAGIC_VALID(t, NM_MAGIC) + +struct isc_nm { + int magic; + isc_refcount_t references; + isc_mem_t *mctx; + uint32_t nworkers; + isc_mutex_t lock; + isc_condition_t wkstatecond; + isc__networker_t *workers; + + isc_stats_t *stats; + + isc_mempool_t *reqpool; + isc_mutex_t reqlock; + + isc_mempool_t *evpool; + isc_mutex_t evlock; + + uint_fast32_t workers_running; + uint_fast32_t workers_paused; + atomic_uint_fast32_t maxudp; + + /* + * Active connections are being closed and new connections are + * no longer allowed. + */ + atomic_bool closing; + + /* + * A worker is actively waiting for other workers, for example to + * stop listening; that means no other thread can do the same thing + * or pause, or we'll deadlock. We have to either re-enqueue our + * event or wait for the other one to finish if we want to pause. + */ + atomic_bool interlocked; + + /* + * Timeout values for TCP connections, corresponding to + * tcp-intiial-timeout, tcp-idle-timeout, tcp-keepalive-timeout, + * and tcp-advertised-timeout. Note that these are stored in + * milliseconds so they can be used directly with the libuv timer, + * but they are configured in tenths of seconds. + */ + uint32_t init; + uint32_t idle; + uint32_t keepalive; + uint32_t advertised; + +#ifdef NETMGR_TRACE + ISC_LIST(isc_nmsocket_t) active_sockets; +#endif +}; + +typedef enum isc_nmsocket_type { + isc_nm_udpsocket, + isc_nm_udplistener, /* Aggregate of nm_udpsocks */ + isc_nm_tcpsocket, + isc_nm_tcplistener, + isc_nm_tcpdnslistener, + isc_nm_tcpdnssocket, +} isc_nmsocket_type; + +/*% + * A universal structure for either a single socket or a group of + * dup'd/SO_REUSE_PORT-using sockets listening on the same interface. + */ +#define NMSOCK_MAGIC ISC_MAGIC('N', 'M', 'S', 'K') +#define VALID_NMSOCK(t) ISC_MAGIC_VALID(t, NMSOCK_MAGIC) + +/*% + * Index into socket stat counter arrays. + */ +enum { STATID_OPEN = 0, + STATID_OPENFAIL = 1, + STATID_CLOSE = 2, + STATID_BINDFAIL = 3, + STATID_CONNECTFAIL = 4, + STATID_CONNECT = 5, + STATID_ACCEPTFAIL = 6, + STATID_ACCEPT = 7, + STATID_SENDFAIL = 8, + STATID_RECVFAIL = 9, + STATID_ACTIVE = 10 }; + +struct isc_nmsocket { + /*% Unlocked, RO */ + int magic; + int tid; + isc_nmsocket_type type; + isc_nm_t *mgr; + /*% Parent socket for multithreaded listeners */ + isc_nmsocket_t *parent; + /*% Listener socket this connection was accepted on */ + isc_nmsocket_t *listener; + /*% Self, for self-contained unreferenced sockets (tcpdns) */ + isc_nmsocket_t *self; + + /*% + * quota is the TCP client, attached when a TCP connection + * is established. pquota is a non-attached pointer to the + * TCP client quota, stored in listening sockets but only + * attached in connected sockets. + */ + isc_quota_t *quota; + isc_quota_t *pquota; + isc_quota_cb_t quotacb; + + /*% + * Socket statistics + */ + const isc_statscounter_t *statsindex; + + /*% + * TCP read timeout timer. + */ + uv_timer_t timer; + bool timer_initialized; + uint64_t read_timeout; + + /*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */ + isc_nmsocket_t *outer; + + /*% server socket for connections */ + isc_nmsocket_t *server; + + /*% Child sockets for multi-socket setups */ + isc_nmsocket_t *children; + int nchildren; + isc_nmiface_t *iface; + isc_nmhandle_t *statichandle; + isc_nmhandle_t *outerhandle; + + /*% Extra data allocated at the end of each isc_nmhandle_t */ + size_t extrahandlesize; + + /*% TCP backlog */ + int backlog; + + /*% libuv data */ + uv_os_sock_t fd; + union uv_any_handle uv_handle; + + /*% Peer address */ + isc_sockaddr_t peer; + + /* Atomic */ + /*% Number of running (e.g. listening) child sockets */ + atomic_int_fast32_t rchildren; + + /*% + * Socket is active if it's listening, working, etc. If it's + * closing, then it doesn't make a sense, for example, to + * push handles or reqs for reuse. + */ + atomic_bool active; + atomic_bool destroying; + + /*% + * Socket is closed if it's not active and all the possible + * callbacks were fired, there are no active handles, etc. + * If active==false but closed==false, that means the socket + * is closing. + */ + atomic_bool closed; + atomic_bool listening; + atomic_bool listen_error; + atomic_bool connected; + atomic_bool connect_error; + isc_refcount_t references; + + /*% + * Established an outgoing connection, as client not server. + */ + atomic_bool client; + + /*% + * TCPDNS socket has been set not to pipeline. + */ + atomic_bool sequential; + + /*% + * TCPDNS socket has exceeded the maximum number of + * simultaneous requests per connection, so will be temporarily + * restricted from pipelining. + */ + atomic_bool overlimit; + + /*% + * TCPDNS socket in sequential mode is currently processing a packet, + * we need to wait until it finishes. + */ + atomic_bool processing; + + /*% + * A TCP socket has had isc_nm_pauseread() called. + */ + atomic_bool readpaused; + + /*% + * A TCP or TCPDNS socket has been set to use the keepalive + * timeout instead of the default idle timeout. + */ + atomic_bool keepalive; + + /*% + * 'spare' handles for that can be reused to avoid allocations, + * for UDP. + */ + isc_astack_t *inactivehandles; + isc_astack_t *inactivereqs; + + /*% + * Used to wait for TCP listening events to complete, and + * for the number of running children to reach zero during + * shutdown. + */ + isc_mutex_t lock; + isc_condition_t cond; + + /*% + * Used to pass a result back from TCP listening events. + */ + isc_result_t result; + + /*% + * List of active handles. + * ah - current position in 'ah_frees'; this represents the + * current number of active handles; + * ah_size - size of the 'ah_frees' and 'ah_handles' arrays + * ah_handles - array pointers to active handles + * + * Adding a handle + * - if ah == ah_size, reallocate + * - x = ah_frees[ah] + * - ah_frees[ah++] = 0; + * - ah_handles[x] = handle + * - x must be stored with the handle! + * Removing a handle: + * - ah_frees[--ah] = x + * - ah_handles[x] = NULL; + * + * XXX: for now this is locked with socket->lock, but we + * might want to change it to something lockless in the + * future. + */ + atomic_int_fast32_t ah; + size_t ah_size; + size_t *ah_frees; + isc_nmhandle_t **ah_handles; + + /*% Buffer for TCPDNS processing */ + size_t buf_size; + size_t buf_len; + unsigned char *buf; + + /*% + * This function will be called with handle->sock + * as the argument whenever a handle's references drop + * to zero, after its reset callback has been called. + */ + isc_nm_opaquecb_t closehandle_cb; + + isc_nm_recv_cb_t recv_cb; + void *recv_cbarg; + + isc_nm_accept_cb_t accept_cb; + void *accept_cbarg; +#ifdef NETMGR_TRACE + void *backtrace[TRACE_SIZE]; + int backtrace_size; + LINK(isc_nmsocket_t) active_link; + ISC_LIST(isc_nmhandle_t) active_handles; +#endif +}; + +bool +isc__nm_in_netthread(void); +/*% + * Returns 'true' if we're in the network thread. + */ + +void * +isc__nm_get_ievent(isc_nm_t *mgr, isc__netievent_type type); +/*%< + * Allocate an ievent and set the type. + */ +void +isc__nm_put_ievent(isc_nm_t *mgr, void *ievent); + +void +isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event); +/*%< + * Enqueue an ievent onto a specific worker queue. (This the only safe + * way to use an isc__networker_t from another thread.) + */ + +void +isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf); +/*%< + * Free a buffer allocated for a receive operation. + * + * Note that as currently implemented, this doesn't actually + * free anything, marks the isc__networker's UDP receive buffer + * as "not in use". + */ + +isc_nmhandle_t * +isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer, + isc_sockaddr_t *local); +/*%< + * Get a handle for the socket 'sock', allocating a new one + * if there isn't one available in 'sock->inactivehandles'. + * + * If 'peer' is not NULL, set the handle's peer address to 'peer', + * otherwise set it to 'sock->peer'. + * + * If 'local' is not NULL, set the handle's local address to 'local', + * otherwise set it to 'sock->iface->addr'. + * + * 'sock' will be attached to 'handle->sock'. The caller may need + * to detach the socket afterward. + */ + +isc__nm_uvreq_t * +isc__nm_uvreq_get(isc_nm_t *mgr, isc_nmsocket_t *sock); +/*%< + * Get a UV request structure for the socket 'sock', allocating a + * new one if there isn't one available in 'sock->inactivereqs'. + */ + +void +isc__nm_uvreq_put(isc__nm_uvreq_t **req, isc_nmsocket_t *sock); +/*%< + * Completes the use of a UV request structure, setting '*req' to NULL. + * + * The UV request is pushed onto the 'sock->inactivereqs' stack or, + * if that doesn't work, freed. + */ + +void +isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type, + isc_nmiface_t *iface); +/*%< + * Initialize socket 'sock', attach it to 'mgr', and set it to type 'type' + * and its interface to 'iface'. + */ + +void +isc__nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target); +/*%< + * Attach to a socket, increasing refcount + */ + +void +isc__nmsocket_detach(isc_nmsocket_t **socketp); +/*%< + * Detach from socket, decreasing refcount and possibly destroying the + * socket if it's no longer referenced. + */ + +void +isc__nmsocket_prep_destroy(isc_nmsocket_t *sock); +/*%< + * Market 'sock' as inactive, close it if necessary, and destroy it + * if there are no remaining references or active handles. + */ + +bool +isc__nmsocket_active(isc_nmsocket_t *sock); +/*%< + * Determine whether 'sock' is active by checking 'sock->active' + * or, for child sockets, 'sock->parent->active'. + */ + +void +isc__nmsocket_clearcb(isc_nmsocket_t *sock); +/*%< + * Clear the recv and accept callbacks in 'sock'. + */ + +void +isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ev0); +/*%< + * Issue a 'handle closed' callback on the socket. + */ + +void +isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0); +/*%< + * Walk through all uv handles, get the underlying sockets and issue + * close on them. + */ + +isc_result_t +isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg); +/*%< + * Back-end implementation of isc_nm_send() for UDP handles. + */ + +void +isc__nm_udp_stoplistening(isc_nmsocket_t *sock); + +void +isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0); + +void +isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0); +/*%< + * Callback handlers for asynchronous UDP events (listen, stoplisten, send). + */ + +isc_result_t +isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg); +/*%< + * Back-end implementation of isc_nm_send() for TCP handles. + */ + +isc_result_t +isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg); +/* + * Back-end implementation of isc_nm_read() for TCP handles. + */ + +void +isc__nm_tcp_close(isc_nmsocket_t *sock); +/*%< + * Close a TCP socket. + */ +isc_result_t +isc__nm_tcp_pauseread(isc_nmsocket_t *sock); +/*%< + * Pause reading on this socket, while still remembering the callback. + */ + +isc_result_t +isc__nm_tcp_resumeread(isc_nmsocket_t *sock); +/*%< + * Resume reading from socket. + * + */ + +void +isc__nm_tcp_shutdown(isc_nmsocket_t *sock); +/*%< + * Called during the shutdown process to close and clean up connected + * sockets. + */ + +void +isc__nm_tcp_cancelread(isc_nmhandle_t *handle); +/*%< + * Stop reading on a connected TCP handle. + */ + +void +isc__nm_tcp_stoplistening(isc_nmsocket_t *sock); + +void +isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpaccept(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpstop(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_pauseread(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcp_pauseread(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ev0); +/*%< + * Callback handlers for asynchronous TCP events (connect, listen, + * stoplisten, send, read, pause, close). + */ + +isc_result_t +isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region, + isc_nm_cb_t cb, void *cbarg); +/*%< + * Back-end implementation of isc_nm_send() for TCPDNS handles. + */ + +void +isc__nm_tcpdns_close(isc_nmsocket_t *sock); +/*%< + * Close a TCPDNS socket. + */ + +void +isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock); + +void +isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0); + +#define isc__nm_uverr2result(x) \ + isc___nm_uverr2result(x, true, __FILE__, __LINE__) +isc_result_t +isc___nm_uverr2result(int uverr, bool dolog, const char *file, + unsigned int line); +/*%< + * Convert a libuv error value into an isc_result_t. The + * list of supported error values is not complete; new users + * of this function should add any expected errors that are + * not already there. + */ + +bool +isc__nm_acquire_interlocked(isc_nm_t *mgr); +/*%< + * Try to acquire interlocked state; return true if successful. + */ + +void +isc__nm_drop_interlocked(isc_nm_t *mgr); +/*%< + * Drop interlocked state; signal waiters. + */ + +void +isc__nm_acquire_interlocked_force(isc_nm_t *mgr); +/*%< + * Actively wait for interlocked state. + */ + +void +isc__nm_incstats(isc_nm_t *mgr, isc_statscounter_t counterid); +/*%< + * Increment socket-related statistics counters. + */ + +void +isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid); +/*%< + * Decrement socket-related statistics counters. + */ + +isc_result_t +isc__nm_socket_freebind(uv_os_sock_t fd, sa_family_t sa_family); +/*%< + * Set the IP_FREEBIND (or equivalent) socket option on the uv_handle + */ + +isc_result_t +isc__nm_socket_reuse(uv_os_sock_t fd); +/*%< + * Set the SO_REUSEADDR or SO_REUSEPORT (or equivalent) socket option on the fd + */ + +isc_result_t +isc__nm_socket_reuse_lb(uv_os_sock_t fd); +/*%< + * Set the SO_REUSEPORT_LB (or equivalent) socket option on the fd + */ + +isc_result_t +isc__nm_socket_incoming_cpu(uv_os_sock_t fd); +/*%< + * Set the SO_INCOMING_CPU socket option on the fd if available + */ + +isc_result_t +isc__nm_socket_dontfrag(uv_os_sock_t fd, sa_family_t sa_family); +/*%< + * Set the SO_IP_DONTFRAG (or equivalent) socket option of the fd if available + */ diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c new file mode 100644 index 00000000..13c04099 --- /dev/null +++ b/lib/isc/netmgr/netmgr.c @@ -0,0 +1,1830 @@ +/* + * 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. + */ + +#include <inttypes.h> +#include <unistd.h> +#include <uv.h> + +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/condition.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/print.h> +#include <isc/quota.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/sockaddr.h> +#include <isc/stats.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include "netmgr-int.h" +#include "uv-compat.h" + +#ifdef NETMGR_TRACE +#include <execinfo.h> +#endif + +/*% + * How many isc_nmhandles and isc_nm_uvreqs will we be + * caching for reuse in a socket. + */ +#define ISC_NM_HANDLES_STACK_SIZE 600 +#define ISC_NM_REQS_STACK_SIZE 600 + +/*% + * Shortcut index arrays to get access to statistics counters. + */ + +static const isc_statscounter_t udp4statsindex[] = { + isc_sockstatscounter_udp4open, + isc_sockstatscounter_udp4openfail, + isc_sockstatscounter_udp4close, + isc_sockstatscounter_udp4bindfail, + isc_sockstatscounter_udp4connectfail, + isc_sockstatscounter_udp4connect, + -1, + -1, + isc_sockstatscounter_udp4sendfail, + isc_sockstatscounter_udp4recvfail, + isc_sockstatscounter_udp4active +}; + +static const isc_statscounter_t udp6statsindex[] = { + isc_sockstatscounter_udp6open, + isc_sockstatscounter_udp6openfail, + isc_sockstatscounter_udp6close, + isc_sockstatscounter_udp6bindfail, + isc_sockstatscounter_udp6connectfail, + isc_sockstatscounter_udp6connect, + -1, + -1, + isc_sockstatscounter_udp6sendfail, + isc_sockstatscounter_udp6recvfail, + isc_sockstatscounter_udp6active +}; + +static const isc_statscounter_t tcp4statsindex[] = { + isc_sockstatscounter_tcp4open, isc_sockstatscounter_tcp4openfail, + isc_sockstatscounter_tcp4close, isc_sockstatscounter_tcp4bindfail, + isc_sockstatscounter_tcp4connectfail, isc_sockstatscounter_tcp4connect, + isc_sockstatscounter_tcp4acceptfail, isc_sockstatscounter_tcp4accept, + isc_sockstatscounter_tcp4sendfail, isc_sockstatscounter_tcp4recvfail, + isc_sockstatscounter_tcp4active +}; + +static const isc_statscounter_t tcp6statsindex[] = { + isc_sockstatscounter_tcp6open, isc_sockstatscounter_tcp6openfail, + isc_sockstatscounter_tcp6close, isc_sockstatscounter_tcp6bindfail, + isc_sockstatscounter_tcp6connectfail, isc_sockstatscounter_tcp6connect, + isc_sockstatscounter_tcp6acceptfail, isc_sockstatscounter_tcp6accept, + isc_sockstatscounter_tcp6sendfail, isc_sockstatscounter_tcp6recvfail, + isc_sockstatscounter_tcp6active +}; + +#if 0 +/* XXX: not currently used */ +static const isc_statscounter_t unixstatsindex[] = { + isc_sockstatscounter_unixopen, + isc_sockstatscounter_unixopenfail, + isc_sockstatscounter_unixclose, + isc_sockstatscounter_unixbindfail, + isc_sockstatscounter_unixconnectfail, + isc_sockstatscounter_unixconnect, + isc_sockstatscounter_unixacceptfail, + isc_sockstatscounter_unixaccept, + isc_sockstatscounter_unixsendfail, + isc_sockstatscounter_unixrecvfail, + isc_sockstatscounter_unixactive +}; +#endif /* if 0 */ + +/* + * libuv is not thread safe, but has mechanisms to pass messages + * between threads. Each socket is owned by a thread. For UDP + * sockets we have a set of sockets for each interface and we can + * choose a sibling and send the message directly. For TCP, or if + * we're calling from a non-networking thread, we need to pass the + * request using async_cb. + */ + +ISC_THREAD_LOCAL int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN; + +static void +nmsocket_maybe_destroy(isc_nmsocket_t *sock); +static void +nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle); +static isc_threadresult_t +nm_thread(isc_threadarg_t worker0); +static void +async_cb(uv_async_t *handle); +static bool +process_queue(isc__networker_t *worker, isc_queue_t *queue); +static bool +process_priority_queue(isc__networker_t *worker); +static bool +process_normal_queue(isc__networker_t *worker); +static void +process_queues(isc__networker_t *worker); + +static void +isc__nm_async_stopcb(isc__networker_t *worker, isc__netievent_t *ev0); +static void +isc__nm_async_pausecb(isc__networker_t *worker, isc__netievent_t *ev0); +static void +isc__nm_async_resumecb(isc__networker_t *worker, isc__netievent_t *ev0); + +int +isc_nm_tid() { + return (isc__nm_tid_v); +} + +bool +isc__nm_in_netthread() { + return (isc__nm_tid_v >= 0); +} + +isc_nm_t * +isc_nm_start(isc_mem_t *mctx, uint32_t workers) { + isc_nm_t *mgr = NULL; + char name[32]; + + mgr = isc_mem_get(mctx, sizeof(*mgr)); + *mgr = (isc_nm_t){ .nworkers = workers }; + + isc_mem_attach(mctx, &mgr->mctx); + isc_mutex_init(&mgr->lock); + isc_condition_init(&mgr->wkstatecond); + isc_refcount_init(&mgr->references, 1); + atomic_init(&mgr->maxudp, 0); + atomic_init(&mgr->interlocked, false); + +#ifdef NETMGR_TRACE + ISC_LIST_INIT(mgr->active_sockets); +#endif + + /* + * Default TCP timeout values. + * May be updated by isc_nm_tcptimeouts(). + */ + mgr->init = 30000; + mgr->idle = 30000; + mgr->keepalive = 30000; + mgr->advertised = 30000; + + isc_mutex_init(&mgr->reqlock); + isc_mempool_create(mgr->mctx, sizeof(isc__nm_uvreq_t), &mgr->reqpool); + isc_mempool_setname(mgr->reqpool, "nm_reqpool"); + isc_mempool_setfreemax(mgr->reqpool, 4096); + isc_mempool_associatelock(mgr->reqpool, &mgr->reqlock); + isc_mempool_setfillcount(mgr->reqpool, 32); + + isc_mutex_init(&mgr->evlock); + isc_mempool_create(mgr->mctx, sizeof(isc__netievent_storage_t), + &mgr->evpool); + isc_mempool_setname(mgr->evpool, "nm_evpool"); + isc_mempool_setfreemax(mgr->evpool, 4096); + isc_mempool_associatelock(mgr->evpool, &mgr->evlock); + isc_mempool_setfillcount(mgr->evpool, 32); + + mgr->workers = isc_mem_get(mctx, workers * sizeof(isc__networker_t)); + for (size_t i = 0; i < workers; i++) { + int r; + isc__networker_t *worker = &mgr->workers[i]; + *worker = (isc__networker_t){ + .mgr = mgr, + .id = i, + }; + + r = uv_loop_init(&worker->loop); + RUNTIME_CHECK(r == 0); + + worker->loop.data = &mgr->workers[i]; + + r = uv_async_init(&worker->loop, &worker->async, async_cb); + RUNTIME_CHECK(r == 0); + + isc_mutex_init(&worker->lock); + isc_condition_init(&worker->cond); + + worker->ievents = isc_queue_new(mgr->mctx, 128); + worker->ievents_prio = isc_queue_new(mgr->mctx, 128); + worker->recvbuf = isc_mem_get(mctx, ISC_NETMGR_RECVBUF_SIZE); + + /* + * We need to do this here and not in nm_thread to avoid a + * race - we could exit isc_nm_start, launch nm_destroy, + * and nm_thread would still not be up. + */ + mgr->workers_running++; + isc_thread_create(nm_thread, &mgr->workers[i], &worker->thread); + + snprintf(name, sizeof(name), "isc-net-%04zu", i); + isc_thread_setname(worker->thread, name); + } + + mgr->magic = NM_MAGIC; + return (mgr); +} + +/* + * Free the resources of the network manager. + */ +static void +nm_destroy(isc_nm_t **mgr0) { + REQUIRE(VALID_NM(*mgr0)); + REQUIRE(!isc__nm_in_netthread()); + + isc_nm_t *mgr = *mgr0; + *mgr0 = NULL; + + isc_refcount_destroy(&mgr->references); + + mgr->magic = 0; + + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__networker_t *worker = &mgr->workers[i]; + isc__netievent_t *event = isc__nm_get_ievent(mgr, + netievent_stop); + isc__nm_enqueue_ievent(worker, event); + } + + LOCK(&mgr->lock); + while (mgr->workers_running > 0) { + WAIT(&mgr->wkstatecond, &mgr->lock); + } + UNLOCK(&mgr->lock); + + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__networker_t *worker = &mgr->workers[i]; + isc__netievent_t *ievent = NULL; + int r; + + /* Empty the async event queues */ + while ((ievent = (isc__netievent_t *)isc_queue_dequeue( + worker->ievents)) != NULL) + { + isc_mempool_put(mgr->evpool, ievent); + } + + while ((ievent = (isc__netievent_t *)isc_queue_dequeue( + worker->ievents_prio)) != NULL) + { + isc_mempool_put(mgr->evpool, ievent); + } + + r = uv_loop_close(&worker->loop); + INSIST(r == 0); + + isc_queue_destroy(worker->ievents); + isc_queue_destroy(worker->ievents_prio); + isc_mutex_destroy(&worker->lock); + isc_condition_destroy(&worker->cond); + + isc_mem_put(mgr->mctx, worker->recvbuf, + ISC_NETMGR_RECVBUF_SIZE); + isc_thread_join(worker->thread, NULL); + } + + if (mgr->stats != NULL) { + isc_stats_detach(&mgr->stats); + } + + isc_condition_destroy(&mgr->wkstatecond); + isc_mutex_destroy(&mgr->lock); + + isc_mempool_destroy(&mgr->evpool); + isc_mutex_destroy(&mgr->evlock); + + isc_mempool_destroy(&mgr->reqpool); + isc_mutex_destroy(&mgr->reqlock); + + isc_mem_put(mgr->mctx, mgr->workers, + mgr->nworkers * sizeof(isc__networker_t)); + isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); +} + +void +isc_nm_pause(isc_nm_t *mgr) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(!isc__nm_in_netthread()); + + isc__nm_acquire_interlocked_force(mgr); + + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__networker_t *worker = &mgr->workers[i]; + isc__netievent_t *event = isc__nm_get_ievent(mgr, + netievent_pause); + isc__nm_enqueue_ievent(worker, event); + } + + LOCK(&mgr->lock); + while (mgr->workers_paused != mgr->workers_running) { + WAIT(&mgr->wkstatecond, &mgr->lock); + } + UNLOCK(&mgr->lock); +} + +void +isc_nm_resume(isc_nm_t *mgr) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(!isc__nm_in_netthread()); + + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__networker_t *worker = &mgr->workers[i]; + isc__netievent_t *event = isc__nm_get_ievent(mgr, + netievent_resume); + isc__nm_enqueue_ievent(worker, event); + } + + LOCK(&mgr->lock); + while (mgr->workers_paused != 0) { + WAIT(&mgr->wkstatecond, &mgr->lock); + } + UNLOCK(&mgr->lock); + + isc__nm_drop_interlocked(mgr); +} + +void +isc_nm_attach(isc_nm_t *mgr, isc_nm_t **dst) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(dst != NULL && *dst == NULL); + + isc_refcount_increment(&mgr->references); + + *dst = mgr; +} + +void +isc_nm_detach(isc_nm_t **mgr0) { + isc_nm_t *mgr = NULL; + + REQUIRE(mgr0 != NULL); + REQUIRE(VALID_NM(*mgr0)); + + mgr = *mgr0; + *mgr0 = NULL; + + if (isc_refcount_decrement(&mgr->references) == 1) { + nm_destroy(&mgr); + } +} + +void +isc_nm_closedown(isc_nm_t *mgr) { + REQUIRE(VALID_NM(mgr)); + + atomic_store(&mgr->closing, true); + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__netievent_t *event = NULL; + event = isc__nm_get_ievent(mgr, netievent_shutdown); + isc__nm_enqueue_ievent(&mgr->workers[i], event); + } +} + +void +isc_nm_destroy(isc_nm_t **mgr0) { + isc_nm_t *mgr = NULL; + int counter = 0; + uint_fast32_t references; + + REQUIRE(mgr0 != NULL); + REQUIRE(VALID_NM(*mgr0)); + + mgr = *mgr0; + + /* + * Close active connections. + */ + isc_nm_closedown(mgr); + + /* + * Wait for the manager to be dereferenced elsewhere. + */ + while ((references = isc_refcount_current(&mgr->references)) > 1 && + counter++ < 1000) + { +#ifdef WIN32 + _sleep(10); +#else /* ifdef WIN32 */ + usleep(10000); +#endif /* ifdef WIN32 */ + } + + INSIST(references == 1); + + /* + * Detach final reference. + */ + isc_nm_detach(mgr0); +} + +void +isc_nm_maxudp(isc_nm_t *mgr, uint32_t maxudp) { + REQUIRE(VALID_NM(mgr)); + + atomic_store(&mgr->maxudp, maxudp); +} + +void +isc_nm_tcp_settimeouts(isc_nm_t *mgr, uint32_t init, uint32_t idle, + uint32_t keepalive, uint32_t advertised) { + REQUIRE(VALID_NM(mgr)); + + mgr->init = init * 100; + mgr->idle = idle * 100; + mgr->keepalive = keepalive * 100; + mgr->advertised = advertised * 100; +} + +void +isc_nm_tcp_gettimeouts(isc_nm_t *mgr, uint32_t *initial, uint32_t *idle, + uint32_t *keepalive, uint32_t *advertised) { + REQUIRE(VALID_NM(mgr)); + + if (initial != NULL) { + *initial = mgr->init / 100; + } + + if (idle != NULL) { + *idle = mgr->idle / 100; + } + + if (keepalive != NULL) { + *keepalive = mgr->keepalive / 100; + } + + if (advertised != NULL) { + *advertised = mgr->advertised / 100; + } +} + +/* + * nm_thread is a single worker thread, that runs uv_run event loop + * until asked to stop. + */ +static isc_threadresult_t +nm_thread(isc_threadarg_t worker0) { + isc__networker_t *worker = (isc__networker_t *)worker0; + isc_nm_t *mgr = worker->mgr; + + isc__nm_tid_v = worker->id; + isc_thread_setaffinity(isc__nm_tid_v); + + while (true) { + int r = uv_run(&worker->loop, UV_RUN_DEFAULT); + /* There's always the async handle until we are done */ + INSIST(r > 0 || worker->finished); + + if (worker->paused) { + LOCK(&worker->lock); + /* We need to lock the worker first otherwise + * isc_nm_resume() might slip in before WAIT() in the + * while loop starts and the signal never gets delivered + * and we are forever stuck in the paused loop. + */ + + LOCK(&mgr->lock); + mgr->workers_paused++; + SIGNAL(&mgr->wkstatecond); + UNLOCK(&mgr->lock); + + while (worker->paused) { + WAIT(&worker->cond, &worker->lock); + (void)process_priority_queue(worker); + } + + LOCK(&mgr->lock); + mgr->workers_paused--; + SIGNAL(&mgr->wkstatecond); + UNLOCK(&mgr->lock); + + UNLOCK(&worker->lock); + } + + if (r == 0) { + INSIST(worker->finished); + break; + } + + INSIST(!worker->finished); + + /* + * Empty the async queue. + */ + process_queues(worker); + } + + LOCK(&mgr->lock); + mgr->workers_running--; + SIGNAL(&mgr->wkstatecond); + UNLOCK(&mgr->lock); + + return ((isc_threadresult_t)0); +} + +/* + * async_cb is a universal callback for 'async' events sent to event loop. + * It's the only way to safely pass data to the libuv event loop. We use a + * single async event and a lockless queue of 'isc__netievent_t' structures + * passed from other threads. + */ +static void +async_cb(uv_async_t *handle) { + isc__networker_t *worker = (isc__networker_t *)handle->loop->data; + process_queues(worker); +} + +static void +isc__nm_async_stopcb(isc__networker_t *worker, isc__netievent_t *ev0) { + UNUSED(ev0); + worker->finished = true; + /* Close the async handler */ + uv_close((uv_handle_t *)&worker->async, NULL); + /* uv_stop(&worker->loop); */ +} + +static void +isc__nm_async_pausecb(isc__networker_t *worker, isc__netievent_t *ev0) { + UNUSED(ev0); + REQUIRE(worker->paused == false); + worker->paused = true; + uv_stop(&worker->loop); +} + +static void +isc__nm_async_resumecb(isc__networker_t *worker, isc__netievent_t *ev0) { + UNUSED(ev0); + REQUIRE(worker->paused == true); + worker->paused = false; +} + +static bool +process_priority_queue(isc__networker_t *worker) { + return (process_queue(worker, worker->ievents_prio)); +} + +static bool +process_normal_queue(isc__networker_t *worker) { + return (process_queue(worker, worker->ievents)); +} + +static void +process_queues(isc__networker_t *worker) { + if (!process_priority_queue(worker)) { + return; + } + (void)process_normal_queue(worker); +} + +static bool +process_queue(isc__networker_t *worker, isc_queue_t *queue) { + isc__netievent_t *ievent = NULL; + bool more = true; + + while ((ievent = (isc__netievent_t *)isc_queue_dequeue(queue)) != NULL) + { + switch (ievent->type) { + case netievent_stop: + isc__nm_async_stopcb(worker, ievent); + /* Don't process more ievents when we are stopping */ + more = false; + break; + + case netievent_udplisten: + isc__nm_async_udplisten(worker, ievent); + break; + case netievent_udpstop: + isc__nm_async_udpstop(worker, ievent); + break; + case netievent_udpsend: + isc__nm_async_udpsend(worker, ievent); + break; + + case netievent_tcpconnect: + isc__nm_async_tcpconnect(worker, ievent); + break; + case netievent_tcplisten: + isc__nm_async_tcplisten(worker, ievent); + break; + case netievent_tcpchildaccept: + isc__nm_async_tcpchildaccept(worker, ievent); + break; + case netievent_tcpaccept: + isc__nm_async_tcpaccept(worker, ievent); + break; + case netievent_tcpstartread: + isc__nm_async_tcp_startread(worker, ievent); + break; + case netievent_tcppauseread: + isc__nm_async_tcp_pauseread(worker, ievent); + break; + case netievent_tcpsend: + isc__nm_async_tcpsend(worker, ievent); + break; + case netievent_tcpdnssend: + isc__nm_async_tcpdnssend(worker, ievent); + break; + case netievent_tcpstop: + isc__nm_async_tcpstop(worker, ievent); + break; + case netievent_tcpclose: + isc__nm_async_tcpclose(worker, ievent); + break; + + case netievent_tcpdnsclose: + isc__nm_async_tcpdnsclose(worker, ievent); + break; + case netievent_tcpdnsstop: + isc__nm_async_tcpdnsstop(worker, ievent); + break; + + case netievent_closecb: + isc__nm_async_closecb(worker, ievent); + break; + case netievent_shutdown: + isc__nm_async_shutdown(worker, ievent); + break; + + case netievent_resume: + isc__nm_async_resumecb(worker, ievent); + break; + case netievent_pause: + isc__nm_async_pausecb(worker, ievent); + /* Don't process more ievents when we are pausing */ + more = false; + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + + isc__nm_put_ievent(worker->mgr, ievent); + if (!more) { + break; + } + } + return (more); +} + +void * +isc__nm_get_ievent(isc_nm_t *mgr, isc__netievent_type type) { + isc__netievent_storage_t *event = isc_mempool_get(mgr->evpool); + + *event = (isc__netievent_storage_t){ .ni.type = type }; + return (event); +} + +void +isc__nm_put_ievent(isc_nm_t *mgr, void *ievent) { + isc_mempool_put(mgr->evpool, ievent); +} + +void +isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event) { + if (event->type > netievent_prio) { + /* + * We need to make sure this signal will be delivered and + * the queue will be processed. + */ + LOCK(&worker->lock); + isc_queue_enqueue(worker->ievents_prio, (uintptr_t)event); + SIGNAL(&worker->cond); + UNLOCK(&worker->lock); + } else { + isc_queue_enqueue(worker->ievents, (uintptr_t)event); + } + uv_async_send(&worker->async); +} + +bool +isc__nmsocket_active(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + if (sock->parent != NULL) { + return (atomic_load(&sock->parent->active)); + } + + return (atomic_load(&sock->active)); +} + +void +isc__nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(target != NULL && *target == NULL); + + if (sock->parent != NULL) { + INSIST(sock->parent->parent == NULL); /* sanity check */ + isc_refcount_increment0(&sock->parent->references); + } else { + isc_refcount_increment0(&sock->references); + } + + *target = sock; +} + +/* + * Free all resources inside a socket (including its children if any). + */ +static void +nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) { + isc_nmhandle_t *handle = NULL; + isc__nm_uvreq_t *uvreq = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(!isc__nmsocket_active(sock)); + + atomic_store(&sock->destroying, true); + + if (sock->parent == NULL && sock->children != NULL) { + /* + * We shouldn't be here unless there are no active handles, + * so we can clean up and free the children. + */ + for (int i = 0; i < sock->nchildren; i++) { + if (!atomic_load(&sock->children[i].destroying)) { + nmsocket_cleanup(&sock->children[i], false); + } + } + + /* + * This was a parent socket; free the children. + */ + isc_mem_put(sock->mgr->mctx, sock->children, + sock->nchildren * sizeof(*sock)); + sock->children = NULL; + sock->nchildren = 0; + } + if (sock->statsindex != NULL) { + isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); + } + + sock->statichandle = NULL; + + if (sock->outerhandle != NULL) { + isc_nmhandle_detach(&sock->outerhandle); + } + + if (sock->outer != NULL) { + isc__nmsocket_detach(&sock->outer); + } + + while ((handle = isc_astack_pop(sock->inactivehandles)) != NULL) { + nmhandle_free(sock, handle); + } + + if (sock->buf != NULL) { + isc_mem_free(sock->mgr->mctx, sock->buf); + } + + if (sock->quota != NULL) { + isc_quota_detach(&sock->quota); + } + + sock->pquota = NULL; + + if (sock->timer_initialized) { + sock->timer_initialized = false; + /* We might be in timer callback */ + if (!uv_is_closing((uv_handle_t *)&sock->timer)) { + uv_timer_stop(&sock->timer); + uv_close((uv_handle_t *)&sock->timer, NULL); + } + } + + isc_astack_destroy(sock->inactivehandles); + + while ((uvreq = isc_astack_pop(sock->inactivereqs)) != NULL) { + isc_mempool_put(sock->mgr->reqpool, uvreq); + } + + isc_astack_destroy(sock->inactivereqs); + sock->magic = 0; + + isc_mem_free(sock->mgr->mctx, sock->ah_frees); + isc_mem_free(sock->mgr->mctx, sock->ah_handles); + isc_mutex_destroy(&sock->lock); + isc_condition_destroy(&sock->cond); +#ifdef NETMGR_TRACE + LOCK(&sock->mgr->lock); + ISC_LIST_UNLINK(sock->mgr->active_sockets, sock, active_link); + UNLOCK(&sock->mgr->lock); +#endif + if (dofree) { + isc_nm_t *mgr = sock->mgr; + isc_mem_put(mgr->mctx, sock, sizeof(*sock)); + isc_nm_detach(&mgr); + } else { + isc_nm_detach(&sock->mgr); + } +} + +static void +nmsocket_maybe_destroy(isc_nmsocket_t *sock) { + int active_handles; + bool destroy = false; + + if (sock->parent != NULL) { + /* + * This is a child socket and cannot be destroyed except + * as a side effect of destroying the parent, so let's go + * see if the parent is ready to be destroyed. + */ + nmsocket_maybe_destroy(sock->parent); + return; + } + + /* + * This is a parent socket (or a standalone). See whether the + * children have active handles before deciding whether to + * accept destruction. + */ + LOCK(&sock->lock); + if (atomic_load(&sock->active) || atomic_load(&sock->destroying) || + !atomic_load(&sock->closed) || atomic_load(&sock->references) != 0) + { + UNLOCK(&sock->lock); + return; + } + + active_handles = atomic_load(&sock->ah); + if (sock->children != NULL) { + for (int i = 0; i < sock->nchildren; i++) { + LOCK(&sock->children[i].lock); + active_handles += atomic_load(&sock->children[i].ah); + UNLOCK(&sock->children[i].lock); + } + } + + if (active_handles == 0 || sock->statichandle != NULL) { + destroy = true; + } + + if (destroy) { + atomic_store(&sock->destroying, true); + UNLOCK(&sock->lock); + nmsocket_cleanup(sock, true); + } else { + UNLOCK(&sock->lock); + } +} + +void +isc__nmsocket_prep_destroy(isc_nmsocket_t *sock) { + REQUIRE(sock->parent == NULL); + + /* + * The final external reference to the socket is gone. We can try + * destroying the socket, but we have to wait for all the inflight + * handles to finish first. + */ + atomic_store(&sock->active, false); + + /* + * If the socket has children, they'll need to be marked inactive + * so they can be cleaned up too. + */ + if (sock->children != NULL) { + for (int i = 0; i < sock->nchildren; i++) { + atomic_store(&sock->children[i].active, false); + } + } + + /* + * If we're here then we already stopped listening; otherwise + * we'd have a hanging reference from the listening process. + * + * If it's a regular socket we may need to close it. + */ + if (!atomic_load(&sock->closed)) { + switch (sock->type) { + case isc_nm_tcpsocket: + isc__nm_tcp_close(sock); + return; + case isc_nm_tcpdnssocket: + isc__nm_tcpdns_close(sock); + return; + default: + break; + } + } + + nmsocket_maybe_destroy(sock); +} + +void +isc__nmsocket_detach(isc_nmsocket_t **sockp) { + REQUIRE(sockp != NULL && *sockp != NULL); + REQUIRE(VALID_NMSOCK(*sockp)); + + isc_nmsocket_t *sock = *sockp, *rsock = NULL; + *sockp = NULL; + + /* + * If the socket is a part of a set (a child socket) we are + * counting references for the whole set at the parent. + */ + if (sock->parent != NULL) { + rsock = sock->parent; + INSIST(rsock->parent == NULL); /* Sanity check */ + } else { + rsock = sock; + } + + if (isc_refcount_decrement(&rsock->references) == 1) { + isc__nmsocket_prep_destroy(rsock); + } +} + +void +isc_nmsocket_close(isc_nmsocket_t **sockp) { + REQUIRE(sockp != NULL); + REQUIRE(VALID_NMSOCK(*sockp)); + REQUIRE((*sockp)->type == isc_nm_udplistener || + (*sockp)->type == isc_nm_tcplistener || + (*sockp)->type == isc_nm_tcpdnslistener); + + isc__nmsocket_detach(sockp); +} + +void +isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type, + isc_nmiface_t *iface) { + uint16_t family; + + REQUIRE(sock != NULL); + REQUIRE(mgr != NULL); + REQUIRE(iface != NULL); + + family = iface->addr.type.sa.sa_family; + + *sock = (isc_nmsocket_t){ .type = type, + .iface = iface, + .fd = -1, + .ah_size = 32, + .inactivehandles = isc_astack_new( + mgr->mctx, ISC_NM_HANDLES_STACK_SIZE), + .inactivereqs = isc_astack_new( + mgr->mctx, ISC_NM_REQS_STACK_SIZE) }; + +#ifdef NETMGR_TRACE + sock->backtrace_size = backtrace(sock->backtrace, TRACE_SIZE); + ISC_LINK_INIT(sock, active_link); + ISC_LIST_INIT(sock->active_handles); + LOCK(&mgr->lock); + ISC_LIST_APPEND(mgr->active_sockets, sock, active_link); + UNLOCK(&mgr->lock); +#endif + + isc_nm_attach(mgr, &sock->mgr); + sock->uv_handle.handle.data = sock; + + sock->ah_frees = isc_mem_allocate(mgr->mctx, + sock->ah_size * sizeof(size_t)); + sock->ah_handles = isc_mem_allocate( + mgr->mctx, sock->ah_size * sizeof(isc_nmhandle_t *)); + ISC_LINK_INIT(&sock->quotacb, link); + for (size_t i = 0; i < 32; i++) { + sock->ah_frees[i] = i; + sock->ah_handles[i] = NULL; + } + + switch (type) { + case isc_nm_udpsocket: + case isc_nm_udplistener: + if (family == AF_INET) { + sock->statsindex = udp4statsindex; + } else { + sock->statsindex = udp6statsindex; + } + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); + break; + case isc_nm_tcpsocket: + case isc_nm_tcplistener: + if (family == AF_INET) { + sock->statsindex = tcp4statsindex; + } else { + sock->statsindex = tcp6statsindex; + } + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); + break; + default: + break; + } + + isc_mutex_init(&sock->lock); + isc_condition_init(&sock->cond); + isc_refcount_init(&sock->references, 1); + + atomic_init(&sock->active, true); + atomic_init(&sock->sequential, false); + atomic_init(&sock->overlimit, false); + atomic_init(&sock->processing, false); + atomic_init(&sock->readpaused, false); + + sock->magic = NMSOCK_MAGIC; +} + +void +isc__nmsocket_clearcb(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(!isc__nm_in_netthread() || sock->tid == isc_nm_tid()); + + sock->recv_cb = NULL; + sock->recv_cbarg = NULL; + sock->accept_cb = NULL; + sock->accept_cbarg = NULL; +} + +void +isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) { + isc__networker_t *worker = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + if (buf->base == NULL) { + /* Empty buffer: might happen in case of error. */ + return; + } + worker = &sock->mgr->workers[sock->tid]; + + REQUIRE(worker->recvbuf_inuse); + if (sock->type == isc_nm_udpsocket && buf->base > worker->recvbuf && + buf->base <= worker->recvbuf + ISC_NETMGR_RECVBUF_SIZE) + { + /* Can happen in case of out-of-order recvmmsg in libuv1.36 */ + return; + } + REQUIRE(buf->base == worker->recvbuf); + worker->recvbuf_inuse = false; +} + +static isc_nmhandle_t * +alloc_handle(isc_nmsocket_t *sock) { + isc_nmhandle_t *handle = + isc_mem_get(sock->mgr->mctx, + sizeof(isc_nmhandle_t) + sock->extrahandlesize); + + *handle = (isc_nmhandle_t){ .magic = NMHANDLE_MAGIC }; +#ifdef NETMGR_TRACE + ISC_LINK_INIT(handle, active_link); +#endif + isc_refcount_init(&handle->references, 1); + + return (handle); +} + +isc_nmhandle_t * +isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer, + isc_sockaddr_t *local) { + isc_nmhandle_t *handle = NULL; + size_t handlenum; + int pos; + + REQUIRE(VALID_NMSOCK(sock)); + + handle = isc_astack_pop(sock->inactivehandles); + + if (handle == NULL) { + handle = alloc_handle(sock); + } else { + isc_refcount_init(&handle->references, 1); + INSIST(VALID_NMHANDLE(handle)); + } + + isc__nmsocket_attach(sock, &handle->sock); + +#ifdef NETMGR_TRACE + handle->backtrace_size = backtrace(handle->backtrace, TRACE_SIZE); +#endif + + if (peer != NULL) { + memcpy(&handle->peer, peer, sizeof(isc_sockaddr_t)); + } else { + memcpy(&handle->peer, &sock->peer, sizeof(isc_sockaddr_t)); + } + + if (local != NULL) { + memcpy(&handle->local, local, sizeof(isc_sockaddr_t)); + } else if (sock->iface != NULL) { + memcpy(&handle->local, &sock->iface->addr, + sizeof(isc_sockaddr_t)); + } else { + INSIST(0); + ISC_UNREACHABLE(); + } + + LOCK(&sock->lock); + /* We need to add this handle to the list of active handles */ + if ((size_t)atomic_load(&sock->ah) == sock->ah_size) { + sock->ah_frees = + isc_mem_reallocate(sock->mgr->mctx, sock->ah_frees, + sock->ah_size * 2 * sizeof(size_t)); + sock->ah_handles = isc_mem_reallocate( + sock->mgr->mctx, sock->ah_handles, + sock->ah_size * 2 * sizeof(isc_nmhandle_t *)); + + for (size_t i = sock->ah_size; i < sock->ah_size * 2; i++) { + sock->ah_frees[i] = i; + sock->ah_handles[i] = NULL; + } + + sock->ah_size *= 2; + } + + handlenum = atomic_fetch_add(&sock->ah, 1); + pos = sock->ah_frees[handlenum]; + + INSIST(sock->ah_handles[pos] == NULL); + sock->ah_handles[pos] = handle; + handle->ah_pos = pos; +#ifdef NETMGR_TRACE + ISC_LIST_APPEND(sock->active_handles, handle, active_link); +#endif + UNLOCK(&sock->lock); + + if (sock->type == isc_nm_tcpsocket || + (sock->type == isc_nm_udpsocket && atomic_load(&sock->client))) + { + INSIST(sock->statichandle == NULL); + + /* + * statichandle must be assigned, not attached; + * otherwise, if a handle was detached elsewhere + * it could never reach 0 references, and the + * handle and socket would never be freed. + */ + sock->statichandle = handle; + } + + return (handle); +} + +void +isc_nmhandle_attach(isc_nmhandle_t *handle, isc_nmhandle_t **handlep) { + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(handlep != NULL && *handlep == NULL); + + isc_refcount_increment(&handle->references); + *handlep = handle; +} + +bool +isc_nmhandle_is_stream(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + return (handle->sock->type == isc_nm_tcpsocket || + handle->sock->type == isc_nm_tcpdnssocket); +} + +static void +nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle) { + size_t extra = sock->extrahandlesize; + + isc_refcount_destroy(&handle->references); + + if (handle->dofree != NULL) { + handle->dofree(handle->opaque); + } + + *handle = (isc_nmhandle_t){ .magic = 0 }; + + isc_mem_put(sock->mgr->mctx, handle, sizeof(isc_nmhandle_t) + extra); +} + +static void +nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) { + size_t handlenum; + bool reuse = false; + + /* + * We do all of this under lock to avoid races with socket + * destruction. We have to do this now, because at this point the + * socket is either unused or still attached to event->sock. + */ + LOCK(&sock->lock); + + INSIST(sock->ah_handles[handle->ah_pos] == handle); + INSIST(sock->ah_size > handle->ah_pos); + INSIST(atomic_load(&sock->ah) > 0); + +#ifdef NETMGR_TRACE + ISC_LIST_UNLINK(sock->active_handles, handle, active_link); +#endif + + sock->ah_handles[handle->ah_pos] = NULL; + handlenum = atomic_fetch_sub(&sock->ah, 1) - 1; + sock->ah_frees[handlenum] = handle->ah_pos; + handle->ah_pos = 0; + if (atomic_load(&sock->active)) { + reuse = isc_astack_trypush(sock->inactivehandles, handle); + } + if (!reuse) { + nmhandle_free(sock, handle); + } + UNLOCK(&sock->lock); +} + +void +isc_nmhandle_detach(isc_nmhandle_t **handlep) { + isc_nmsocket_t *sock = NULL; + isc_nmhandle_t *handle = NULL; + + REQUIRE(handlep != NULL); + REQUIRE(VALID_NMHANDLE(*handlep)); + + handle = *handlep; + *handlep = NULL; + + if (isc_refcount_decrement(&handle->references) > 1) { + return; + } + + /* We need an acquire memory barrier here */ + (void)isc_refcount_current(&handle->references); + + sock = handle->sock; + handle->sock = NULL; + + if (handle->doreset != NULL) { + handle->doreset(handle->opaque); + } + + nmhandle_deactivate(sock, handle); + + /* + * The handle is gone now. If the socket has a callback configured + * for that (e.g., to perform cleanup after request processing), + * call it now, or schedule it to run asynchronously. + */ + if (sock->closehandle_cb != NULL) { + if (sock->tid == isc_nm_tid()) { + sock->closehandle_cb(sock); + } else { + isc__netievent_closecb_t *event = isc__nm_get_ievent( + sock->mgr, netievent_closecb); + /* + * The socket will be finally detached by the closecb + * event handler. + */ + isc__nmsocket_attach(sock, &event->sock); + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)event); + } + } + + if (handle == sock->statichandle) { + /* statichandle is assigned, not attached. */ + sock->statichandle = NULL; + } + + isc__nmsocket_detach(&sock); +} + +void * +isc_nmhandle_getdata(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + return (handle->opaque); +} + +void +isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg, + isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree) { + REQUIRE(VALID_NMHANDLE(handle)); + + handle->opaque = arg; + handle->doreset = doreset; + handle->dofree = dofree; +} + +void * +isc_nmhandle_getextra(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + return (handle->extra); +} + +isc_sockaddr_t +isc_nmhandle_peeraddr(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + return (handle->peer); +} + +isc_sockaddr_t +isc_nmhandle_localaddr(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + return (handle->local); +} + +isc_nm_t * +isc_nmhandle_netmgr(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + return (handle->sock->mgr); +} + +isc__nm_uvreq_t * +isc__nm_uvreq_get(isc_nm_t *mgr, isc_nmsocket_t *sock) { + isc__nm_uvreq_t *req = NULL; + + REQUIRE(VALID_NM(mgr)); + REQUIRE(VALID_NMSOCK(sock)); + + if (sock != NULL && atomic_load(&sock->active)) { + /* Try to reuse one */ + req = isc_astack_pop(sock->inactivereqs); + } + + if (req == NULL) { + req = isc_mempool_get(mgr->reqpool); + } + + *req = (isc__nm_uvreq_t){ .magic = 0 }; + req->uv_req.req.data = req; + isc__nmsocket_attach(sock, &req->sock); + req->magic = UVREQ_MAGIC; + + return (req); +} + +void +isc__nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock) { + isc__nm_uvreq_t *req = NULL; + isc_nmhandle_t *handle = NULL; + + REQUIRE(req0 != NULL); + REQUIRE(VALID_UVREQ(*req0)); + + req = *req0; + *req0 = NULL; + + INSIST(sock == req->sock); + + req->magic = 0; + + /* + * We need to save this first to make sure that handle, + * sock, and the netmgr won't all disappear. + */ + handle = req->handle; + req->handle = NULL; + + if (!atomic_load(&sock->active) || + !isc_astack_trypush(sock->inactivereqs, req)) { + isc_mempool_put(sock->mgr->reqpool, req); + } + + if (handle != NULL) { + isc_nmhandle_detach(&handle); + } + + isc__nmsocket_detach(&sock); +} + +isc_result_t +isc_nm_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg) { + REQUIRE(VALID_NMHANDLE(handle)); + + switch (handle->sock->type) { + case isc_nm_udpsocket: + case isc_nm_udplistener: + return (isc__nm_udp_send(handle, region, cb, cbarg)); + case isc_nm_tcpsocket: + return (isc__nm_tcp_send(handle, region, cb, cbarg)); + case isc_nm_tcpdnssocket: + return (isc__nm_tcpdns_send(handle, region, cb, cbarg)); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +isc_result_t +isc_nm_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { + REQUIRE(VALID_NMHANDLE(handle)); + + switch (handle->sock->type) { + case isc_nm_tcpsocket: + return (isc__nm_tcp_read(handle, cb, cbarg)); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +void +isc_nm_cancelread(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + switch (handle->sock->type) { + case isc_nm_tcpsocket: + isc__nm_tcp_cancelread(handle); + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +isc_result_t +isc_nm_pauseread(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + isc_nmsocket_t *sock = handle->sock; + + switch (sock->type) { + case isc_nm_tcpsocket: + return (isc__nm_tcp_pauseread(sock)); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +isc_result_t +isc_nm_resumeread(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + isc_nmsocket_t *sock = handle->sock; + + switch (sock->type) { + case isc_nm_tcpsocket: + return (isc__nm_tcp_resumeread(sock)); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +void +isc_nm_stoplistening(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + + switch (sock->type) { + case isc_nm_udplistener: + isc__nm_udp_stoplistening(sock); + break; + case isc_nm_tcpdnslistener: + isc__nm_tcpdns_stoplistening(sock); + break; + case isc_nm_tcplistener: + isc__nm_tcp_stoplistening(sock); + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +void +isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_closecb_t *ievent = (isc__netievent_closecb_t *)ev0; + + REQUIRE(VALID_NMSOCK(ievent->sock)); + REQUIRE(ievent->sock->tid == isc_nm_tid()); + REQUIRE(ievent->sock->closehandle_cb != NULL); + + UNUSED(worker); + + ievent->sock->closehandle_cb(ievent->sock); + isc__nmsocket_detach(&ievent->sock); +} + +static void +shutdown_walk_cb(uv_handle_t *handle, void *arg) { + UNUSED(arg); + + switch (handle->type) { + case UV_TCP: + isc__nm_tcp_shutdown(uv_handle_get_data(handle)); + break; + default: + break; + } +} + +void +isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0) { + UNUSED(ev0); + uv_walk(&worker->loop, shutdown_walk_cb, NULL); +} + +bool +isc__nm_acquire_interlocked(isc_nm_t *mgr) { + LOCK(&mgr->lock); + bool success = atomic_compare_exchange_strong(&mgr->interlocked, + &(bool){ false }, true); + UNLOCK(&mgr->lock); + return (success); +} + +void +isc__nm_drop_interlocked(isc_nm_t *mgr) { + LOCK(&mgr->lock); + bool success = atomic_compare_exchange_strong(&mgr->interlocked, + &(bool){ true }, false); + INSIST(success); + BROADCAST(&mgr->wkstatecond); + UNLOCK(&mgr->lock); +} + +void +isc__nm_acquire_interlocked_force(isc_nm_t *mgr) { + LOCK(&mgr->lock); + while (!atomic_compare_exchange_strong(&mgr->interlocked, + &(bool){ false }, true)) + { + WAIT(&mgr->wkstatecond, &mgr->lock); + } + UNLOCK(&mgr->lock); +} + +void +isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(mgr->stats == NULL); + REQUIRE(isc_stats_ncounters(stats) == isc_sockstatscounter_max); + + isc_stats_attach(stats, &mgr->stats); +} + +void +isc__nm_incstats(isc_nm_t *mgr, isc_statscounter_t counterid) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(counterid != -1); + + if (mgr->stats != NULL) { + isc_stats_increment(mgr->stats, counterid); + } +} + +void +isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(counterid != -1); + + if (mgr->stats != NULL) { + isc_stats_decrement(mgr->stats, counterid); + } +} + +#define setsockopt_on(socket, level, name) \ + setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) + +isc_result_t +isc__nm_socket_freebind(uv_os_sock_t fd, sa_family_t sa_family) { + /* + * Set the IP_FREEBIND (or equivalent option) on the uv_handle. + */ +#ifdef IP_FREEBIND + UNUSED(sa_family); + if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#elif defined(IP_BINDANY) || defined(IPV6_BINDANY) + if (sa_family == AF_INET) { +#if defined(IP_BINDANY) + if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#endif + } else if (sa_family == AF_INET6) { +#if defined(IPV6_BINDANY) + if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#endif + } + return (ISC_R_NOTIMPLEMENTED); +#elif defined(SO_BINDANY) + UNUSED(sa_family); + if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#else + UNUSED(fd); + UNUSED(sa_family); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +isc_result_t +isc__nm_socket_reuse(uv_os_sock_t fd) { + /* + * Generally, the SO_REUSEADDR socket option allows reuse of + * local addresses. + * + * On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some + * additional refinements for programs that use multicast. + * + * On Linux, SO_REUSEPORT has different semantics: it _shares_ the port + * rather than steal it from the current listener, so we don't use it + * here, but rather in isc__nm_socket_reuse_lb(). + * + * On Windows, it also allows a socket to forcibly bind to a port in use + * by another socket. + */ + +#if defined(SO_REUSEPORT) && !defined(__linux__) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#elif defined(SO_REUSEADDR) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEADDR) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#else + UNUSED(fd); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +isc_result_t +isc__nm_socket_reuse_lb(uv_os_sock_t fd) { + /* + * On FreeBSD 12+, SO_REUSEPORT_LB socket option allows sockets to be + * bound to an identical socket address. For UDP sockets, the use of + * this option can provide better distribution of incoming datagrams to + * multiple processes (or threads) as compared to the traditional + * technique of having multiple processes compete to receive datagrams + * on the same socket. + * + * On Linux, the same thing is achieved simply with SO_REUSEPORT. + */ +#if defined(SO_REUSEPORT_LB) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT_LB) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(SO_REUSEPORT) && defined(__linux__) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +isc_result_t +isc__nm_socket_incoming_cpu(uv_os_sock_t fd) { +#ifdef SO_INCOMING_CPU + if (setsockopt_on(fd, SOL_SOCKET, SO_INCOMING_CPU) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + return (ISC_R_NOTIMPLEMENTED); +} + +isc_result_t +isc__nm_socket_dontfrag(uv_os_sock_t fd, sa_family_t sa_family) { + /* + * Set the Don't Fragment flag on IP packets + */ + if (sa_family == AF_INET6) { +#if defined(IPV6_DONTFRAG) + if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_DONTFRAG) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(IPV6_MTU_DISCOVER) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &(int){ IP_PMTUDISC_DO }, sizeof(int)) == -1) + { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + } else if (sa_family == AF_INET) { +#if defined(IP_DONTFRAG) + if (setsockopt_on(fd, IPPROTO_IP, IP_DONTFRAG) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(IP_MTU_DISCOVER) + if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, + &(int){ IP_PMTUDISC_DO }, sizeof(int)) == -1) + { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + } else { + return (ISC_R_FAMILYNOSUPPORT); + } + + return (ISC_R_NOTIMPLEMENTED); +} + +#ifdef NETMGR_TRACE +/* + * Dump all active sockets in netmgr. We output to stderr + * as the logger might be already shut down. + */ + +static const char * +nmsocket_type_totext(isc_nmsocket_type type) { + switch (type) { + case isc_nm_udpsocket: + return ("isc_nm_udpsocket"); + case isc_nm_udplistener: + return ("isc_nm_udplistener"); + case isc_nm_tcpsocket: + return ("isc_nm_tcpsocket"); + case isc_nm_tcplistener: + return ("isc_nm_tcplistener"); + case isc_nm_tcpdnslistener: + return ("isc_nm_tcpdnslistener"); + case isc_nm_tcpdnssocket: + return ("isc_nm_tcpdnssocket"); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +static void +nmhandle_dump(isc_nmhandle_t *handle) { + fprintf(stderr, "Active handle %p, refs %lu\n", handle, + isc_refcount_current(&handle->references)); + fprintf(stderr, "Created by:\n"); + backtrace_symbols_fd(handle->backtrace, handle->backtrace_size, + STDERR_FILENO); + fprintf(stderr, "\n\n"); +} + +static void +nmsocket_dump(isc_nmsocket_t *sock) { + isc_nmhandle_t *handle; + LOCK(&sock->lock); + fprintf(stderr, "\n=================\n"); + fprintf(stderr, "Active socket %p, type %s, refs %lu\n", sock, + nmsocket_type_totext(sock->type), + isc_refcount_current(&sock->references)); + fprintf(stderr, "Parent %p, listener %p\n", sock->parent, + sock->listener); + fprintf(stderr, "Created by:\n"); + backtrace_symbols_fd(sock->backtrace, sock->backtrace_size, + STDERR_FILENO); + fprintf(stderr, "\n"); + fprintf(stderr, "Active handles:\n"); + for (handle = ISC_LIST_HEAD(sock->active_handles); handle != NULL; + handle = ISC_LIST_NEXT(handle, active_link)) + { + nmhandle_dump(handle); + } + fprintf(stderr, "\n"); + UNLOCK(&sock->lock); +} + +void +isc__nm_dump_active(isc_nm_t *nm) { + isc_nmsocket_t *sock; + REQUIRE(VALID_NM(nm)); + LOCK(&nm->lock); + fprintf(stderr, "Outstanding sockets\n"); + for (sock = ISC_LIST_HEAD(nm->active_sockets); sock != NULL; + sock = ISC_LIST_NEXT(sock, active_link)) + { + nmsocket_dump(sock); + } + UNLOCK(&nm->lock); +} +#endif diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c new file mode 100644 index 00000000..9c147121 --- /dev/null +++ b/lib/isc/netmgr/tcp.c @@ -0,0 +1,1184 @@ +/* + * 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. + */ + +#include <libgen.h> +#include <unistd.h> +#include <uv.h> + +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/condition.h> +#include <isc/log.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/quota.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/sockaddr.h> +#include <isc/stdtime.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include "netmgr-int.h" +#include "uv-compat.h" + +static atomic_uint_fast32_t last_tcpquota_log = ATOMIC_VAR_INIT(0); + +static bool +can_log_tcp_quota() { + isc_stdtime_t now, last; + + isc_stdtime_get(&now); + last = atomic_exchange_relaxed(&last_tcpquota_log, now); + if (now != last) { + return (true); + } + + return (false); +} + +static int +tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req); + +static void +tcp_close_direct(isc_nmsocket_t *sock); + +static isc_result_t +tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req); +static void +tcp_connect_cb(uv_connect_t *uvreq, int status); + +static void +tcp_connection_cb(uv_stream_t *server, int status); + +static void +read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + +static void +tcp_close_cb(uv_handle_t *uvhandle); + +static void +tcp_listenclose_cb(uv_handle_t *handle); +static isc_result_t +accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota); + +static void +quota_accept_cb(isc_quota_t *quota, void *sock0); + +static int +tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { + isc__networker_t *worker = NULL; + int r; + + REQUIRE(isc__nm_in_netthread()); + + worker = &sock->mgr->workers[isc_nm_tid()]; + + r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp); + if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); + /* Socket was never opened; no need for tcp_close_direct() */ + atomic_store(&sock->closed, true); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->connect_error, true); + return (r); + } + + if (req->local.length != 0) { + r = uv_tcp_bind(&sock->uv_handle.tcp, &req->local.type.sa, 0); + if (r != 0) { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_BINDFAIL]); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->connect_error, true); + tcp_close_direct(sock); + return (r); + } + } + + uv_handle_set_data(&sock->uv_handle.handle, sock); + r = uv_tcp_connect(&req->uv_req.connect, &sock->uv_handle.tcp, + &req->peer.type.sa, tcp_connect_cb); + if (r != 0) { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_CONNECTFAIL]); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->connect_error, true); + tcp_close_direct(sock); + } + return (r); +} + +void +isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpconnect_t *ievent = + (isc__netievent_tcpconnect_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + isc__nm_uvreq_t *req = ievent->req; + int r; + + UNUSED(worker); + + r = tcp_connect_direct(sock, req); + if (r != 0) { + /* We need to issue callbacks ourselves */ + tcp_connect_cb(&req->uv_req.connect, r); + goto done; + } + + atomic_store(&sock->connected, true); + +done: + LOCK(&sock->lock); + SIGNAL(&sock->cond); + UNLOCK(&sock->lock); +} + +static void +tcp_connect_cb(uv_connect_t *uvreq, int status) { + isc_result_t result; + isc__nm_uvreq_t *req = (isc__nm_uvreq_t *)uvreq->data; + isc_nmsocket_t *sock = NULL; + struct sockaddr_storage ss; + isc_nmhandle_t *handle = NULL; + + sock = uv_handle_get_data((uv_handle_t *)uvreq->handle); + + REQUIRE(VALID_UVREQ(req)); + + if (status != 0) { + req->cb.connect(NULL, isc__nm_uverr2result(status), req->cbarg); + isc__nm_uvreq_put(&req, sock); + return; + } + + sock = uv_handle_get_data((uv_handle_t *)uvreq->handle); + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]); + uv_tcp_getpeername(&sock->uv_handle.tcp, (struct sockaddr *)&ss, + &(int){ sizeof(ss) }); + result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + handle = isc__nmhandle_get(sock, NULL, NULL); + req->cb.connect(handle, ISC_R_SUCCESS, req->cbarg); + + isc__nm_uvreq_put(&req, sock); + + atomic_init(&sock->client, true); + + /* + * The sock is now attached to the handle. + */ + isc__nmsocket_detach(&sock); + + /* + * The connect callback should have attached to the handle. + * If it didn't, the socket will be closed now. + */ + isc_nmhandle_detach(&handle); +} + +isc_result_t +isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer, + isc_nm_cb_t cb, void *cbarg, size_t extrahandlesize) { + isc_nmsocket_t *nsock = NULL, *tmp = NULL; + isc__netievent_tcpconnect_t *ievent = NULL; + isc__nm_uvreq_t *req = NULL; + isc_result_t result = ISC_R_SUCCESS; + + REQUIRE(VALID_NM(mgr)); + REQUIRE(local != NULL); + REQUIRE(peer != NULL); + + nsock = isc_mem_get(mgr->mctx, sizeof(*nsock)); + isc__nmsocket_init(nsock, mgr, isc_nm_tcpsocket, local); + nsock->extrahandlesize = extrahandlesize; + nsock->result = ISC_R_SUCCESS; + + req = isc__nm_uvreq_get(mgr, nsock); + req->cb.connect = cb; + req->cbarg = cbarg; + req->peer = peer->addr; + req->local = local->addr; + + ievent = isc__nm_get_ievent(mgr, netievent_tcpconnect); + ievent->sock = nsock; + ievent->req = req; + + /* + * Async callbacks can dereference the socket in the meantime, + * we need to hold an additional reference to it. + */ + isc__nmsocket_attach(nsock, &tmp); + + if (isc__nm_in_netthread()) { + nsock->tid = isc_nm_tid(); + isc__nm_async_tcpconnect(&mgr->workers[nsock->tid], + (isc__netievent_t *)ievent); + isc__nm_put_ievent(mgr, ievent); + } else { + nsock->tid = isc_random_uniform(mgr->nworkers); + isc__nm_enqueue_ievent(&mgr->workers[nsock->tid], + (isc__netievent_t *)ievent); + + LOCK(&nsock->lock); + while (!atomic_load(&nsock->connected) && + !atomic_load(&nsock->connect_error)) { + WAIT(&nsock->cond, &nsock->lock); + } + UNLOCK(&nsock->lock); + } + + if (nsock->result != ISC_R_SUCCESS) { + result = nsock->result; + isc__nmsocket_detach(&nsock); + } + + isc__nmsocket_detach(&tmp); + + return (result); +} + +isc_result_t +isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface, + isc_nm_accept_cb_t accept_cb, void *accept_cbarg, + size_t extrahandlesize, int backlog, isc_quota_t *quota, + isc_nmsocket_t **sockp) { + isc_nmsocket_t *nsock = NULL; + isc__netievent_tcplisten_t *ievent = NULL; + + REQUIRE(VALID_NM(mgr)); + + nsock = isc_mem_get(mgr->mctx, sizeof(*nsock)); + isc__nmsocket_init(nsock, mgr, isc_nm_tcplistener, iface); + nsock->accept_cb = accept_cb; + nsock->accept_cbarg = accept_cbarg; + nsock->extrahandlesize = extrahandlesize; + nsock->backlog = backlog; + nsock->result = ISC_R_SUCCESS; + if (quota != NULL) { + /* + * We don't attach to quota, just assign - to avoid + * increasing quota unnecessarily. + */ + nsock->pquota = quota; + } + isc_quota_cb_init(&nsock->quotacb, quota_accept_cb, nsock); + + ievent = isc__nm_get_ievent(mgr, netievent_tcplisten); + ievent->sock = nsock; + if (isc__nm_in_netthread()) { + nsock->tid = isc_nm_tid(); + isc__nm_async_tcplisten(&mgr->workers[nsock->tid], + (isc__netievent_t *)ievent); + isc__nm_put_ievent(mgr, ievent); + } else { + nsock->tid = isc_random_uniform(mgr->nworkers); + isc__nm_enqueue_ievent(&mgr->workers[nsock->tid], + (isc__netievent_t *)ievent); + + LOCK(&nsock->lock); + while (!atomic_load(&nsock->listening) && + !atomic_load(&nsock->listen_error)) { + WAIT(&nsock->cond, &nsock->lock); + } + UNLOCK(&nsock->lock); + } + + if (nsock->result == ISC_R_SUCCESS) { + *sockp = nsock; + return (ISC_R_SUCCESS); + } else { + isc_result_t result = nsock->result; + isc__nmsocket_detach(&nsock); + return (result); + } +} + +/* + * For multi-threaded TCP listening, we create a single socket, + * bind to it, and start listening. On an incoming connection we accept + * it, and then pass the accepted socket using the uv_export/uv_import + * mechanism to a child thread. + */ +void +isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcplisten_t *ievent = (isc__netievent_tcplisten_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + struct sockaddr_storage sname; + int r, flags = 0, snamelen = sizeof(sname); + sa_family_t sa_family; + uv_os_sock_t fd; + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(sock->type == isc_nm_tcplistener); + + r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp); + if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); + /* The socket was never opened, so no need for uv_close() */ + atomic_store(&sock->closed, true); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->listen_error, true); + goto done; + } + + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]); + + sa_family = sock->iface->addr.type.sa.sa_family; + if (sa_family == AF_INET6) { + flags = UV_TCP_IPV6ONLY; + } + + r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, + flags); + if (r == UV_EADDRNOTAVAIL && + uv_fileno(&sock->uv_handle.handle, (uv_os_fd_t *)&fd) == 0 && + isc__nm_socket_freebind(fd, sa_family) == ISC_R_SUCCESS) + { + /* + * Retry binding with IP_FREEBIND (or equivalent option) if the + * address is not available. This helps with IPv6 tentative + * addresses which are reported by the route socket, although + * named is not yet able to properly bind to them. + */ + r = uv_tcp_bind(&sock->uv_handle.tcp, + &sock->iface->addr.type.sa, flags); + } + + if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]); + uv_close(&sock->uv_handle.handle, tcp_close_cb); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->listen_error, true); + goto done; + } + + /* + * By doing this now, we can find out immediately whether bind() + * failed, and quit if so. (uv_bind() uses a delayed error, + * initially returning success even if bind() fails, and this + * could cause a deadlock later if we didn't check first.) + */ + r = uv_tcp_getsockname(&sock->uv_handle.tcp, (struct sockaddr *)&sname, + &snamelen); + if (r != 0) { + uv_close(&sock->uv_handle.handle, tcp_close_cb); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->listen_error, true); + goto done; + } + + /* + * The callback will run in the same thread uv_listen() was called + * from, so a race with tcp_connection_cb() isn't possible. + */ + r = uv_listen((uv_stream_t *)&sock->uv_handle.tcp, sock->backlog, + tcp_connection_cb); + if (r != 0) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "uv_listen failed: %s", + isc_result_totext(isc__nm_uverr2result(r))); + uv_close(&sock->uv_handle.handle, tcp_close_cb); + sock->result = isc__nm_uverr2result(r); + atomic_store(&sock->listen_error, true); + goto done; + } + + uv_handle_set_data(&sock->uv_handle.handle, sock); + + atomic_store(&sock->listening, true); + +done: + LOCK(&sock->lock); + SIGNAL(&sock->cond); + UNLOCK(&sock->lock); + return; +} + +static void +tcp_connection_cb(uv_stream_t *server, int status) { + isc_nmsocket_t *psock = uv_handle_get_data((uv_handle_t *)server); + isc_result_t result; + + UNUSED(status); + + result = accept_connection(psock, NULL); + if (result != ISC_R_SUCCESS && result != ISC_R_NOCONN) { + if ((result != ISC_R_QUOTA && result != ISC_R_SOFTQUOTA) || + can_log_tcp_quota()) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "TCP connection failed: %s", + isc_result_totext(result)); + } + } +} + +void +isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpchildaccept_t *ievent = + (isc__netievent_tcpchildaccept_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + isc_nmhandle_t *handle; + isc_result_t result; + struct sockaddr_storage ss; + isc_sockaddr_t local; + int r; + isc_nm_accept_cb_t accept_cb; + void *accept_cbarg; + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(sock->tid == isc_nm_tid()); + + sock->quota = ievent->quota; + ievent->quota = NULL; + + worker = &sock->mgr->workers[isc_nm_tid()]; + uv_tcp_init(&worker->loop, &sock->uv_handle.tcp); + + r = isc_uv_import(&sock->uv_handle.stream, &ievent->streaminfo); + if (r != 0) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "uv_import failed: %s", + isc_result_totext(isc__nm_uverr2result(r))); + result = isc__nm_uverr2result(r); + goto error; + } + + r = uv_tcp_getpeername(&sock->uv_handle.tcp, (struct sockaddr *)&ss, + &(int){ sizeof(ss) }); + if (r != 0) { + result = isc__nm_uverr2result(r); + goto error; + } + + result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss); + if (result != ISC_R_SUCCESS) { + goto error; + } + + r = uv_tcp_getsockname(&sock->uv_handle.tcp, (struct sockaddr *)&ss, + &(int){ sizeof(ss) }); + if (r != 0) { + result = isc__nm_uverr2result(r); + goto error; + } + + result = isc_sockaddr_fromsockaddr(&local, (struct sockaddr *)&ss); + if (result != ISC_R_SUCCESS) { + goto error; + } + + handle = isc__nmhandle_get(sock, NULL, &local); + + INSIST(sock->accept_cb != NULL); + accept_cb = sock->accept_cb; + accept_cbarg = sock->accept_cbarg; + + sock->read_timeout = sock->mgr->init; + accept_cb(handle, ISC_R_SUCCESS, accept_cbarg); + + /* + * sock is now attached to the handle. + */ + isc__nmsocket_detach(&sock); + + /* + * The accept callback should have attached to the handle. + * If it didn't, the socket will be closed now. + */ + isc_nmhandle_detach(&handle); + return; + +error: + /* + * Detach the quota early to make room for other connections; + * otherwise it'd be detached later asynchronously, and clog + * the quota unnecessarily. + */ + if (sock->quota != NULL) { + isc_quota_detach(&sock->quota); + } + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR, + ISC_LOG_ERROR, "Accepting TCP connection failed: %s", + isc_result_totext(result)); + + /* + * Detach the socket properly to make sure uv_close() is called. + */ + isc__nmsocket_detach(&sock); +} + +void +isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcplistener); + + isc__netievent_tcpstop_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpstop); + isc__nmsocket_attach(sock, &ievent->sock); + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); +} + +void +isc__nm_async_tcpstop(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpstop_t *ievent = (isc__netievent_tcpstop_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + + UNUSED(worker); + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcplistener); + + /* + * If network manager is interlocked, re-enqueue the event for later. + */ + if (!isc__nm_acquire_interlocked(sock->mgr)) { + isc__netievent_tcpstop_t *event = NULL; + + event = isc__nm_get_ievent(sock->mgr, netievent_tcpstop); + event->sock = sock; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)event); + } else { + uv_close((uv_handle_t *)&sock->uv_handle.tcp, + tcp_listenclose_cb); + isc__nm_drop_interlocked(sock->mgr); + } +} + +/* + * This callback is used for closing listening sockets. + */ +static void +tcp_listenclose_cb(uv_handle_t *handle) { + isc_nmsocket_t *sock = uv_handle_get_data(handle); + + LOCK(&sock->lock); + atomic_store(&sock->closed, true); + atomic_store(&sock->listening, false); + sock->pquota = NULL; + UNLOCK(&sock->lock); + + isc__nmsocket_detach(&sock); +} + +static void +readtimeout_cb(uv_timer_t *handle) { + isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle); + isc_nm_recv_cb_t cb; + void *cbarg; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + + /* + * Socket is actively processing something, so restart the timer + * and return. + */ + if (atomic_load(&sock->processing)) { + uv_timer_start(handle, readtimeout_cb, sock->read_timeout, 0); + return; + } + + /* + * Timeout; stop reading and process whatever we have. + */ + uv_read_stop(&sock->uv_handle.stream); + if (sock->quota) { + isc_quota_detach(&sock->quota); + } + + cb = sock->recv_cb; + cbarg = sock->recv_cbarg; + isc__nmsocket_clearcb(sock); + + if (cb != NULL) { + cb(sock->statichandle, ISC_R_TIMEDOUT, NULL, cbarg); + } +} + +isc_result_t +isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { + isc_nmsocket_t *sock = NULL; + isc__netievent_startread_t *ievent = NULL; + + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + sock = handle->sock; + + REQUIRE(sock->tid == isc_nm_tid()); + sock->recv_cb = cb; + sock->recv_cbarg = cbarg; + + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread); + ievent->sock = sock; + + if (sock->tid == isc_nm_tid()) { + isc__nm_async_tcp_startread(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + isc__nm_put_ievent(sock->mgr, ievent); + } else { + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } + + return (ISC_R_SUCCESS); +} + +/*%< + * Allocator for TCP read operations. Limited to size 2^16. + * + * Note this doesn't actually allocate anything, it just assigns the + * worker's receive buffer to a socket, and marks it as "in use". + */ +static void +tcp_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; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpsocket); + REQUIRE(isc__nm_in_netthread()); + REQUIRE(size <= 65536); + + worker = &sock->mgr->workers[sock->tid]; + INSIST(!worker->recvbuf_inuse); + + buf->base = worker->recvbuf; + buf->len = size; + worker->recvbuf_inuse = true; +} + +void +isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_startread_t *ievent = (isc__netievent_startread_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + int r; + + REQUIRE(worker->id == isc_nm_tid()); + if (sock->read_timeout != 0) { + if (!sock->timer_initialized) { + uv_timer_init(&worker->loop, &sock->timer); + uv_handle_set_data((uv_handle_t *)&sock->timer, sock); + sock->timer_initialized = true; + } + uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout, + 0); + } + + r = uv_read_start(&sock->uv_handle.stream, tcp_alloc_cb, read_cb); + if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]); + } +} + +isc_result_t +isc__nm_tcp_pauseread(isc_nmsocket_t *sock) { + isc__netievent_pauseread_t *ievent = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + + if (atomic_load(&sock->readpaused)) { + return (ISC_R_SUCCESS); + } + + atomic_store(&sock->readpaused, true); + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcppauseread); + ievent->sock = sock; + + if (sock->tid == isc_nm_tid()) { + isc__nm_async_tcp_pauseread(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + isc__nm_put_ievent(sock->mgr, ievent); + } else { + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } + + return (ISC_R_SUCCESS); +} + +void +isc__nm_async_tcp_pauseread(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_pauseread_t *ievent = (isc__netievent_pauseread_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(worker->id == isc_nm_tid()); + + if (sock->timer_initialized) { + uv_timer_stop(&sock->timer); + } + uv_read_stop(&sock->uv_handle.stream); +} + +isc_result_t +isc__nm_tcp_resumeread(isc_nmsocket_t *sock) { + isc__netievent_startread_t *ievent = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + + if (sock->recv_cb == NULL) { + return (ISC_R_CANCELED); + } + + if (!atomic_load(&sock->readpaused)) { + return (ISC_R_SUCCESS); + } + + atomic_store(&sock->readpaused, false); + + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread); + ievent->sock = sock; + + if (sock->tid == isc_nm_tid()) { + isc__nm_async_tcp_startread(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + isc__nm_put_ievent(sock->mgr, ievent); + } else { + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } + + return (ISC_R_SUCCESS); +} + +static void +read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { + isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream); + isc_nm_recv_cb_t cb; + void *cbarg; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + REQUIRE(buf != NULL); + + cb = sock->recv_cb; + cbarg = sock->recv_cbarg; + + if (nread >= 0) { + isc_region_t region = { .base = (unsigned char *)buf->base, + .length = nread }; + + if (cb != NULL) { + cb(sock->statichandle, ISC_R_SUCCESS, ®ion, cbarg); + } + + sock->read_timeout = (atomic_load(&sock->keepalive) + ? sock->mgr->keepalive + : sock->mgr->idle); + + if (sock->timer_initialized && sock->read_timeout != 0) { + /* The timer will be updated */ + uv_timer_start(&sock->timer, readtimeout_cb, + sock->read_timeout, 0); + } + + isc__nm_free_uvbuf(sock, buf); + return; + } + + isc__nm_free_uvbuf(sock, buf); + + /* + * This might happen if the inner socket is closing. It means that + * it's detached, so the socket will be closed. + */ + if (cb != NULL) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]); + isc__nmsocket_clearcb(sock); + cb(sock->statichandle, ISC_R_EOF, NULL, cbarg); + } + + /* + * We don't need to clean up now; the socket will be closed and + * resources and quota reclaimed when handle is freed in + * isc__nm_tcp_close(). + */ +} + +static void +quota_accept_cb(isc_quota_t *quota, void *sock0) { + isc_nmsocket_t *sock = (isc_nmsocket_t *)sock0; + isc__netievent_tcpaccept_t *ievent = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + + /* + * Create a tcpaccept event and pass it using the async channel. + */ + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpaccept); + ievent->sock = sock; + ievent->quota = quota; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); +} + +/* + * This is called after we get a quota_accept_cb() callback. + */ +void +isc__nm_async_tcpaccept(isc__networker_t *worker, isc__netievent_t *ev0) { + isc_result_t result; + isc__netievent_tcpaccept_t *ievent = (isc__netievent_tcpaccept_t *)ev0; + + REQUIRE(worker->id == ievent->sock->tid); + + result = accept_connection(ievent->sock, ievent->quota); + if (result != ISC_R_SUCCESS && result != ISC_R_NOCONN) { + if ((result != ISC_R_QUOTA && result != ISC_R_SOFTQUOTA) || + can_log_tcp_quota()) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "TCP connection failed: %s", + isc_result_totext(result)); + } + } + + /* + * The socket was attached just before we called isc_quota_attach_cb(). + */ + isc__nmsocket_detach(&ievent->sock); +} + +/* + * Close callback for uv_tcp_t strutures created in accept_connection(). + */ +static void +free_uvtcpt(uv_handle_t *uvs) { + isc_mem_t *mctx = (isc_mem_t *)uv_handle_get_data(uvs); + isc_mem_putanddetach(&mctx, uvs, sizeof(uv_tcp_t)); +} + +static isc_result_t +accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) { + isc_result_t result; + isc__netievent_tcpchildaccept_t *event = NULL; + isc__networker_t *worker = NULL; + uv_tcp_t *uvstream = NULL; + isc_mem_t *mctx = NULL; + int r, w; + + REQUIRE(VALID_NMSOCK(ssock)); + + if (!atomic_load_relaxed(&ssock->active) || + atomic_load_relaxed(&ssock->mgr->closing)) + { + /* We're closing, bail */ + if (quota != NULL) { + isc_quota_detach("a); + } + return (ISC_R_CANCELED); + } + + /* We can be called directly or as a callback from quota */ + if (ssock->pquota != NULL && quota == NULL) { + /* + * We need to attach to ssock, because it might be queued + * waiting for a TCP quota slot. If so, then we'll detach it + * later when the connection is accepted. (XXX: This may be + * suboptimal, it might be better not to attach unless + * we need to - but we risk a race then.) + */ + isc_nmsocket_t *tsock = NULL; + isc__nmsocket_attach(ssock, &tsock); + result = isc_quota_attach_cb(ssock->pquota, "a, + &ssock->quotacb); + if (result == ISC_R_QUOTA) { + isc__nm_incstats(ssock->mgr, + ssock->statsindex[STATID_ACCEPTFAIL]); + return (result); + } + + /* + * We're under quota, so there's no need to wait; + * Detach the socket. + */ + isc__nmsocket_detach(&tsock); + } + + isc__nm_incstats(ssock->mgr, ssock->statsindex[STATID_ACCEPT]); + + worker = &ssock->mgr->workers[isc_nm_tid()]; + uvstream = isc_mem_get(ssock->mgr->mctx, sizeof(uv_tcp_t)); + + isc_mem_attach(ssock->mgr->mctx, &mctx); + uv_handle_set_data((uv_handle_t *)uvstream, mctx); + mctx = NULL; /* Detached later in free_uvtcpt() */ + + uv_tcp_init(&worker->loop, uvstream); + + r = uv_accept(&ssock->uv_handle.stream, (uv_stream_t *)uvstream); + if (r != 0) { + result = isc__nm_uverr2result(r); + uv_close((uv_handle_t *)uvstream, free_uvtcpt); + isc_quota_detach("a); + return (result); + } + + /* We have an accepted TCP socket, pass it to a random worker */ + w = isc_random_uniform(ssock->mgr->nworkers); + event = isc__nm_get_ievent(ssock->mgr, netievent_tcpchildaccept); + + /* Duplicate the server socket */ + isc_nmsocket_t *csock = isc_mem_get(ssock->mgr->mctx, + sizeof(isc_nmsocket_t)); + isc__nmsocket_init(csock, ssock->mgr, isc_nm_tcpsocket, ssock->iface); + csock->tid = w; + csock->extrahandlesize = ssock->extrahandlesize; + isc__nmsocket_attach(ssock, &csock->server); + csock->accept_cb = ssock->accept_cb; + csock->accept_cbarg = ssock->accept_cbarg; + + event->sock = csock; + event->quota = quota; + + r = isc_uv_export((uv_stream_t *)uvstream, &event->streaminfo); + RUNTIME_CHECK(r == 0); + + uv_close((uv_handle_t *)uvstream, free_uvtcpt); + + if (w == isc_nm_tid()) { + isc__nm_async_tcpchildaccept(&ssock->mgr->workers[w], + (isc__netievent_t *)event); + isc__nm_put_ievent(ssock->mgr, event); + } else { + isc__nm_enqueue_ievent(&ssock->mgr->workers[w], + (isc__netievent_t *)event); + } + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg) { + isc_nmsocket_t *sock = handle->sock; + isc__netievent_tcpsend_t *ievent = NULL; + isc__nm_uvreq_t *uvreq = NULL; + + REQUIRE(sock->type == isc_nm_tcpsocket); + + uvreq = isc__nm_uvreq_get(sock->mgr, sock); + uvreq->uvbuf.base = (char *)region->base; + uvreq->uvbuf.len = region->length; + isc_nmhandle_attach(handle, &uvreq->handle); + uvreq->cb.send = cb; + uvreq->cbarg = cbarg; + + if (sock->tid == isc_nm_tid()) { + /* + * If we're in the same thread as the socket we can send the + * data directly + */ + return (tcp_send_direct(sock, uvreq)); + } else { + /* + * We need to create an event and pass it using async channel + */ + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpsend); + ievent->sock = sock; + ievent->req = uvreq; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + return (ISC_R_SUCCESS); + } + + return (ISC_R_UNEXPECTED); +} + +static void +tcp_send_cb(uv_write_t *req, int status) { + isc_result_t result = ISC_R_SUCCESS; + isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data; + isc_nmsocket_t *sock = NULL; + + REQUIRE(VALID_UVREQ(uvreq)); + REQUIRE(VALID_NMHANDLE(uvreq->handle)); + + if (status < 0) { + result = isc__nm_uverr2result(status); + isc__nm_incstats(uvreq->sock->mgr, + uvreq->sock->statsindex[STATID_SENDFAIL]); + } + + uvreq->cb.send(uvreq->handle, result, uvreq->cbarg); + + sock = uvreq->handle->sock; + isc__nm_uvreq_put(&uvreq, sock); +} + +/* + * Handle 'tcpsend' async event - send a packet on the socket + */ +void +isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0) { + isc_result_t result; + isc__netievent_tcpsend_t *ievent = (isc__netievent_tcpsend_t *)ev0; + + REQUIRE(worker->id == ievent->sock->tid); + + if (!atomic_load(&ievent->sock->active)) { + return; + } + + result = tcp_send_direct(ievent->sock, ievent->req); + if (result != ISC_R_SUCCESS) { + ievent->req->cb.send(ievent->req->handle, result, + ievent->req->cbarg); + isc__nm_uvreq_put(&ievent->req, ievent->req->handle->sock); + } +} + +static isc_result_t +tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { + int r; + + REQUIRE(sock->tid == isc_nm_tid()); + REQUIRE(sock->type == isc_nm_tcpsocket); + r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf, + 1, tcp_send_cb); + if (r < 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_SENDFAIL]); + req->cb.send(NULL, isc__nm_uverr2result(r), req->cbarg); + isc__nm_uvreq_put(&req, sock); + return (isc__nm_uverr2result(r)); + } + + return (ISC_R_SUCCESS); +} + +static void +tcp_close_cb(uv_handle_t *uvhandle) { + isc_nmsocket_t *sock = uv_handle_get_data(uvhandle); + + REQUIRE(VALID_NMSOCK(sock)); + + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CLOSE]); + atomic_store(&sock->closed, true); + atomic_store(&sock->connected, false); + isc__nmsocket_prep_destroy(sock); +} + +static void +timer_close_cb(uv_handle_t *uvhandle) { + isc_nmsocket_t *sock = uv_handle_get_data(uvhandle); + + REQUIRE(VALID_NMSOCK(sock)); + + if (sock->server != NULL) { + isc__nmsocket_detach(&sock->server); + } + uv_close(&sock->uv_handle.handle, tcp_close_cb); +} + +static void +tcp_close_direct(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + REQUIRE(sock->type == isc_nm_tcpsocket); + if (sock->quota != NULL) { + isc_quota_detach(&sock->quota); + } + if (sock->timer_initialized) { + sock->timer_initialized = false; + uv_timer_stop(&sock->timer); + uv_close((uv_handle_t *)&sock->timer, timer_close_cb); + } else { + if (sock->server != NULL) { + isc__nmsocket_detach(&sock->server); + } + uv_close(&sock->uv_handle.handle, tcp_close_cb); + } +} + +void +isc__nm_tcp_close(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpsocket); + + if (sock->tid == isc_nm_tid()) { + tcp_close_direct(sock); + } else { + /* + * We need to create an event and pass it using async channel + */ + isc__netievent_tcpclose_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpclose); + + ievent->sock = sock; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } +} + +void +isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpclose_t *ievent = (isc__netievent_tcpclose_t *)ev0; + + REQUIRE(worker->id == ievent->sock->tid); + + tcp_close_direct(ievent->sock); +} + +void +isc__nm_tcp_shutdown(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + + if (sock->type == isc_nm_tcpsocket && sock->statichandle != NULL) { + isc_nm_recv_cb_t cb; + void *cbarg; + + cb = sock->recv_cb; + cbarg = sock->recv_cbarg; + isc__nmsocket_clearcb(sock); + + if (cb != NULL) { + cb(sock->statichandle, ISC_R_CANCELED, NULL, cbarg); + } + } +} + +void +isc__nm_tcp_cancelread(isc_nmhandle_t *handle) { + isc_nmsocket_t *sock = NULL; + + REQUIRE(VALID_NMHANDLE(handle)); + + sock = handle->sock; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpsocket); + REQUIRE(sock->tid == isc_nm_tid()); + + if (atomic_load(&sock->client)) { + isc_nm_recv_cb_t cb; + void *cbarg; + + cb = sock->recv_cb; + cbarg = sock->recv_cbarg; + isc__nmsocket_clearcb(sock); + + cb(handle, ISC_R_EOF, NULL, cbarg); + } +} diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c new file mode 100644 index 00000000..283f7766 --- /dev/null +++ b/lib/isc/netmgr/tcpdns.c @@ -0,0 +1,689 @@ +/* + * 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. + */ + +#include <unistd.h> +#include <uv.h> + +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/condition.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/sockaddr.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include "netmgr-int.h" +#include "uv-compat.h" + +#define TCPDNS_CLIENTS_PER_CONN 23 +/*%< + * + * Maximum number of simultaneous handles in flight supported for a single + * connected TCPDNS socket. This value was chosen arbitrarily, and may be + * changed in the future. + */ + +static void +dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *arg); + +static void +resume_processing(void *arg); + +static void +tcpdns_close_direct(isc_nmsocket_t *sock); + +static inline size_t +dnslen(unsigned char *base) { + return ((base[0] << 8) + (base[1])); +} + +/* + * 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); + + if (sock->buf == NULL) { + /* We don't have the buffer at all */ + size_t alloc_len = len < NM_REG_BUF ? NM_REG_BUF : NM_BIG_BUF; + sock->buf = isc_mem_allocate(sock->mgr->mctx, alloc_len); + sock->buf_size = alloc_len; + } else { + /* We have the buffer but it's too small */ + sock->buf = isc_mem_reallocate(sock->mgr->mctx, sock->buf, + NM_BIG_BUF); + sock->buf_size = NM_BIG_BUF; + } +} + +static void +timer_close_cb(uv_handle_t *handle) { + isc_nmsocket_t *sock = (isc_nmsocket_t *)uv_handle_get_data(handle); + + REQUIRE(VALID_NMSOCK(sock)); + + atomic_store(&sock->closed, true); + tcpdns_close_direct(sock); +} + +static void +dnstcp_readtimeout(uv_timer_t *timer) { + isc_nmsocket_t *sock = + (isc_nmsocket_t *)uv_handle_get_data((uv_handle_t *)timer); + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + + /* Close the TCP connection; its closure should fire ours. */ + isc_nmhandle_detach(&sock->outerhandle); +} + +/* + * Accept callback for TCP-DNS connection. + */ +static isc_result_t +dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + isc_nmsocket_t *dnslistensock = (isc_nmsocket_t *)cbarg; + isc_nmsocket_t *dnssock = NULL; + isc_nmhandle_t *readhandle = NULL; + isc_nm_accept_cb_t accept_cb; + void *accept_cbarg; + + REQUIRE(VALID_NMSOCK(dnslistensock)); + REQUIRE(dnslistensock->type == isc_nm_tcpdnslistener); + + if (result != ISC_R_SUCCESS) { + return (result); + } + + accept_cb = dnslistensock->accept_cb; + accept_cbarg = dnslistensock->accept_cbarg; + + if (accept_cb != NULL) { + result = accept_cb(handle, ISC_R_SUCCESS, accept_cbarg); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + /* We need to create a 'wrapper' dnssocket for this connection */ + dnssock = isc_mem_get(handle->sock->mgr->mctx, sizeof(*dnssock)); + isc__nmsocket_init(dnssock, handle->sock->mgr, isc_nm_tcpdnssocket, + handle->sock->iface); + + dnssock->extrahandlesize = dnslistensock->extrahandlesize; + isc__nmsocket_attach(dnslistensock, &dnssock->listener); + + isc__nmsocket_attach(dnssock, &dnssock->self); + + isc_nmhandle_attach(handle, &dnssock->outerhandle); + + dnssock->peer = handle->sock->peer; + dnssock->read_timeout = handle->sock->mgr->init; + dnssock->tid = isc_nm_tid(); + dnssock->closehandle_cb = resume_processing; + + uv_timer_init(&dnssock->mgr->workers[isc_nm_tid()].loop, + &dnssock->timer); + dnssock->timer.data = dnssock; + dnssock->timer_initialized = true; + uv_timer_start(&dnssock->timer, dnstcp_readtimeout, + dnssock->read_timeout, 0); + + /* + * Add a reference to handle to keep it from being freed by + * the caller. It will be detached in dnslisted_readcb() when + * the connection is closed or there is no more data to be read. + */ + isc_nmhandle_attach(handle, &readhandle); + result = isc_nm_read(readhandle, dnslisten_readcb, dnssock); + if (result != ISC_R_SUCCESS) { + isc_nmhandle_detach(&readhandle); + } + isc__nmsocket_detach(&dnssock); + + return (ISC_R_SUCCESS); +} + +/* + * Process a single packet from the incoming buffer. + * + * Return ISC_R_SUCCESS and attach 'handlep' to a handle if something + * was processed; return ISC_R_NOMORE if there isn't a full message + * to be processed. + * + * The caller will need to unreference the handle. + */ +static isc_result_t +processbuffer(isc_nmsocket_t *dnssock, isc_nmhandle_t **handlep) { + size_t len; + + REQUIRE(VALID_NMSOCK(dnssock)); + REQUIRE(dnssock->tid == isc_nm_tid()); + REQUIRE(handlep != NULL && *handlep == NULL); + + /* + * If we don't even have the length yet, we can't do + * anything. + */ + if (dnssock->buf_len < 2) { + return (ISC_R_NOMORE); + } + + /* + * Process the first packet from the buffer, leaving + * the rest (if any) for later. + */ + len = dnslen(dnssock->buf); + if (len <= dnssock->buf_len - 2) { + isc_nmhandle_t *dnshandle = NULL; + isc_nmsocket_t *listener = NULL; + isc_nm_recv_cb_t cb = NULL; + void *cbarg = NULL; + + if (atomic_load(&dnssock->client) && + dnssock->statichandle != NULL) { + isc_nmhandle_attach(dnssock->statichandle, &dnshandle); + } else { + dnshandle = isc__nmhandle_get(dnssock, NULL, NULL); + } + + listener = dnssock->listener; + if (listener != NULL) { + cb = listener->recv_cb; + cbarg = listener->recv_cbarg; + } else if (dnssock->recv_cb != NULL) { + cb = dnssock->recv_cb; + cbarg = dnssock->recv_cbarg; + /* + * We need to clear the read callback *before* + * calling it, because it might make another + * call to isc_nm_read() and set up a new callback. + */ + isc__nmsocket_clearcb(dnssock); + } + + if (cb != NULL) { + cb(dnshandle, ISC_R_SUCCESS, + &(isc_region_t){ .base = dnssock->buf + 2, + .length = len }, + cbarg); + } + + len += 2; + dnssock->buf_len -= len; + if (len > 0) { + memmove(dnssock->buf, dnssock->buf + len, + dnssock->buf_len); + } + + *handlep = dnshandle; + return (ISC_R_SUCCESS); + } + + return (ISC_R_NOMORE); +} + +/* + * We've got a read on our underlying socket. Check whether + * we have a complete DNS packet and, if so, call the callback. + */ +static void +dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *arg) { + isc_nmsocket_t *dnssock = (isc_nmsocket_t *)arg; + unsigned char *base = NULL; + bool done = false; + size_t len; + + REQUIRE(VALID_NMSOCK(dnssock)); + REQUIRE(dnssock->tid == isc_nm_tid()); + REQUIRE(VALID_NMHANDLE(handle)); + + if (region == NULL || eresult != ISC_R_SUCCESS) { + /* Connection closed */ + dnssock->result = eresult; + if (dnssock->self != NULL) { + isc__nmsocket_detach(&dnssock->self); + } + isc__nmsocket_clearcb(dnssock); + if (dnssock->outerhandle != NULL) { + isc_nmhandle_detach(&dnssock->outerhandle); + } + isc_nmhandle_detach(&handle); + return; + } + + base = region->base; + len = region->length; + + if (dnssock->buf_len + len > dnssock->buf_size) { + alloc_dnsbuf(dnssock, dnssock->buf_len + len); + } + memmove(dnssock->buf + dnssock->buf_len, base, len); + dnssock->buf_len += len; + + dnssock->read_timeout = (atomic_load(&dnssock->keepalive) + ? dnssock->mgr->keepalive + : dnssock->mgr->idle); + + do { + isc_result_t result; + isc_nmhandle_t *dnshandle = NULL; + + result = processbuffer(dnssock, &dnshandle); + if (result != ISC_R_SUCCESS) { + /* + * There wasn't anything in the buffer to process. + */ + return; + } + + /* + * We have a packet: stop timeout timers + */ + atomic_store(&dnssock->outerhandle->sock->processing, true); + if (dnssock->timer_initialized) { + uv_timer_stop(&dnssock->timer); + } + + if (atomic_load(&dnssock->sequential) || + dnssock->recv_cb == NULL) { + /* + * There are two reasons we might want to pause here: + * - We're in sequential mode and we've received + * a whole packet, so we're done until it's been + * processed; or + * - We no longer have a read callback. + */ + isc_nm_pauseread(dnssock->outerhandle); + done = true; + } else { + /* + * We're pipelining, so we now resume processing + * packets until the clients-per-connection limit + * is reached (as determined by the number of + * active handles on the socket). When the limit + * is reached, pause reading. + */ + if (atomic_load(&dnssock->ah) >= + TCPDNS_CLIENTS_PER_CONN) { + isc_nm_pauseread(dnssock->outerhandle); + done = true; + } + } + + isc_nmhandle_detach(&dnshandle); + } while (!done); +} + +/* + * isc_nm_listentcpdns listens for connections and accepts + * them immediately, then calls the cb for each incoming DNS packet + * (with 2-byte length stripped) - just like for UDP packet. + */ +isc_result_t +isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, + void *cbarg, isc_nm_accept_cb_t accept_cb, + void *accept_cbarg, size_t extrahandlesize, int backlog, + isc_quota_t *quota, isc_nmsocket_t **sockp) { + isc_nmsocket_t *dnslistensock = isc_mem_get(mgr->mctx, + sizeof(*dnslistensock)); + isc_result_t result; + + REQUIRE(VALID_NM(mgr)); + + isc__nmsocket_init(dnslistensock, mgr, isc_nm_tcpdnslistener, iface); + dnslistensock->recv_cb = cb; + dnslistensock->recv_cbarg = cbarg; + dnslistensock->accept_cb = accept_cb; + dnslistensock->accept_cbarg = accept_cbarg; + dnslistensock->extrahandlesize = extrahandlesize; + + /* + * dnslistensock will be a DNS 'wrapper' around a connected + * stream. We set dnslistensock->outer to a socket listening + * for a TCP connection. + */ + result = isc_nm_listentcp(mgr, iface, dnslisten_acceptcb, dnslistensock, + extrahandlesize, backlog, quota, + &dnslistensock->outer); + if (result == ISC_R_SUCCESS) { + atomic_store(&dnslistensock->listening, true); + *sockp = dnslistensock; + return (ISC_R_SUCCESS); + } else { + atomic_store(&dnslistensock->closed, true); + isc__nmsocket_detach(&dnslistensock); + return (result); + } +} + +void +isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpstop_t *ievent = (isc__netievent_tcpdnsstop_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + + UNUSED(worker); + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpdnslistener); + REQUIRE(sock->tid == isc_nm_tid()); + + atomic_store(&sock->listening, false); + atomic_store(&sock->closed, true); + + isc__nmsocket_clearcb(sock); + + if (sock->outer != NULL) { + isc__nm_tcp_stoplistening(sock->outer); + isc__nmsocket_detach(&sock->outer); + } + + isc__nmsocket_detach(&sock); +} + +void +isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpdnslistener); + + isc__netievent_tcpdnsstop_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpdnsstop); + isc__nmsocket_attach(sock, &ievent->sock); + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); +} + +void +isc_nm_tcpdns_sequential(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + if (handle->sock->type != isc_nm_tcpdnssocket || + handle->sock->outerhandle == NULL) + { + return; + } + + /* + * We don't want pipelining on this connection. That means + * that we need to pause after reading each request, and + * resume only after the request has been processed. This + * is done in resume_processing(), which is the socket's + * closehandle_cb callback, called whenever a handle + * is released. + */ + isc_nm_pauseread(handle->sock->outerhandle); + atomic_store(&handle->sock->sequential, true); +} + +void +isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + if (handle->sock->type != isc_nm_tcpdnssocket || + handle->sock->outerhandle == NULL) + { + return; + } + + atomic_store(&handle->sock->keepalive, true); + atomic_store(&handle->sock->outerhandle->sock->keepalive, true); +} + +static void +resume_processing(void *arg) { + isc_nmsocket_t *sock = (isc_nmsocket_t *)arg; + isc_result_t result; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + + if (sock->type != isc_nm_tcpdnssocket || sock->outerhandle == NULL) { + return; + } + + if (atomic_load(&sock->ah) == 0) { + /* Nothing is active; sockets can timeout now */ + atomic_store(&sock->outerhandle->sock->processing, false); + if (sock->timer_initialized) { + uv_timer_start(&sock->timer, dnstcp_readtimeout, + sock->read_timeout, 0); + } + } + + /* + * For sequential sockets: Process what's in the buffer, or + * if there aren't any messages buffered, resume reading. + */ + if (atomic_load(&sock->sequential)) { + isc_nmhandle_t *handle = NULL; + + result = processbuffer(sock, &handle); + if (result == ISC_R_SUCCESS) { + atomic_store(&sock->outerhandle->sock->processing, + true); + if (sock->timer_initialized) { + uv_timer_stop(&sock->timer); + } + isc_nmhandle_detach(&handle); + } else if (sock->outerhandle != NULL) { + result = isc_nm_resumeread(sock->outerhandle); + if (result != ISC_R_SUCCESS) { + isc_nmhandle_detach(&sock->outerhandle); + } + } + + return; + } + + /* + * For pipelined sockets: If we're under the clients-per-connection + * limit, resume processing until we reach the limit again. + */ + do { + isc_nmhandle_t *dnshandle = NULL; + + result = processbuffer(sock, &dnshandle); + if (result != ISC_R_SUCCESS) { + /* + * Nothing in the buffer; resume reading. + */ + if (sock->outerhandle != NULL) { + isc_nm_resumeread(sock->outerhandle); + } + + break; + } + + if (sock->timer_initialized) { + uv_timer_stop(&sock->timer); + } + atomic_store(&sock->outerhandle->sock->processing, true); + isc_nmhandle_detach(&dnshandle); + } while (atomic_load(&sock->ah) < TCPDNS_CLIENTS_PER_CONN); +} + +static void +tcpdnssend_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + isc__nm_uvreq_t *req = (isc__nm_uvreq_t *)cbarg; + + UNUSED(handle); + + req->cb.send(req->handle, result, req->cbarg); + isc_mem_put(req->sock->mgr->mctx, req->uvbuf.base, req->uvbuf.len); + isc__nm_uvreq_put(&req, req->handle->sock); + isc_nmhandle_detach(&handle); +} + +void +isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) { + isc_result_t result; + isc__netievent_tcpdnssend_t *ievent = + (isc__netievent_tcpdnssend_t *)ev0; + isc__nm_uvreq_t *req = ievent->req; + isc_nmsocket_t *sock = ievent->sock; + + REQUIRE(worker->id == sock->tid); + REQUIRE(sock->tid == isc_nm_tid()); + + result = ISC_R_NOTCONNECTED; + if (atomic_load(&sock->active) && sock->outerhandle != NULL) { + isc_nmhandle_t *sendhandle = NULL; + isc_region_t r; + + r.base = (unsigned char *)req->uvbuf.base; + r.length = req->uvbuf.len; + isc_nmhandle_attach(sock->outerhandle, &sendhandle); + result = isc_nm_send(sendhandle, &r, tcpdnssend_cb, req); + if (result != ISC_R_SUCCESS) { + isc_nmhandle_detach(&sendhandle); + } + } + + if (result != ISC_R_SUCCESS) { + req->cb.send(req->handle, result, req->cbarg); + isc_mem_put(sock->mgr->mctx, req->uvbuf.base, req->uvbuf.len); + isc__nm_uvreq_put(&req, sock); + } +} + +/* + * isc__nm_tcp_send sends buf to a peer on a socket. + */ +isc_result_t +isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region, + isc_nm_cb_t cb, void *cbarg) { + isc__nm_uvreq_t *uvreq = NULL; + + REQUIRE(VALID_NMHANDLE(handle)); + + isc_nmsocket_t *sock = handle->sock; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpdnssocket); + + uvreq = isc__nm_uvreq_get(sock->mgr, sock); + isc_nmhandle_attach(handle, &uvreq->handle); + uvreq->cb.send = cb; + uvreq->cbarg = cbarg; + + uvreq->uvbuf.base = isc_mem_get(sock->mgr->mctx, region->length + 2); + uvreq->uvbuf.len = region->length + 2; + *(uint16_t *)uvreq->uvbuf.base = htons(region->length); + memmove(uvreq->uvbuf.base + 2, region->base, region->length); + + if (sock->tid == isc_nm_tid()) { + isc_result_t result; + isc_nmhandle_t *sendhandle = NULL; + isc_region_t r; + + r.base = (unsigned char *)uvreq->uvbuf.base; + r.length = uvreq->uvbuf.len; + + isc_nmhandle_attach(sock->outerhandle, &sendhandle); + result = isc_nm_send(sock->outerhandle, &r, tcpdnssend_cb, + uvreq); + if (result != ISC_R_SUCCESS) { + isc_nmhandle_detach(&sendhandle); + } + return (result); + } else { + isc__netievent_tcpdnssend_t *ievent = NULL; + + ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpdnssend); + ievent->req = uvreq; + ievent->sock = sock; + + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + + return (ISC_R_SUCCESS); + } + + return (ISC_R_UNEXPECTED); +} + +static void +tcpdns_close_direct(isc_nmsocket_t *sock) { + REQUIRE(sock->tid == isc_nm_tid()); + + /* We don't need atomics here, it's all in single network thread */ + if (sock->self != NULL) { + isc__nmsocket_detach(&sock->self); + } else if (sock->timer_initialized) { + /* + * We need to fire the timer callback to clean it up, + * it will then call us again (via detach) so that we + * can finally close the socket. + */ + sock->timer_initialized = false; + uv_timer_stop(&sock->timer); + uv_close((uv_handle_t *)&sock->timer, timer_close_cb); + } else { + /* + * At this point we're certain that there are no external + * references, we can close everything. + */ + if (sock->outerhandle != NULL) { + isc__nmsocket_clearcb(sock->outerhandle->sock); + isc_nmhandle_detach(&sock->outerhandle); + } + if (sock->listener != NULL) { + isc__nmsocket_detach(&sock->listener); + } + atomic_store(&sock->closed, true); + isc__nmsocket_prep_destroy(sock); + } +} + +void +isc__nm_tcpdns_close(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpdnssocket); + + if (sock->tid == isc_nm_tid()) { + tcpdns_close_direct(sock); + } else { + isc__netievent_tcpdnsclose_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpdnsclose); + + ievent->sock = sock; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } +} + +void +isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpdnsclose_t *ievent = + (isc__netievent_tcpdnsclose_t *)ev0; + + REQUIRE(worker->id == ievent->sock->tid); + + tcpdns_close_direct(ievent->sock); +} diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c new file mode 100644 index 00000000..fd017fde --- /dev/null +++ b/lib/isc/netmgr/udp.c @@ -0,0 +1,557 @@ +/* + * 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. + */ + +#include <unistd.h> +#include <uv.h> + +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/condition.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/sockaddr.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include "netmgr-int.h" +#include "uv-compat.h" + +static isc_result_t +udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req, + isc_sockaddr_t *peer); + +static void +udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf, + const struct sockaddr *addr, unsigned flags); + +static void +udp_send_cb(uv_udp_send_t *req, int status); + +isc_result_t +isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, + void *cbarg, size_t extrahandlesize, isc_nmsocket_t **sockp) { + isc_nmsocket_t *nsock = NULL; + + REQUIRE(VALID_NM(mgr)); + + /* + * We are creating mgr->nworkers duplicated sockets, one + * socket for each worker thread. + */ + nsock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t)); + isc__nmsocket_init(nsock, mgr, isc_nm_udplistener, iface); + nsock->nchildren = mgr->nworkers; + atomic_init(&nsock->rchildren, mgr->nworkers); + nsock->children = isc_mem_get(mgr->mctx, + mgr->nworkers * sizeof(*nsock)); + memset(nsock->children, 0, mgr->nworkers * sizeof(*nsock)); + + INSIST(nsock->recv_cb == NULL && nsock->recv_cbarg == NULL); + nsock->recv_cb = cb; + nsock->recv_cbarg = cbarg; + nsock->extrahandlesize = extrahandlesize; + + for (size_t i = 0; i < mgr->nworkers; i++) { + isc_result_t result; + uint16_t family = iface->addr.type.sa.sa_family; + + isc__netievent_udplisten_t *ievent = NULL; + isc_nmsocket_t *csock = &nsock->children[i]; + + isc__nmsocket_init(csock, mgr, isc_nm_udpsocket, iface); + csock->parent = nsock; + csock->tid = i; + csock->extrahandlesize = extrahandlesize; + + INSIST(csock->recv_cb == NULL && csock->recv_cbarg == NULL); + csock->recv_cb = cb; + csock->recv_cbarg = cbarg; + csock->fd = socket(family, SOCK_DGRAM, 0); + RUNTIME_CHECK(csock->fd >= 0); + + result = isc__nm_socket_reuse(csock->fd); + RUNTIME_CHECK(result == ISC_R_SUCCESS || + result == ISC_R_NOTIMPLEMENTED); + + result = isc__nm_socket_reuse_lb(csock->fd); + RUNTIME_CHECK(result == ISC_R_SUCCESS || + result == ISC_R_NOTIMPLEMENTED); + + /* We don't check for the result, because SO_INCOMING_CPU can be + * available without the setter on Linux kernel version 4.4, and + * setting SO_INCOMING_CPU is just an optimization. + */ + (void)isc__nm_socket_incoming_cpu(csock->fd); + + ievent = isc__nm_get_ievent(mgr, netievent_udplisten); + ievent->sock = csock; + isc__nm_enqueue_ievent(&mgr->workers[i], + (isc__netievent_t *)ievent); + } + + *sockp = nsock; + return (ISC_R_SUCCESS); +} + +/*%< + * Allocator for UDP recv operations. Limited to size 20 * (2^16 + 2), + * which allows enough space for recvmmsg() to get multiple messages at + * a time. + * + * Note this doesn't actually allocate anything, it just assigns the + * worker's receive buffer to a socket, and marks it as "in use". + */ +static void +udp_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; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_udpsocket); + REQUIRE(isc__nm_in_netthread()); + REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE); + + worker = &sock->mgr->workers[sock->tid]; + INSIST(!worker->recvbuf_inuse); + + buf->base = worker->recvbuf; + buf->len = ISC_NETMGR_RECVBUF_SIZE; + worker->recvbuf_inuse = true; +} + +/* + * Asynchronous 'udplisten' call handler: start listening on a UDP socket. + */ +void +isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_udplisten_t *ievent = (isc__netievent_udplisten_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + int r, uv_bind_flags = 0; + int uv_init_flags = 0; + sa_family_t sa_family; + + REQUIRE(sock->type == isc_nm_udpsocket); + REQUIRE(sock->iface != NULL); + REQUIRE(sock->parent != NULL); + REQUIRE(sock->tid == isc_nm_tid()); + +#ifdef UV_UDP_RECVMMSG + uv_init_flags |= UV_UDP_RECVMMSG; +#endif + uv_udp_init_ex(&worker->loop, &sock->uv_handle.udp, uv_init_flags); + uv_handle_set_data(&sock->uv_handle.handle, NULL); + isc__nmsocket_attach(sock, + (isc_nmsocket_t **)&sock->uv_handle.udp.data); + + r = uv_udp_open(&sock->uv_handle.udp, sock->fd); + if (r == 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]); + } else { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); + } + + sa_family = sock->iface->addr.type.sa.sa_family; + if (sa_family == AF_INET6) { + uv_bind_flags |= UV_UDP_IPV6ONLY; + } + + r = uv_udp_bind(&sock->uv_handle.udp, + &sock->parent->iface->addr.type.sa, uv_bind_flags); + if (r == UV_EADDRNOTAVAIL && + isc__nm_socket_freebind(sock->fd, sa_family) == ISC_R_SUCCESS) + { + /* + * Retry binding with IP_FREEBIND (or equivalent option) if the + * address is not available. This helps with IPv6 tentative + * addresses which are reported by the route socket, although + * named is not yet able to properly bind to them. + */ + r = uv_udp_bind(&sock->uv_handle.udp, + &sock->parent->iface->addr.type.sa, + uv_bind_flags); + } + + if (r < 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]); + } +#ifdef ISC_RECV_BUFFER_SIZE + uv_recv_buffer_size(&sock->uv_handle.handle, + &(int){ ISC_RECV_BUFFER_SIZE }); +#endif +#ifdef ISC_SEND_BUFFER_SIZE + uv_send_buffer_size(&sock->uv_handle.handle, + &(int){ ISC_SEND_BUFFER_SIZE }); +#endif + uv_udp_recv_start(&sock->uv_handle.udp, udp_alloc_cb, udp_recv_cb); +} + +static void +udp_stop_cb(uv_handle_t *handle) { + isc_nmsocket_t *sock = uv_handle_get_data(handle); + atomic_store(&sock->closed, true); + + isc__nmsocket_detach((isc_nmsocket_t **)&sock->uv_handle.udp.data); +} + +static void +stop_udp_child(isc_nmsocket_t *sock) { + REQUIRE(sock->type == isc_nm_udpsocket); + REQUIRE(sock->tid == isc_nm_tid()); + + uv_udp_recv_stop(&sock->uv_handle.udp); + uv_close((uv_handle_t *)&sock->uv_handle.udp, udp_stop_cb); + + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CLOSE]); + + LOCK(&sock->parent->lock); + atomic_fetch_sub(&sock->parent->rchildren, 1); + UNLOCK(&sock->parent->lock); + BROADCAST(&sock->parent->cond); +} + +static void +stoplistening(isc_nmsocket_t *sock) { + REQUIRE(sock->type == isc_nm_udplistener); + + for (int i = 0; i < sock->nchildren; i++) { + isc__netievent_udpstop_t *event = NULL; + + if (isc_nm_tid() == sock->children[i].tid) { + stop_udp_child(&sock->children[i]); + continue; + } + + event = isc__nm_get_ievent(sock->mgr, netievent_udpstop); + event->sock = &sock->children[i]; + isc__nm_enqueue_ievent(&sock->mgr->workers[i], + (isc__netievent_t *)event); + } + + LOCK(&sock->lock); + while (atomic_load_relaxed(&sock->rchildren) > 0) { + WAIT(&sock->cond, &sock->lock); + } + atomic_store(&sock->closed, true); + UNLOCK(&sock->lock); + + isc__nmsocket_prep_destroy(sock); +} + +void +isc__nm_udp_stoplistening(isc_nmsocket_t *sock) { + isc__netievent_udpstop_t *ievent = NULL; + + /* We can't be launched from network thread, we'd deadlock */ + REQUIRE(!isc__nm_in_netthread()); + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_udplistener); + + /* + * Socket is already closing; there's nothing to do. + */ + if (!isc__nmsocket_active(sock)) { + return; + } + /* + * Mark it inactive now so that all sends will be ignored + * and we won't try to stop listening again. + */ + atomic_store(&sock->active, false); + + /* + * If the manager is interlocked, re-enqueue this as an asynchronous + * event. Otherwise, go ahead and stop listening right away. + */ + if (!isc__nm_acquire_interlocked(sock->mgr)) { + ievent = isc__nm_get_ievent(sock->mgr, netievent_udpstop); + ievent->sock = sock; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } else { + stoplistening(sock); + isc__nm_drop_interlocked(sock->mgr); + } +} + +/* + * Asynchronous 'udpstop' call handler: stop listening on a UDP socket. + */ +void +isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_udpstop_t *ievent = (isc__netievent_udpstop_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + + REQUIRE(sock->iface != NULL); + UNUSED(worker); + + /* + * If this is a child socket, stop listening and return. + */ + if (sock->parent != NULL) { + stop_udp_child(sock); + return; + } + + /* + * If network manager is paused, re-enqueue the event for later. + */ + if (!isc__nm_acquire_interlocked(sock->mgr)) { + isc__netievent_udplisten_t *event = NULL; + + event = isc__nm_get_ievent(sock->mgr, netievent_udpstop); + event->sock = sock; + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)event); + } else { + stoplistening(sock); + isc__nm_drop_interlocked(sock->mgr); + } +} + +/* + * udp_recv_cb handles incoming UDP packet from uv. The buffer here is + * reused for a series of packets, so we need to allocate a new one. This + * new one can be reused to send the response then. + */ +static void +udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf, + const struct sockaddr *addr, unsigned flags) { + isc_result_t result; + isc_nmhandle_t *nmhandle = NULL; + isc_sockaddr_t sockaddr; + isc_nmsocket_t *sock = NULL; + isc_region_t region; + uint32_t maxudp; + bool free_buf = true; + isc_nm_recv_cb_t cb; + void *cbarg; + + /* + * Even though destruction of the socket can only happen from the + * network thread that we're in, we still attach to the socket here + * to ensure it won't be destroyed by the recv callback. + */ + isc__nmsocket_attach(uv_handle_get_data((uv_handle_t *)handle), &sock); + +#ifdef UV_UDP_MMSG_CHUNK + free_buf = ((flags & UV_UDP_MMSG_CHUNK) == 0); +#else + UNUSED(flags); +#endif + + /* + * Three possible reasons to return now without processing: + * - If addr == NULL, in which case it's the end of stream; + * we can free the buffer and bail. + * - If we're simulating a firewall blocking UDP packets + * bigger than 'maxudp' bytes for testing purposes. + * - If the socket is no longer active. + */ + maxudp = atomic_load(&sock->mgr->maxudp); + if ((addr == NULL) || (maxudp != 0 && (uint32_t)nrecv > maxudp) || + (!isc__nmsocket_active(sock))) + { + if (free_buf) { + isc__nm_free_uvbuf(sock, buf); + } + isc__nmsocket_detach(&sock); + return; + } + + result = isc_sockaddr_fromsockaddr(&sockaddr, addr); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + nmhandle = isc__nmhandle_get(sock, &sockaddr, NULL); + region.base = (unsigned char *)buf->base; + region.length = nrecv; + + INSIST(sock->tid == isc_nm_tid()); + INSIST(sock->recv_cb != NULL); + cb = sock->recv_cb; + cbarg = sock->recv_cbarg; + + cb(nmhandle, ISC_R_SUCCESS, ®ion, cbarg); + + if (free_buf) { + isc__nm_free_uvbuf(sock, buf); + } + + /* + * The sock is now attached to the handle, we can detach our ref. + */ + isc__nmsocket_detach(&sock); + + /* + * If the recv callback wants to hold on to the handle, + * it needs to attach to it. + */ + isc_nmhandle_detach(&nmhandle); +} + +/* + * Send the data in 'region' to a peer via a UDP socket. We try to find + * a proper sibling/child socket so that we won't have to jump to another + * thread. + */ +isc_result_t +isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, + void *cbarg) { + isc_nmsocket_t *sock = handle->sock; + isc_nmsocket_t *psock = NULL, *rsock = sock; + isc_sockaddr_t *peer = &handle->peer; + isc__netievent_udpsend_t *ievent = NULL; + isc__nm_uvreq_t *uvreq = NULL; + uint32_t maxudp = atomic_load(&sock->mgr->maxudp); + int ntid; + + /* + * We're simulating a firewall blocking UDP packets bigger than + * 'maxudp' bytes, for testing purposes. + * + * The client would ordinarily have unreferenced the handle + * in the callback, but that won't happen in this case, so + * we need to do so here. + */ + if (maxudp != 0 && region->length > maxudp) { + isc_nmhandle_detach(&handle); + return (ISC_R_SUCCESS); + } + + if (sock->type == isc_nm_udpsocket && !atomic_load(&sock->client)) { + INSIST(sock->parent != NULL); + psock = sock->parent; + } else if (sock->type == isc_nm_udplistener) { + psock = sock; + } else if (!atomic_load(&sock->client)) { + INSIST(0); + ISC_UNREACHABLE(); + } + + if (!isc__nmsocket_active(sock)) { + return (ISC_R_CANCELED); + } + + /* + * If we're in the network thread, we can send directly. If the + * handle is associated with a UDP socket, we can reuse its thread + * (assuming CPU affinity). Otherwise, pick a thread at random. + */ + if (isc__nm_in_netthread()) { + ntid = isc_nm_tid(); + } else if (sock->type == isc_nm_udpsocket && + !atomic_load(&sock->client)) { + ntid = sock->tid; + } else { + ntid = (int)isc_random_uniform(sock->nchildren); + } + + if (psock != NULL) { + rsock = &psock->children[ntid]; + } + + uvreq = isc__nm_uvreq_get(sock->mgr, sock); + uvreq->uvbuf.base = (char *)region->base; + uvreq->uvbuf.len = region->length; + + isc_nmhandle_attach(handle, &uvreq->handle); + + uvreq->cb.send = cb; + uvreq->cbarg = cbarg; + + if (isc_nm_tid() == rsock->tid) { + /* + * If we're in the same thread as the socket we can send the + * data directly + */ + return (udp_send_direct(rsock, uvreq, peer)); + } else { + /* + * We need to create an event and pass it using async channel + */ + ievent = isc__nm_get_ievent(sock->mgr, netievent_udpsend); + ievent->sock = rsock; + ievent->peer = *peer; + ievent->req = uvreq; + + isc__nm_enqueue_ievent(&sock->mgr->workers[rsock->tid], + (isc__netievent_t *)ievent); + return (ISC_R_SUCCESS); + } +} + +/* + * Asynchronous 'udpsend' event handler: send a packet on a UDP socket. + */ +void +isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_udpsend_t *ievent = (isc__netievent_udpsend_t *)ev0; + + REQUIRE(worker->id == ievent->sock->tid); + + if (isc__nmsocket_active(ievent->sock)) { + udp_send_direct(ievent->sock, ievent->req, &ievent->peer); + } else { + ievent->req->cb.send(ievent->req->handle, ISC_R_CANCELED, + ievent->req->cbarg); + isc__nm_uvreq_put(&ievent->req, ievent->req->sock); + } +} + +static void +udp_send_cb(uv_udp_send_t *req, int status) { + isc_result_t result = ISC_R_SUCCESS; + isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data; + + REQUIRE(VALID_UVREQ(uvreq)); + REQUIRE(VALID_NMHANDLE(uvreq->handle)); + + if (status < 0) { + result = isc__nm_uverr2result(status); + isc__nm_incstats(uvreq->sock->mgr, + uvreq->sock->statsindex[STATID_SENDFAIL]); + } + + uvreq->cb.send(uvreq->handle, result, uvreq->cbarg); + isc__nm_uvreq_put(&uvreq, uvreq->sock); +} + +/* + * udp_send_direct sends buf to a peer on a socket. Sock has to be in + * the same thread as the callee. + */ +static isc_result_t +udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req, + isc_sockaddr_t *peer) { + const struct sockaddr *sa = NULL; + int rv; + + REQUIRE(sock->tid == isc_nm_tid()); + REQUIRE(sock->type == isc_nm_udpsocket); + + if (!isc__nmsocket_active(sock)) { + return (ISC_R_CANCELED); + } + + sa = atomic_load(&sock->connected) ? NULL : &peer->type.sa; + rv = uv_udp_send(&req->uv_req.udp_send, &sock->uv_handle.udp, + &req->uvbuf, 1, sa, udp_send_cb); + if (rv < 0) { + isc__nm_incstats(req->sock->mgr, + req->sock->statsindex[STATID_SENDFAIL]); + return (isc__nm_uverr2result(rv)); + } + + return (ISC_R_SUCCESS); +} diff --git a/lib/isc/netmgr/uv-compat.c b/lib/isc/netmgr/uv-compat.c new file mode 100644 index 00000000..8ad3b1a0 --- /dev/null +++ b/lib/isc/netmgr/uv-compat.c @@ -0,0 +1,189 @@ +/* + * 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. + */ + +#include "uv-compat.h" +#include <unistd.h> + +#include <isc/util.h> + +#ifndef HAVE_UV_IMPORT +/* + * XXXWPK: This code goes into libuv internals and it's platform dependent. + * It's ugly, we shouldn't do it, but the alternative with passing sockets + * over IPC sockets is even worse, and causes all kind of different + * problems. We should try to push these things upstream. + */ + +#ifdef WIN32 +/* This code is adapted from libuv/src/win/internal.h */ + +typedef enum { + UV__IPC_SOCKET_XFER_NONE = 0, + UV__IPC_SOCKET_XFER_TCP_CONNECTION, + UV__IPC_SOCKET_XFER_TCP_SERVER +} uv__ipc_socket_xfer_type_t; + +typedef struct { + WSAPROTOCOL_INFOW socket_info; + uint32_t delayed_error; +} uv__ipc_socket_xfer_info_t; + +/* + * Needed to make sure that the internal structure that we pulled out of + * libuv hasn't changed. + */ + +int +uv__tcp_xfer_import(uv_tcp_t *tcp, uv__ipc_socket_xfer_type_t xfer_type, + uv__ipc_socket_xfer_info_t *xfer_info); + +int +uv__tcp_xfer_export(uv_tcp_t *handle, int target_pid, + uv__ipc_socket_xfer_type_t *xfer_type, + uv__ipc_socket_xfer_info_t *xfer_info); + +int +isc_uv_export(uv_stream_t *stream, isc_uv_stream_info_t *info) { + uv__ipc_socket_xfer_info_t xfer_info; + uv__ipc_socket_xfer_type_t xfer_type = UV__IPC_SOCKET_XFER_NONE; + + /* + * Needed to make sure that the internal structure that we pulled + * out of libuv hasn't changed. + */ + RUNTIME_CHECK(sizeof(uv__ipc_socket_xfer_info_t) == 632); + + if (stream->type != UV_TCP) { + return (-1); + } + int r = uv__tcp_xfer_export((uv_tcp_t *)stream, GetCurrentProcessId(), + &xfer_type, &xfer_info); + if (r != 0) { + return (r); + } + if (xfer_info.delayed_error != 0) { + return (xfer_info.delayed_error); + } + INSIST(xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION); + info->type = UV_TCP; + info->socket_info = xfer_info.socket_info; + return (0); +} + +int +isc_uv_import(uv_stream_t *stream, isc_uv_stream_info_t *info) { + if (stream->type != UV_TCP || info->type != UV_TCP) { + return (-1); + } + + return (uv__tcp_xfer_import( + (uv_tcp_t *)stream, UV__IPC_SOCKET_XFER_TCP_CONNECTION, + &(uv__ipc_socket_xfer_info_t){ + .socket_info = info->socket_info })); +} +#else /* WIN32 */ +/* Adapted from libuv/src/unix/internal.h */ +#include <fcntl.h> +#include <sys/ioctl.h> + +static int +isc_uv__cloexec(int fd, int set) { + int r; + + /* + * This #ifdef is taken directly from the libuv sources. + * We use FIOCLEX and FIONCLEX ioctl() calls when possible, + * but on some platforms are not implemented, or defined but + * not implemented correctly. On those, we use the FD_CLOEXEC + * fcntl() call, which adds extra system call overhead, but + * works. + */ +#if defined(_AIX) || defined(__APPLE__) || defined(__DragonFly__) || \ + defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ + defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) + do { + r = ioctl(fd, set ? FIOCLEX : FIONCLEX); + } while (r == -1 && errno == EINTR); +#else /* FIOCLEX/FIONCLEX unsupported */ + int flags; + + do { + r = fcntl(fd, F_GETFD); + } while (r == -1 && errno == EINTR); + + if (r == -1) { + return (-1); + } + + if (!!(r & FD_CLOEXEC) == !!set) { + return (0); + } + + if (set) { + flags = r | FD_CLOEXEC; + } else { + flags = r & ~FD_CLOEXEC; + } + + do { + r = fcntl(fd, F_SETFD, flags); + } while (r == -1 && errno == EINTR); +#endif /* FIOCLEX/FIONCLEX unsupported */ + + if (r != 0) { + return (-1); + } + + return (0); +} + +int +isc_uv_export(uv_stream_t *stream, isc_uv_stream_info_t *info) { + int oldfd, fd; + int err; + + if (stream->type != UV_TCP) { + return (-1); + } + err = uv_fileno((uv_handle_t *)stream, (uv_os_fd_t *)&oldfd); + + if (err != 0) { + return (err); + } + + fd = dup(oldfd); + if (fd == -1) { + return (-1); + } + + err = isc_uv__cloexec(fd, 1); + if (err != 0) { + close(fd); + return (err); + } + + info->type = stream->type; + info->fd = fd; + return (0); +} + +int +isc_uv_import(uv_stream_t *stream, isc_uv_stream_info_t *info) { + if (info->type != UV_TCP) { + return (-1); + } + + uv_tcp_t *tcp = (uv_tcp_t *)stream; + return (uv_tcp_open(tcp, info->fd)); +} +#endif /* ifdef WIN32 */ + +#endif /* ifndef HAVE_UV_IMPORT */ diff --git a/lib/isc/netmgr/uv-compat.h b/lib/isc/netmgr/uv-compat.h new file mode 100644 index 00000000..d02ddd3e --- /dev/null +++ b/lib/isc/netmgr/uv-compat.h @@ -0,0 +1,81 @@ +/* + * 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 +#include <uv.h> + +/* + * These functions were introduced in newer libuv, but we still + * want BIND9 compile on older ones so we emulate them. + * They're inline to avoid conflicts when running with a newer + * library version. + */ + +#ifndef HAVE_UV_HANDLE_GET_DATA +static inline void * +uv_handle_get_data(const uv_handle_t *handle) { + return (handle->data); +} +#endif /* ifndef HAVE_UV_HANDLE_GET_DATA */ + +#ifndef HAVE_UV_HANDLE_SET_DATA +static inline void +uv_handle_set_data(uv_handle_t *handle, void *data) { + handle->data = data; +} +#endif /* ifndef HAVE_UV_HANDLE_SET_DATA */ + +#ifdef HAVE_UV_IMPORT + +#define isc_uv_stream_info_t uv_stream_info_t +#define isc_uv_export uv_export +#define isc_uv_import uv_import + +#else + +/* + * These functions are not available in libuv, but they're very internal + * to libuv. We should try to get them merged upstream. + */ + +/* + * A sane way to pass listening TCP socket to child threads, without using + * IPC (as the libuv example shows) but a version of the uv_export() and + * uv_import() functions that were unfortunately removed from libuv. + * This is based on the original libuv code. + */ + +typedef struct isc_uv_stream_info_s isc_uv_stream_info_t; + +struct isc_uv_stream_info_s { + uv_handle_type type; +#ifdef WIN32 + WSAPROTOCOL_INFOW socket_info; +#else /* ifdef WIN32 */ + int fd; +#endif /* ifdef WIN32 */ +}; + +int +isc_uv_export(uv_stream_t *stream, isc_uv_stream_info_t *info); +/*%< + * Exports uv_stream_t as isc_uv_stream_info_t value, which could + * be used to initialize shared streams within the same process. + */ + +int +isc_uv_import(uv_stream_t *stream, isc_uv_stream_info_t *info); +/*%< + * Imports uv_stream_info_t value into uv_stream_t to initialize a + * shared stream. + */ + +#endif diff --git a/lib/isc/netmgr/uverr2result.c b/lib/isc/netmgr/uverr2result.c new file mode 100644 index 00000000..f1c0a74b --- /dev/null +++ b/lib/isc/netmgr/uverr2result.c @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#include <stdbool.h> +#include <uv.h> + +#include <isc/result.h> +#include <isc/strerr.h> +#include <isc/string.h> +#include <isc/util.h> + +#include "netmgr-int.h" + +/*% + * Convert a libuv error value into an isc_result_t. The + * list of supported error values is not complete; new users + * of this function should add any expected errors that are + * not already there. + */ +isc_result_t +isc___nm_uverr2result(int uverr, bool dolog, const char *file, + unsigned int line) { + switch (uverr) { + case UV_ENOTDIR: + case UV_ELOOP: + case UV_EINVAL: /* XXX sometimes this is not for files */ + case UV_ENAMETOOLONG: + case UV_EBADF: + return (ISC_R_INVALIDFILE); + case UV_ENOENT: + return (ISC_R_FILENOTFOUND); + case UV_EAGAIN: + return (ISC_R_NOCONN); + case UV_EACCES: + case UV_EPERM: + return (ISC_R_NOPERM); + case UV_EEXIST: + return (ISC_R_FILEEXISTS); + case UV_EIO: + return (ISC_R_IOERROR); + case UV_ENOMEM: + return (ISC_R_NOMEMORY); + case UV_ENFILE: + case UV_EMFILE: + return (ISC_R_TOOMANYOPENFILES); + case UV_ENOSPC: + return (ISC_R_DISCFULL); + case UV_EPIPE: + case UV_ECONNRESET: + case UV_ECONNABORTED: + return (ISC_R_CONNECTIONRESET); + case UV_ENOTCONN: + return (ISC_R_NOTCONNECTED); + case UV_ETIMEDOUT: + return (ISC_R_TIMEDOUT); + case UV_ENOBUFS: + return (ISC_R_NORESOURCES); + case UV_EAFNOSUPPORT: + return (ISC_R_FAMILYNOSUPPORT); + case UV_ENETDOWN: + return (ISC_R_NETDOWN); + case UV_EHOSTDOWN: + return (ISC_R_HOSTDOWN); + case UV_ENETUNREACH: + return (ISC_R_NETUNREACH); + case UV_EHOSTUNREACH: + return (ISC_R_HOSTUNREACH); + case UV_EADDRINUSE: + return (ISC_R_ADDRINUSE); + case UV_EADDRNOTAVAIL: + return (ISC_R_ADDRNOTAVAIL); + case UV_ECONNREFUSED: + return (ISC_R_CONNREFUSED); + default: + if (dolog) { + UNEXPECTED_ERROR(file, line, + "unable to convert libuv " + "error code to isc_result: %d: %s", + uverr, uv_strerror(uverr)); + } + return (ISC_R_UNEXPECTED); + } +} diff --git a/lib/isc/netscope.c b/lib/isc/netscope.c index da004639..45c0b52f 100644 --- a/lib/isc/netscope.c +++ b/lib/isc/netscope.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,15 +11,14 @@ /*! \file */ -#include <config.h> - #include <inttypes.h> #include <stdlib.h> -#include <isc/string.h> #include <isc/net.h> #include <isc/netscope.h> #include <isc/result.h> +#include <isc/string.h> +#include <isc/util.h> isc_result_t isc_netscope_pton(int af, char *scopename, void *addr, uint32_t *zoneid) { @@ -27,40 +26,48 @@ isc_netscope_pton(int af, char *scopename, void *addr, uint32_t *zoneid) { #ifdef HAVE_IF_NAMETOINDEX unsigned int ifid; struct in6_addr *in6; -#endif - uint32_t zone; +#endif /* ifdef HAVE_IF_NAMETOINDEX */ + uint32_t zone = 0; uint64_t llz; +#ifndef HAVE_IF_NAMETOINDEX + UNUSED(addr); +#endif + /* at this moment, we only support AF_INET6 */ - if (af != AF_INET6) + if (af != AF_INET6) { return (ISC_R_FAILURE); + } /* - * Basically, "names" are more stable than numeric IDs in terms of - * renumbering, and are more preferred. However, since there is no - * standard naming convention and APIs to deal with the names. Thus, - * we only handle the case of link-local addresses, for which we use - * interface names as link names, assuming one to one mapping between - * interfaces and links. + * Basically, "names" are more stable than numeric IDs in terms + * of renumbering, and are more preferred. However, since there + * is no standard naming convention and APIs to deal with the + * names. Thus, we only handle the case of link-local + * addresses, for which we use interface names as link names, + * assuming one to one mapping between interfaces and links. */ #ifdef HAVE_IF_NAMETOINDEX in6 = (struct in6_addr *)addr; if (IN6_IS_ADDR_LINKLOCAL(in6) && (ifid = if_nametoindex((const char *)scopename)) != 0) + { zone = (uint32_t)ifid; - else { -#endif + } else { +#endif /* ifdef HAVE_IF_NAMETOINDEX */ llz = strtoull(scopename, &ep, 10); - if (ep == scopename) + if (ep == scopename) { return (ISC_R_FAILURE); + } /* check overflow */ zone = (uint32_t)(llz & 0xffffffffUL); - if (zone != llz) + if (zone != llz) { return (ISC_R_FAILURE); + } #ifdef HAVE_IF_NAMETOINDEX } -#endif +#endif /* ifdef HAVE_IF_NAMETOINDEX */ *zoneid = zone; return (ISC_R_SUCCESS); diff --git a/lib/isc/nonce.c b/lib/isc/nonce.c index 2302af39..f1e3370b 100644 --- a/lib/isc/nonce.c +++ b/lib/isc/nonce.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <isc/nonce.h> #include "entropy_private.h" diff --git a/lib/isc/openssl_shim.c b/lib/isc/openssl_shim.c index d1cbc83b..7890b0cf 100644 --- a/lib/isc/openssl_shim.c +++ b/lib/isc/openssl_shim.c @@ -3,91 +3,82 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - -#include <openssl/opensslv.h> - +#include "openssl_shim.h" #include <stdlib.h> #include <string.h> -#include "openssl_shim.h" + +#include <openssl/crypto.h> #include <openssl/engine.h> #include <openssl/evp.h> #include <openssl/hmac.h> -#include <openssl/crypto.h> +#include <openssl/opensslv.h> #if !HAVE_CRYPTO_ZALLOC void * -CRYPTO_zalloc(size_t size) -{ +CRYPTO_zalloc(size_t size) { void *ret = OPENSSL_malloc(size); if (ret != NULL) { memset(ret, 0, size); } return (ret); } -#endif +#endif /* if !HAVE_CRYPTO_ZALLOC */ #if !HAVE_EVP_CIPHER_CTX_NEW EVP_CIPHER_CTX * -EVP_CIPHER_CTX_new(void) -{ +EVP_CIPHER_CTX_new(void) { EVP_CIPHER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); return (ctx); } -#endif +#endif /* if !HAVE_EVP_CIPHER_CTX_NEW */ #if !HAVE_EVP_CIPHER_CTX_FREE void -EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) -{ +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { if (ctx != NULL) { EVP_CIPHER_CTX_cleanup(ctx); OPENSSL_free(ctx); } } -#endif +#endif /* if !HAVE_EVP_CIPHER_CTX_FREE */ #if !HAVE_EVP_MD_CTX_NEW EVP_MD_CTX * -EVP_MD_CTX_new(void) -{ +EVP_MD_CTX_new(void) { EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); if (ctx != NULL) { memset(ctx, 0, sizeof(*ctx)); } return (ctx); } -#endif +#endif /* if !HAVE_EVP_MD_CTX_NEW */ #if !HAVE_EVP_MD_CTX_FREE void -EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ +EVP_MD_CTX_free(EVP_MD_CTX *ctx) { if (ctx != NULL) { EVP_MD_CTX_cleanup(ctx); OPENSSL_free(ctx); } } -#endif +#endif /* if !HAVE_EVP_MD_CTX_FREE */ #if !HAVE_EVP_MD_CTX_RESET int -EVP_MD_CTX_reset(EVP_MD_CTX *ctx) -{ +EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { return (EVP_MD_CTX_cleanup(ctx)); } -#endif +#endif /* if !HAVE_EVP_MD_CTX_RESET */ #if !HAVE_HMAC_CTX_NEW HMAC_CTX * -HMAC_CTX_new(void) -{ +HMAC_CTX_new(void) { HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { if (!HMAC_CTX_reset(ctx)) { @@ -97,18 +88,17 @@ HMAC_CTX_new(void) } return (ctx); } -#endif +#endif /* if !HAVE_HMAC_CTX_NEW */ #if !HAVE_HMAC_CTX_FREE void -HMAC_CTX_free(HMAC_CTX *ctx) -{ +HMAC_CTX_free(HMAC_CTX *ctx) { if (ctx != NULL) { HMAC_CTX_cleanup(ctx); OPENSSL_free(ctx); } } -#endif +#endif /* if !HAVE_HMAC_CTX_FREE */ #if !HAVE_HMAC_CTX_RESET int @@ -116,10 +106,11 @@ HMAC_CTX_reset(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); return (1); } -#endif +#endif /* if !HAVE_HMAC_CTX_RESET */ #if !HAVE_HMAC_CTX_GET_MD -const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx) { - return ctx->md; +const EVP_MD * +HMAC_CTX_get_md(const HMAC_CTX *ctx) { + return (ctx->md); } -#endif +#endif /* if !HAVE_HMAC_CTX_GET_MD */ diff --git a/lib/isc/openssl_shim.h b/lib/isc/openssl_shim.h index fe427fb7..038df128 100644 --- a/lib/isc/openssl_shim.h +++ b/lib/isc/openssl_shim.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,51 +11,59 @@ #pragma once -#include <config.h> - -#include <openssl/opensslv.h> #include <openssl/crypto.h> #include <openssl/engine.h> #include <openssl/evp.h> #include <openssl/hmac.h> +#include <openssl/opensslv.h> #if !HAVE_CRYPTO_ZALLOC -void *CRYPTO_zalloc(size_t size); +void * +CRYPTO_zalloc(size_t size); #define OPENSSL_zalloc(num) CRYPTO_zalloc(num) -#endif +#endif /* if !HAVE_CRYPTO_ZALLOC */ #if !HAVE_EVP_CIPHER_CTX_NEW -EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); -#endif +EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void); +#endif /* if !HAVE_EVP_CIPHER_CTX_NEW */ #if !HAVE_EVP_CIPHER_CTX_FREE -void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); -#endif +void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); +#endif /* if !HAVE_EVP_CIPHER_CTX_FREE */ #if !HAVE_EVP_MD_CTX_NEW -EVP_MD_CTX *EVP_MD_CTX_new(void); -#endif +EVP_MD_CTX * +EVP_MD_CTX_new(void); +#endif /* if !HAVE_EVP_MD_CTX_NEW */ #if !HAVE_EVP_MD_CTX_FREE -void EVP_MD_CTX_free(EVP_MD_CTX *ctx); -#endif +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx); +#endif /* if !HAVE_EVP_MD_CTX_FREE */ #if !HAVE_EVP_MD_CTX_RESET -int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); -#endif +int +EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +#endif /* if !HAVE_EVP_MD_CTX_RESET */ #if !HAVE_HMAC_CTX_NEW -HMAC_CTX *HMAC_CTX_new(void); -#endif +HMAC_CTX * +HMAC_CTX_new(void); +#endif /* if !HAVE_HMAC_CTX_NEW */ #if !HAVE_HMAC_CTX_FREE -void HMAC_CTX_free(HMAC_CTX *ctx); -#endif +void +HMAC_CTX_free(HMAC_CTX *ctx); +#endif /* if !HAVE_HMAC_CTX_FREE */ #if !HAVE_HMAC_CTX_RESET -int HMAC_CTX_reset(HMAC_CTX *ctx); -#endif +int +HMAC_CTX_reset(HMAC_CTX *ctx); +#endif /* if !HAVE_HMAC_CTX_RESET */ #if !HAVE_HMAC_CTX_GET_MD -const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); -#endif +const EVP_MD * +HMAC_CTX_get_md(const HMAC_CTX *ctx); +#endif /* if !HAVE_HMAC_CTX_GET_MD */ diff --git a/lib/isc/parseint.c b/lib/isc/parseint.c index ced6911c..ed539fdf 100644 --- a/lib/isc/parseint.c +++ b/lib/isc/parseint.c @@ -3,21 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <ctype.h> #include <errno.h> -#include <limits.h> #include <inttypes.h> +#include <limits.h> #include <stdlib.h> #include <isc/parseint.h> @@ -28,20 +25,23 @@ isc_parse_uint32(uint32_t *uip, const char *string, int base) { unsigned long n; uint32_t r; char *e; - if (! isalnum((unsigned char)(string[0]))) + if (!isalnum((unsigned char)(string[0]))) { return (ISC_R_BADNUMBER); + } errno = 0; n = strtoul(string, &e, base); - if (*e != '\0') + if (*e != '\0') { return (ISC_R_BADNUMBER); + } /* * Where long is 64 bits we need to convert to 32 bits then test for * equality. This is a no-op on 32 bit machines and a good compiler * will optimise it away. */ r = (uint32_t)n; - if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) + if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) { return (ISC_R_RANGE); + } *uip = r; return (ISC_R_SUCCESS); } @@ -51,11 +51,13 @@ isc_parse_uint16(uint16_t *uip, const char *string, int base) { uint32_t val; isc_result_t result; result = isc_parse_uint32(&val, string, base); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); - if (val > 0xFFFF) + } + if (val > 0xFFFF) { return (ISC_R_RANGE); - *uip = (uint16_t) val; + } + *uip = (uint16_t)val; return (ISC_R_SUCCESS); } @@ -64,10 +66,12 @@ isc_parse_uint8(uint8_t *uip, const char *string, int base) { uint32_t val; isc_result_t result; result = isc_parse_uint32(&val, string, base); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); - if (val > 0xFF) + } + if (val > 0xFF) { return (ISC_R_RANGE); - *uip = (uint8_t) val; + } + *uip = (uint8_t)val; return (ISC_R_SUCCESS); } diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c index aaddac5c..d1fa5076 100644 --- a/lib/isc/pk11.c +++ b/lib/isc/pk11.c @@ -3,17 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - +#include <errno.h> +#include <inttypes.h> #include <stdbool.h> #include <stdio.h> -#include <inttypes.h> #include <stdlib.h> #include <string.h> @@ -23,29 +22,27 @@ #include <isc/platform.h> #include <isc/print.h> #include <isc/stdio.h> +#include <isc/strerr.h> #include <isc/string.h> #include <isc/thread.h> #include <isc/util.h> -#include <dst/result.h> - -#include <pk11/pk11.h> #include <pk11/internal.h> +#include <pk11/pk11.h> #include <pk11/result.h> #include <pk11/site.h> - -#include <pkcs11/cryptoki.h> #include <pkcs11/pkcs11.h> -#include <pkcs11/eddsa.h> + +#include <dst/result.h> /* was 32 octets, Petr Spacek suggested 1024, SoftHSMv2 uses 256... */ #ifndef PINLEN -#define PINLEN 256 -#endif +#define PINLEN 256 +#endif /* ifndef PINLEN */ #ifndef PK11_NO_LOGERR #define PK11_NO_LOGERR 1 -#endif +#endif /* ifndef PK11_NO_LOGERR */ LIBISC_EXTERNAL_DATA bool pk11_verbose_init = false; @@ -59,45 +56,47 @@ typedef struct pk11_token pk11_token_t; typedef ISC_LIST(pk11_session_t) pk11_sessionlist_t; struct pk11_session { - unsigned int magic; - CK_SESSION_HANDLE session; + unsigned int magic; + CK_SESSION_HANDLE session; ISC_LINK(pk11_session_t) link; - pk11_token_t *token; + pk11_token_t *token; }; struct pk11_token { - unsigned int magic; - unsigned int operations; - ISC_LINK(pk11_token_t) link; - CK_SLOT_ID slotid; - pk11_sessionlist_t sessions; - bool logged; - char name[32]; - char manuf[32]; - char model[16]; - char serial[16]; - char pin[PINLEN + 1]; + unsigned int magic; + unsigned int operations; + ISC_LINK(pk11_token_t) link; + CK_SLOT_ID slotid; + pk11_sessionlist_t sessions; + bool logged; + char name[32]; + char manuf[32]; + char model[16]; + char serial[16]; + char pin[PINLEN + 1]; }; static ISC_LIST(pk11_token_t) tokens; static pk11_token_t *best_rsa_token; -static pk11_token_t *best_dh_token; static pk11_token_t *best_ecdsa_token; static pk11_token_t *best_eddsa_token; -static isc_result_t free_all_sessions(void); -static isc_result_t free_session_list(pk11_sessionlist_t *slist); -static isc_result_t setup_session(pk11_session_t *sp, - pk11_token_t *token, - bool rw); -static void scan_slots(void); -static isc_result_t token_login(pk11_session_t *sp); -static char *percent_decode(char *x, size_t *len); -static bool pk11strcmp(const char *x, size_t lenx, - const char *y, size_t leny); -static CK_ATTRIBUTE *push_attribute(pk11_object_t *obj, - isc_mem_t *mctx, - size_t len); +static isc_result_t +free_all_sessions(void); +static isc_result_t +free_session_list(pk11_sessionlist_t *slist); +static isc_result_t +setup_session(pk11_session_t *sp, pk11_token_t *token, bool rw); +static void +scan_slots(void); +static isc_result_t +token_login(pk11_session_t *sp); +static char * +percent_decode(char *x, size_t *len); +static bool +pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny); +static CK_ATTRIBUTE * +push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len); static isc_mutex_t alloclock; static isc_mutex_t sessionlock; @@ -105,23 +104,23 @@ static isc_mutex_t sessionlock; static pk11_sessionlist_t actives; static CK_C_INITIALIZE_ARGS pk11_init_args = { - NULL_PTR, /* CreateMutex */ - NULL_PTR, /* DestroyMutex */ - NULL_PTR, /* LockMutex */ - NULL_PTR, /* UnlockMutex */ - CKF_OS_LOCKING_OK, /* flags */ - NULL_PTR, /* pReserved */ + NULL_PTR, /* CreateMutex */ + NULL_PTR, /* DestroyMutex */ + NULL_PTR, /* LockMutex */ + NULL_PTR, /* UnlockMutex */ + CKF_OS_LOCKING_OK, /* flags */ + NULL_PTR, /* pReserved */ }; #ifndef PK11_LIB_LOCATION -#define PK11_LIB_LOCATION "unknown_provider" -#endif +#define PK11_LIB_LOCATION "unknown_provider" +#endif /* ifndef PK11_LIB_LOCATION */ #ifndef WIN32 static const char *lib_name = PK11_LIB_LOCATION; -#else +#else /* ifndef WIN32 */ static const char *lib_name = PK11_LIB_LOCATION ".dll"; -#endif +#endif /* ifndef WIN32 */ void pk11_set_lib_name(const char *name) { @@ -141,8 +140,9 @@ initialize(void) { isc_mutex_init(&sessionlock); pk11_provider = getenv("PKCS11_PROVIDER"); - if (pk11_provider != NULL) + if (pk11_provider != NULL) { lib_name = pk11_provider; + } } void * @@ -150,30 +150,37 @@ pk11_mem_get(size_t size) { void *ptr; LOCK(&alloclock); - if (pk11_mctx != NULL) + if (pk11_mctx != NULL) { ptr = isc_mem_get(pk11_mctx, size); - else { + } else { ptr = malloc(size); - if (ptr != NULL) - allocsize += (int)size; + if (ptr == NULL && size != 0) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, "malloc failed: %s", + strbuf); + } } UNLOCK(&alloclock); - if (ptr != NULL) + if (ptr != NULL) { memset(ptr, 0, size); + } return (ptr); } void pk11_mem_put(void *ptr, size_t size) { - if (ptr != NULL) + if (ptr != NULL) { memset(ptr, 0, size); + } LOCK(&alloclock); - if (pk11_mctx != NULL) + if (pk11_mctx != NULL) { isc_mem_put(pk11_mctx, ptr, size); - else { - if (ptr != NULL) + } else { + if (ptr != NULL) { allocsize -= (int)size; + } free(ptr); } UNLOCK(&alloclock); @@ -188,8 +195,9 @@ pk11_initialize(isc_mem_t *mctx, const char *engine) { LOCK(&sessionlock); LOCK(&alloclock); - if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0)) + if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0)) { isc_mem_attach(mctx, &pk11_mctx); + } UNLOCK(&alloclock); if (initialized) { goto unlock; @@ -200,11 +208,12 @@ pk11_initialize(isc_mem_t *mctx, const char *engine) { ISC_LIST_INIT(tokens); ISC_LIST_INIT(actives); - if (engine != NULL) + if (engine != NULL) { lib_name = engine; + } /* Initialize the CRYPTOKI library */ - rv = pkcs_C_Initialize((CK_VOID_PTR) &pk11_init_args); + rv = pkcs_C_Initialize((CK_VOID_PTR)&pk11_init_args); if (rv == 0xfe) { result = PK11_R_NOPROVIDER; @@ -218,7 +227,7 @@ pk11_initialize(isc_mem_t *mctx, const char *engine) { } scan_slots(); - unlock: +unlock: UNLOCK(&sessionlock); return (result); } @@ -229,7 +238,7 @@ pk11_finalize(void) { isc_result_t ret; ret = free_all_sessions(); - (void) pkcs_C_Finalize(NULL_PTR); + (void)pkcs_C_Finalize(NULL_PTR); token = ISC_LIST_HEAD(tokens); while (token != NULL) { next = ISC_LIST_NEXT(token, link); @@ -237,9 +246,6 @@ pk11_finalize(void) { if (token == best_rsa_token) { best_rsa_token = NULL; } - if (token == best_dh_token) { - best_dh_token = NULL; - } if (token == best_ecdsa_token) { best_ecdsa_token = NULL; } @@ -249,17 +255,16 @@ pk11_finalize(void) { pk11_mem_put(token, sizeof(*token)); token = next; } - if (pk11_mctx != NULL) + if (pk11_mctx != NULL) { isc_mem_detach(&pk11_mctx); + } initialized = false; return (ret); } isc_result_t -pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, - bool need_services, bool rw, - bool logon, const char *pin, CK_SLOT_ID slot) -{ +pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, bool need_services, + bool rw, bool logon, const char *pin, CK_SLOT_ID slot) { pk11_token_t *token = NULL; pk11_sessionlist_t *freelist; pk11_session_t *sp; @@ -271,36 +276,43 @@ pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, ctx->session = CK_INVALID_HANDLE; ret = pk11_initialize(NULL, NULL); - if (ret != ISC_R_SUCCESS) + if (ret != ISC_R_SUCCESS) { return (ret); + } LOCK(&sessionlock); /* wait for initialization to finish */ UNLOCK(&sessionlock); - switch(optype) { + switch (optype) { case OP_ANY: - for (token = ISC_LIST_HEAD(tokens); - token != NULL; + for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) - if (token->slotid == slot) + { + if (token->slotid == slot) { break; + } + } break; default: - for (token = ISC_LIST_HEAD(tokens); - token != NULL; + for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) - if (token->slotid == slot) + { + if (token->slotid == slot) { break; + } + } break; } - if (token == NULL) + if (token == NULL) { return (ISC_R_NOTFOUND); + } /* Override the token's PIN */ if (logon && pin != NULL && *pin != '\0') { - if (strlen(pin) > PINLEN) + if (strlen(pin) > PINLEN) { return (ISC_R_RANGE); + } /* * We want to zero out the old pin before * overwriting with a new one. @@ -317,8 +329,9 @@ pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, ISC_LIST_UNLINK(*freelist, sp, link); ISC_LIST_APPEND(actives, sp, link); UNLOCK(&sessionlock); - if (logon) + if (logon) { ret = token_login(sp); + } ctx->handle = sp; ctx->session = sp->session; return (ret); @@ -326,15 +339,14 @@ pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, UNLOCK(&sessionlock); sp = pk11_mem_get(sizeof(*sp)); - if (sp == NULL) - return (ISC_R_NOMEMORY); sp->magic = SES_MAGIC; sp->token = token; sp->session = CK_INVALID_HANDLE; ISC_LINK_INIT(sp, link); ret = setup_session(sp, token, rw); - if ((ret == ISC_R_SUCCESS) && logon) + if ((ret == ISC_R_SUCCESS) && logon) { ret = token_login(sp); + } LOCK(&sessionlock); ISC_LIST_APPEND(actives, sp, link); UNLOCK(&sessionlock); @@ -345,10 +357,11 @@ pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, void pk11_return_session(pk11_context_t *ctx) { - pk11_session_t *sp = (pk11_session_t *) ctx->handle; + pk11_session_t *sp = (pk11_session_t *)ctx->handle; - if (sp == NULL) + if (sp == NULL) { return; + } ctx->handle = NULL; ctx->session = CK_INVALID_HANDLE; @@ -371,18 +384,20 @@ free_all_sessions(void) { isc_result_t ret = ISC_R_SUCCESS; isc_result_t oret; - for (token = ISC_LIST_HEAD(tokens); - token != NULL; - token = ISC_LIST_NEXT(token, link)) { + for (token = ISC_LIST_HEAD(tokens); token != NULL; + token = ISC_LIST_NEXT(token, link)) + { oret = free_session_list(&token->sessions); - if (oret != ISC_R_SUCCESS) + if (oret != ISC_R_SUCCESS) { ret = oret; + } } if (!ISC_LIST_EMPTY(actives)) { ret = ISC_R_ADDRINUSE; oret = free_session_list(&actives); - if (oret != ISC_R_SUCCESS) + if (oret != ISC_R_SUCCESS) { ret = oret; + } } return (ret); } @@ -401,8 +416,9 @@ free_session_list(pk11_sessionlist_t *slist) { UNLOCK(&sessionlock); if (sp->session != CK_INVALID_HANDLE) { rv = pkcs_C_CloseSession(sp->session); - if (rv != CKR_OK) + if (rv != CKR_OK) { ret = DST_R_CRYPTOFAILURE; + } } LOCK(&sessionlock); pk11_mem_put(sp, sizeof(*sp)); @@ -413,19 +429,19 @@ free_session_list(pk11_sessionlist_t *slist) { } static isc_result_t -setup_session(pk11_session_t *sp, pk11_token_t *token, - bool rw) -{ +setup_session(pk11_session_t *sp, pk11_token_t *token, bool rw) { CK_RV rv; CK_FLAGS flags = CKF_SERIAL_SESSION; - if (rw) + if (rw) { flags += CKF_RW_SESSION; + } - rv = pkcs_C_OpenSession(token->slotid, flags, NULL_PTR, - NULL_PTR, &sp->session); - if (rv != CKR_OK) + rv = pkcs_C_OpenSession(token->slotid, flags, NULL_PTR, NULL_PTR, + &sp->session); + if (rv != CKR_OK) { return (DST_R_CRYPTOFAILURE); + } return (ISC_R_SUCCESS); } @@ -438,30 +454,35 @@ token_login(pk11_session_t *sp) { LOCK(&sessionlock); if (!token->logged) { rv = pkcs_C_Login(sp->session, CKU_USER, - (CK_UTF8CHAR_PTR) token->pin, - (CK_ULONG) strlen(token->pin)); + (CK_UTF8CHAR_PTR)token->pin, + (CK_ULONG)strlen(token->pin)); if (rv != CKR_OK) { #if PK11_NO_LOGERR pk11_error_fatalcheck(__FILE__, __LINE__, "pkcs_C_Login", rv); -#else +#else /* if PK11_NO_LOGERR */ ret = ISC_R_NOPERM; -#endif - } else +#endif /* if PK11_NO_LOGERR */ + } else { token->logged = true; + } } UNLOCK(&sessionlock); return (ret); } -#define PK11_TRACE(fmt) \ - if (pk11_verbose_init) fprintf(stderr, fmt) -#define PK11_TRACE1(fmt, arg) \ - if (pk11_verbose_init) fprintf(stderr, fmt, arg) +#define PK11_TRACE(fmt) \ + if (pk11_verbose_init) \ + fprintf(stderr, fmt) +#define PK11_TRACE1(fmt, arg) \ + if (pk11_verbose_init) \ + fprintf(stderr, fmt, arg) #define PK11_TRACE2(fmt, arg1, arg2) \ - if (pk11_verbose_init) fprintf(stderr, fmt, arg1, arg2) -#define PK11_TRACEM(mech) \ - if (pk11_verbose_init) fprintf(stderr, #mech ": 0x%lx\n", rv) + if (pk11_verbose_init) \ + fprintf(stderr, fmt, arg1, arg2) +#define PK11_TRACEM(mech) \ + if (pk11_verbose_init) \ + fprintf(stderr, #mech ": 0x%lx\n", rv) static void scan_slots(void) { @@ -479,10 +500,10 @@ scan_slots(void) { PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, NULL_PTR, &slotCount)); PK11_TRACE1("slotCount=%lu\n", slotCount); /* it's not an error if we didn't find any providers */ - if (slotCount == 0) + if (slotCount == 0) { return; + } slotList = pk11_mem_get(sizeof(CK_SLOT_ID) * slotCount); - RUNTIME_CHECK(slotList != NULL); PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, slotList, &slotCount)); for (i = 0; i < slotCount; i++) { @@ -490,10 +511,10 @@ scan_slots(void) { PK11_TRACE2("slot#%u=0x%lx\n", i, slot); rv = pkcs_C_GetTokenInfo(slot, &tokenInfo); - if (rv != CKR_OK) + if (rv != CKR_OK) { continue; + } token = pk11_mem_get(sizeof(*token)); - RUNTIME_CHECK(token != NULL); token->magic = TOK_MAGIC; token->slotid = slot; ISC_LINK_INIT(token, link); @@ -513,42 +534,41 @@ scan_slots(void) { bad = true; PK11_TRACEM(CKM_RSA_PKCS_KEY_PAIR_GEN); } - rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_RSA_PKCS, - &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_RSA_PKCS, &mechInfo); + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_MD5_RSA_PKCS); } rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA1_RSA_PKCS, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_SHA1_RSA_PKCS); } rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_RSA_PKCS, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_SHA256_RSA_PKCS); } rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_RSA_PKCS, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_SHA512_RSA_PKCS); } rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_RSA_PKCS); } @@ -569,9 +589,9 @@ scan_slots(void) { PK11_TRACEM(CKM_EC_KEY_PAIR_GEN); } rv = pkcs_C_GetMechanismInfo(slot, CKM_ECDSA, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_ECDSA); } @@ -582,21 +602,19 @@ scan_slots(void) { } } -#if defined(CKM_EDDSA_KEY_PAIR_GEN) && defined(CKM_EDDSA) && defined(CKK_EDDSA) /* Check for EDDSA support */ - /* XXXOND: This was already broken */ bad = false; - rv = pkcs_C_GetMechanismInfo(slot, CKM_EDDSA_KEY_PAIR_GEN, + rv = pkcs_C_GetMechanismInfo(slot, CKM_EC_EDWARDS_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) { bad = true; - PK11_TRACEM(CKM_EDDSA_KEY_PAIR_GEN); + PK11_TRACEM(CKM_EC_EDWARDS_KEY_PAIR_GEN); } rv = pkcs_C_GetMechanismInfo(slot, CKM_EDDSA, &mechInfo); - if ((rv != CKR_OK) || - ((mechInfo.flags & CKF_SIGN) == 0) || - ((mechInfo.flags & CKF_VERIFY) == 0)) { + if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || + ((mechInfo.flags & CKF_VERIFY) == 0)) + { bad = true; PK11_TRACEM(CKM_EDDSA); } @@ -606,7 +624,6 @@ scan_slots(void) { best_eddsa_token = token; } } -#endif } if (slotList != NULL) { @@ -629,18 +646,23 @@ pk11_get_best_token(pk11_optype_t optype) { token = best_eddsa_token; break; default: + break; + } + if (token == NULL) { return (0); } return (token->slotid); } -unsigned int -pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { +isc_result_t +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) { unsigned int bitcnt, i; CK_BYTE top; - if (bytecnt == 0) - return (0); + if (bytecnt == 0) { + *bits = 0; + return (ISC_R_SUCCESS); + } bitcnt = bytecnt * 8; for (i = 0; i < bytecnt; i++) { top = data[i]; @@ -648,26 +670,41 @@ pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { bitcnt -= 8; continue; } - if (top & 0x80) - return (bitcnt); - if (top & 0x40) - return (bitcnt - 1); - if (top & 0x20) - return (bitcnt - 2); - if (top & 0x10) - return (bitcnt - 3); - if (top & 0x08) - return (bitcnt - 4); - if (top & 0x04) - return (bitcnt - 5); - if (top & 0x02) - return (bitcnt - 6); - if (top & 0x01) - return (bitcnt - 7); + if (top & 0x80) { + *bits = bitcnt; + return (ISC_R_SUCCESS); + } + if (top & 0x40) { + *bits = bitcnt - 1; + return (ISC_R_SUCCESS); + } + if (top & 0x20) { + *bits = bitcnt - 2; + return (ISC_R_SUCCESS); + } + if (top & 0x10) { + *bits = bitcnt - 3; + return (ISC_R_SUCCESS); + } + if (top & 0x08) { + *bits = bitcnt - 4; + return (ISC_R_SUCCESS); + } + if (top & 0x04) { + *bits = bitcnt - 5; + return (ISC_R_SUCCESS); + } + if (top & 0x02) { + *bits = bitcnt - 6; + return (ISC_R_SUCCESS); + } + if (top & 0x01) { + *bits = bitcnt - 7; + return (ISC_R_SUCCESS); + } break; } - INSIST(0); - ISC_UNREACHABLE(); + return (ISC_R_RANGE); } CK_ATTRIBUTE * @@ -680,8 +717,9 @@ pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr) { CK_ATTRIBUTE *next; next = attr + 1; - if ((next - obj->repr) >= obj->attrcnt) + if ((next - obj->repr) >= obj->attrcnt) { return (NULL); + } return (next); } @@ -689,11 +727,13 @@ CK_ATTRIBUTE * pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) { CK_ATTRIBUTE *attr; - for(attr = pk11_attribute_first(obj); - attr != NULL; - attr = pk11_attribute_next(obj, attr)) - if (attr->type == type) + for (attr = pk11_attribute_first(obj); attr != NULL; + attr = pk11_attribute_next(obj, attr)) + { + if (attr->type == type) { return (attr); + } + } return (NULL); } @@ -772,7 +812,7 @@ percent_decode(char *x, size_t *len) { return (NULL); } p += 2; - *c = (char) v; + *c = (char)v; (*len)++; break; default: @@ -790,8 +830,9 @@ pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny) { INSIST((leny == 32) || (leny == 16)); memset(buf, ' ', 32); - if (lenx > leny) + if (lenx > leny) { lenx = leny; + } memmove(buf, x, lenx); return (memcmp(buf, y, leny) == 0); } @@ -802,22 +843,16 @@ push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len) { CK_ATTRIBUTE *attr; CK_BYTE cnt = obj->attrcnt; + REQUIRE(old != NULL || cnt == 0); + obj->repr = isc_mem_get(mctx, (cnt + 1) * sizeof(*attr)); - if (obj->repr == NULL) { - obj->repr = old; - return (NULL); - } memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); - memmove(obj->repr, old, cnt * sizeof(*attr)); + if (old != NULL) { + memmove(obj->repr, old, cnt * sizeof(*attr)); + } attr = obj->repr + cnt; - attr->ulValueLen = (CK_ULONG) len; + attr->ulValueLen = (CK_ULONG)len; attr->pValue = isc_mem_get(mctx, len); - if (attr->pValue == NULL) { - memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); - isc_mem_put(mctx, obj->repr, (cnt + 1) * sizeof(*attr)); - obj->repr = old; - return (NULL); - } memset(attr->pValue, 0, len); if (old != NULL) { memset(old, 0, cnt * sizeof(*attr)); @@ -827,12 +862,15 @@ push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len) { return (attr); } -#define DST_RET(a) { ret = a; goto err; } +#define DST_RET(a) \ + { \ + ret = a; \ + goto err; \ + } isc_result_t -pk11_parse_uri(pk11_object_t *obj, const char *label, - isc_mem_t *mctx, pk11_optype_t optype) -{ +pk11_parse_uri(pk11_object_t *obj, const char *label, isc_mem_t *mctx, + pk11_optype_t optype) { CK_ATTRIBUTE *attr; pk11_token_t *token = NULL; char *uri, *p, *a, *na, *v; @@ -845,17 +883,17 @@ pk11_parse_uri(pk11_object_t *obj, const char *label, /* get values to work on */ len = strlen(label) + 1; uri = isc_mem_get(mctx, len); - if (uri == NULL) - return (ISC_R_NOMEMORY); memmove(uri, label, len); /* get the URI scheme */ p = strchr(uri, ':'); - if (p == NULL) + if (p == NULL) { DST_RET(PK11_R_NOPROVIDER); + } *p++ = '\0'; - if (strcmp(uri, "pkcs11") != 0) + if (strcmp(uri, "pkcs11") != 0) { DST_RET(PK11_R_NOPROVIDER); + } /* get attributes */ for (na = p; na != NULL;) { @@ -872,54 +910,77 @@ pk11_parse_uri(pk11_object_t *obj, const char *label, if (p != NULL) { *p++ = '\0'; v = p; - } else + } else { v = a; + } l = 0; v = percent_decode(v, &l); - if (v == NULL) + if (v == NULL) { DST_RET(PK11_R_NOPROVIDER); + } if ((a == v) || (strcmp(a, "object") == 0)) { /* object: CKA_LABEL */ attr = pk11_attribute_bytype(obj, CKA_LABEL); - if (attr != NULL) + if (attr != NULL) { DST_RET(PK11_R_NOPROVIDER); + } attr = push_attribute(obj, mctx, l); - if (attr == NULL) + if (attr == NULL) { DST_RET(ISC_R_NOMEMORY); + } attr->type = CKA_LABEL; memmove(attr->pValue, v, l); } else if (strcmp(a, "token") == 0) { /* token: CK_TOKEN_INFO label */ - if (token == NULL) + if (token == NULL) { for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) - if (pk11strcmp(v, l, token->name, 32)) + { + if (pk11strcmp(v, l, token->name, 32)) { break; + } + } + } } else if (strcmp(a, "manufacturer") == 0) { /* manufacturer: CK_TOKEN_INFO manufacturerID */ - if (token == NULL) + if (token == NULL) { for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) + { if (pk11strcmp(v, l, token->manuf, 32)) + { break; + } + } + } } else if (strcmp(a, "serial") == 0) { /* serial: CK_TOKEN_INFO serialNumber */ - if (token == NULL) + if (token == NULL) { for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) + { if (pk11strcmp(v, l, token->serial, 16)) + { break; + } + } + } } else if (strcmp(a, "model") == 0) { /* model: CK_TOKEN_INFO model */ - if (token == NULL) + if (token == NULL) { for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) + { if (pk11strcmp(v, l, token->model, 16)) + { break; + } + } + } } else if (strcmp(a, "library-manufacturer") == 0) { /* ignored */ } else if (strcmp(a, "library-description") == 0) { @@ -929,41 +990,51 @@ pk11_parse_uri(pk11_object_t *obj, const char *label, } else if (strcmp(a, "object-type") == 0) { /* object-type: CKA_CLASS */ /* only private makes sense */ - if (strcmp(v, "private") != 0) + if (strcmp(v, "private") != 0) { DST_RET(PK11_R_NOPROVIDER); + } } else if (strcmp(a, "id") == 0) { /* id: CKA_ID */ attr = pk11_attribute_bytype(obj, CKA_ID); - if (attr != NULL) + if (attr != NULL) { DST_RET(PK11_R_NOPROVIDER); + } attr = push_attribute(obj, mctx, l); - if (attr == NULL) + if (attr == NULL) { DST_RET(ISC_R_NOMEMORY); + } attr->type = CKA_ID; memmove(attr->pValue, v, l); } else if (strcmp(a, "pin-source") == 0) { /* pin-source: PIN */ ret = isc_stdio_open(v, "r", &stream); - if (ret != ISC_R_SUCCESS) + if (ret != ISC_R_SUCCESS) { goto err; + } memset(pin, 0, PINLEN + 1); ret = isc_stdio_read(pin, 1, PINLEN + 1, stream, &l); - if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF)) + if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF)) { goto err; - if (l > PINLEN) + } + if (l > PINLEN) { DST_RET(ISC_R_RANGE); + } ret = isc_stdio_close(stream); stream = NULL; - if (ret != ISC_R_SUCCESS) + if (ret != ISC_R_SUCCESS) { goto err; + } gotpin = true; - } else + } else { DST_RET(PK11_R_NOPROVIDER); + } } if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) && (pk11_attribute_bytype(obj, CKA_ID) == NULL)) + { DST_RET(ISC_R_NOTFOUND); + } if (token == NULL) { if (optype == OP_RSA) { @@ -974,8 +1045,9 @@ pk11_parse_uri(pk11_object_t *obj, const char *label, token = best_eddsa_token; } } - if (token == NULL) + if (token == NULL) { DST_RET(ISC_R_NOTFOUND); + } obj->slot = token->slotid; if (gotpin) { memmove(token->pin, pin, PINLEN + 1); @@ -984,17 +1056,17 @@ pk11_parse_uri(pk11_object_t *obj, const char *label, ret = ISC_R_SUCCESS; - err: - if (stream != NULL) - (void) isc_stdio_close(stream); +err: + if (stream != NULL) { + (void)isc_stdio_close(stream); + } isc_mem_put(mctx, uri, len); return (ret); } void -pk11_error_fatalcheck(const char *file, int line, - const char *funcname, CK_RV rv) -{ +pk11_error_fatalcheck(const char *file, int line, const char *funcname, + CK_RV rv) { isc_error_fatal(file, line, "%s: Error = 0x%.8lX\n", funcname, rv); } @@ -1005,13 +1077,12 @@ pk11_dump_tokens(void) { printf("DEFAULTS\n"); printf("\tbest_rsa_token=%p\n", best_rsa_token); - printf("\tbest_dh_token=%p\n", best_dh_token); printf("\tbest_ecdsa_token=%p\n", best_ecdsa_token); printf("\tbest_eddsa_token=%p\n", best_eddsa_token); - for (token = ISC_LIST_HEAD(tokens); - token != NULL; - token = ISC_LIST_NEXT(token, link)) { + for (token = ISC_LIST_HEAD(tokens); token != NULL; + token = ISC_LIST_NEXT(token, link)) + { printf("\nTOKEN\n"); printf("\taddress=%p\n", token); printf("\tslotID=%lu\n", token->slotid); @@ -1026,8 +1097,9 @@ pk11_dump_tokens(void) { printf("RSA"); } if (token->operations & (1 << OP_ECDSA)) { - if (!first) + if (!first) { printf(","); + } printf("EC"); } printf(")\n"); diff --git a/lib/isc/pk11_result.c b/lib/isc/pk11_result.c index 0aaccf65..a8afed6a 100644 --- a/lib/isc/pk11_result.c +++ b/lib/isc/pk11_result.c @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> #include <stddef.h> #include <isc/once.h> @@ -18,24 +17,22 @@ #include <pk11/result.h> static const char *text[PK11_R_NRESULTS] = { - "PKCS#11 initialization failed", /*%< 0 */ - "no PKCS#11 provider", /*%< 1 */ - "PKCS#11 no random service", /*%< 2 */ - "PKCS#11 no digist service", /*%< 3 */ - "PKCS#11 no AES service", /*%< 4 */ + "PKCS#11 initialization failed", /*%< 0 */ + "no PKCS#11 provider", /*%< 1 */ + "PKCS#11 no random service", /*%< 2 */ + "PKCS#11 no digist service", /*%< 3 */ + "PKCS#11 no AES service", /*%< 4 */ }; static const char *ids[PK11_R_NRESULTS] = { - "PK11_R_INITFAILED", - "PK11_R_NOPROVIDER", - "PK11_R_NORANDOMSERVICE", - "PK11_R_NODIGESTSERVICE", + "PK11_R_INITFAILED", "PK11_R_NOPROVIDER", + "PK11_R_NORANDOMSERVICE", "PK11_R_NODIGESTSERVICE", "PK11_R_NOAESSERVICE", }; -#define PK11_RESULT_RESULTSET 2 +#define PK11_RESULT_RESULTSET 2 -static isc_once_t once = ISC_ONCE_INIT; +static isc_once_t once = ISC_ONCE_INIT; static void initialize_action(void) { diff --git a/lib/isc/pool.c b/lib/isc/pool.c index 8fb2a45e..951e8000 100644 --- a/lib/isc/pool.c +++ b/lib/isc/pool.c @@ -3,22 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <string.h> #include <isc/mem.h> -#include <isc/random.h> #include <isc/pool.h> +#include <isc/random.h> #include <isc/util.h> /*** @@ -26,12 +23,12 @@ ***/ struct isc_pool { - isc_mem_t * mctx; - unsigned int count; - isc_pooldeallocator_t free; - isc_poolinitializer_t init; - void * initarg; - void ** pool; + isc_mem_t *mctx; + unsigned int count; + isc_pooldeallocator_t free; + isc_poolinitializer_t init; + void *initarg; + void **pool; }; /*** @@ -43,8 +40,6 @@ alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) { isc_pool_t *pool; pool = isc_mem_get(mctx, sizeof(*pool)); - if (pool == NULL) - return (ISC_R_NOMEMORY); pool->count = count; pool->free = NULL; pool->init = NULL; @@ -52,10 +47,6 @@ alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) { pool->mctx = NULL; isc_mem_attach(mctx, &pool->mctx); pool->pool = isc_mem_get(mctx, count * sizeof(void *)); - if (pool->pool == NULL) { - isc_mem_put(mctx, pool, sizeof(*pool)); - return (ISC_R_NOMEMORY); - } memset(pool->pool, 0, count * sizeof(void *)); *poolp = pool; @@ -64,10 +55,8 @@ alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) { isc_result_t isc_pool_create(isc_mem_t *mctx, unsigned int count, - isc_pooldeallocator_t release, - isc_poolinitializer_t init, void *initarg, - isc_pool_t **poolp) -{ + isc_pooldeallocator_t release, isc_poolinitializer_t init, + void *initarg, isc_pool_t **poolp) { isc_pool_t *pool = NULL; isc_result_t result; unsigned int i; @@ -76,8 +65,9 @@ isc_pool_create(isc_mem_t *mctx, unsigned int count, /* Allocate the pool structure */ result = alloc_pool(mctx, count, &pool); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } pool->free = release; pool->init = init; @@ -109,8 +99,7 @@ isc_pool_count(isc_pool_t *pool) { isc_result_t isc_pool_expand(isc_pool_t **sourcep, unsigned int count, - isc_pool_t **targetp) -{ + isc_pool_t **targetp) { isc_result_t result; isc_pool_t *pool; @@ -118,14 +107,16 @@ isc_pool_expand(isc_pool_t **sourcep, unsigned int count, REQUIRE(targetp != NULL && *targetp == NULL); pool = *sourcep; + *sourcep = NULL; if (count > pool->count) { isc_pool_t *newpool = NULL; unsigned int i; /* Allocate a new pool structure */ result = alloc_pool(pool->mctx, count, &newpool); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } newpool->free = pool->free; newpool->init = pool->init; @@ -151,7 +142,6 @@ isc_pool_expand(isc_pool_t **sourcep, unsigned int count, pool = newpool; } - *sourcep = NULL; *targetp = pool; return (ISC_R_SUCCESS); } @@ -160,11 +150,12 @@ void isc_pool_destroy(isc_pool_t **poolp) { unsigned int i; isc_pool_t *pool = *poolp; + *poolp = NULL; for (i = 0; i < pool->count; i++) { - if (pool->free != NULL && pool->pool[i] != NULL) + if (pool->free != NULL && pool->pool[i] != NULL) { pool->free(&pool->pool[i]); + } } isc_mem_put(pool->mctx, pool->pool, pool->count * sizeof(void *)); isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); - *poolp = NULL; } diff --git a/lib/isc/portset.c b/lib/isc/portset.c index 87be245c..e24673c8 100644 --- a/lib/isc/portset.c +++ b/lib/isc/portset.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> #include <isc/mem.h> #include <isc/portset.h> @@ -31,7 +28,7 @@ * the second most significant bit of buf[0] corresponds to port 1. */ struct isc_portset { - unsigned int nports; /*%< number of ports in the set */ + unsigned int nports; /*%< number of ports in the set */ uint32_t buf[ISC_PORTSET_BUFSIZE]; }; @@ -63,8 +60,6 @@ isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp) { REQUIRE(portsetp != NULL && *portsetp == NULL); portset = isc_mem_get(mctx, sizeof(*portset)); - if (portset == NULL) - return (ISC_R_NOMEMORY); /* Make the set 'empty' by default */ memset(portset, 0, sizeof(*portset)); @@ -111,8 +106,7 @@ isc_portset_remove(isc_portset_t *portset, in_port_t port) { void isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo, - in_port_t port_hi) -{ + in_port_t port_hi) { in_port_t p; REQUIRE(portset != NULL); @@ -126,8 +120,7 @@ isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo, void isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo, - in_port_t port_hi) -{ + in_port_t port_hi) { in_port_t p; REQUIRE(portset != NULL); diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in index af4fd6ec..39b7bac2 100644 --- a/lib/isc/pthreads/Makefile.in +++ b/lib/isc/pthreads/Makefile.in @@ -2,7 +2,7 @@ # # 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 http://mozilla.org/MPL/2.0/. +# 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. diff --git a/lib/isc/pthreads/condition.c b/lib/isc/pthreads/condition.c index 0f9c70f9..ac9fcea8 100644 --- a/lib/isc/pthreads/condition.c +++ b/lib/isc/pthreads/condition.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <errno.h> #include <isc/condition.h> @@ -40,10 +37,11 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { * If we have a range error ts.tv_sec is most probably a signed * 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge. */ - if (result == ISC_R_RANGE) + if (result == ISC_R_RANGE) { ts.tv_sec = INT_MAX; - else if (result != ISC_R_SUCCESS) + } else if (result != ISC_R_SUCCESS) { return (result); + } /*! * POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds @@ -54,18 +52,19 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { do { #if ISC_MUTEX_PROFILE presult = pthread_cond_timedwait(c, &m->mutex, &ts); -#else +#else /* if ISC_MUTEX_PROFILE */ presult = pthread_cond_timedwait(c, m, &ts); -#endif - if (presult == 0) +#endif /* if ISC_MUTEX_PROFILE */ + if (presult == 0) { return (ISC_R_SUCCESS); - if (presult == ETIMEDOUT) + } + if (presult == ETIMEDOUT) { return (ISC_R_TIMEDOUT); + } } while (presult == EINTR); strerror_r(presult, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "pthread_cond_timedwait() returned %s", - strbuf); + "pthread_cond_timedwait() returned %s", strbuf); return (ISC_R_UNEXPECTED); } diff --git a/lib/isc/pthreads/include/.clang-format b/lib/isc/pthreads/include/.clang-format new file mode 120000 index 00000000..e919bbad --- /dev/null +++ b/lib/isc/pthreads/include/.clang-format @@ -0,0 +1 @@ +../../../../.clang-format.headers
\ No newline at end of file diff --git a/lib/isc/pthreads/include/isc/condition.h b/lib/isc/pthreads/include/isc/condition.h index 9cc04d01..aed1db08 100644 --- a/lib/isc/pthreads/include/isc/condition.h +++ b/lib/isc/pthreads/include/isc/condition.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -25,37 +25,34 @@ typedef pthread_cond_t isc_condition_t; -#define isc_condition_init(cond) \ - if (pthread_cond_init(cond, NULL) != 0) { \ - char isc_condition_strbuf[ISC_STRERRORSIZE]; \ - strerror_r(errno, isc_condition_strbuf, \ - sizeof(isc_condition_strbuf)); \ - isc_error_fatal(__FILE__, __LINE__, \ - "pthread_cond_init failed: %s", \ - isc_condition_strbuf); \ +#define isc_condition_init(cond) \ + if (pthread_cond_init(cond, NULL) != 0) { \ + char isc_condition_strbuf[ISC_STRERRORSIZE]; \ + strerror_r(errno, isc_condition_strbuf, \ + sizeof(isc_condition_strbuf)); \ + isc_error_fatal(__FILE__, __LINE__, \ + "pthread_cond_init failed: %s", \ + isc_condition_strbuf); \ } #if ISC_MUTEX_PROFILE -#define isc_condition_wait(cp, mp) \ - ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) -#else -#define isc_condition_wait(cp, mp) \ - ((pthread_cond_wait((cp), (mp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) -#endif +#define isc_condition_wait(cp, mp) \ + ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? ISC_R_SUCCESS \ + : ISC_R_UNEXPECTED) +#else /* if ISC_MUTEX_PROFILE */ +#define isc_condition_wait(cp, mp) \ + ((pthread_cond_wait((cp), (mp)) == 0) ? ISC_R_SUCCESS \ + : ISC_R_UNEXPECTED) +#endif /* if ISC_MUTEX_PROFILE */ #define isc_condition_signal(cp) \ - ((pthread_cond_signal((cp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) + ((pthread_cond_signal((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_condition_broadcast(cp) \ - ((pthread_cond_broadcast((cp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) + ((pthread_cond_broadcast((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_condition_destroy(cp) \ - ((pthread_cond_destroy((cp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) + ((pthread_cond_destroy((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) ISC_LANG_BEGINDECLS diff --git a/lib/isc/pthreads/include/isc/mutex.h b/lib/isc/pthreads/include/isc/mutex.h index 4f3a4d46..7192d343 100644 --- a/lib/isc/pthreads/include/isc/mutex.h +++ b/lib/isc/pthreads/include/isc/mutex.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_MUTEX_H #define ISC_MUTEX_H 1 @@ -19,7 +18,7 @@ #include <stdio.h> #include <isc/lang.h> -#include <isc/result.h> /* for ISC_R_ codes */ +#include <isc/result.h> /* for ISC_R_ codes */ ISC_LANG_BEGINDECLS @@ -31,9 +30,11 @@ ISC_LANG_BEGINDECLS #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) extern pthread_mutexattr_t isc__mutex_attrs; #define ISC__MUTEX_ATTRS &isc__mutex_attrs -#else +#else /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \ + * defined(PTHREAD_MUTEX_ERRORCHECK) */ #define ISC__MUTEX_ATTRS NULL -#endif +#endif /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \ + * defined(PTHREAD_MUTEX_ERRORCHECK) */ /* XXX We could do fancier error handling... */ @@ -45,92 +46,82 @@ extern pthread_mutexattr_t isc__mutex_attrs; */ #ifndef ISC_MUTEX_PROFILE #define ISC_MUTEX_PROFILE 0 -#endif +#endif /* ifndef ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE typedef struct isc_mutexstats isc_mutexstats_t; typedef struct { - pthread_mutex_t mutex; /*%< The actual mutex. */ - isc_mutexstats_t * stats; /*%< Mutex statistics. */ + pthread_mutex_t mutex; /*%< The actual mutex. */ + isc_mutexstats_t *stats; /*%< Mutex statistics. */ } isc_mutex_t; -#else -typedef pthread_mutex_t isc_mutex_t; -#endif - +#else /* if ISC_MUTEX_PROFILE */ +typedef pthread_mutex_t isc_mutex_t; +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE -#define isc_mutex_init(mp) \ - isc_mutex_init_profile((mp), __FILE__, __LINE__) -#else +#define isc_mutex_init(mp) isc_mutex_init_profile((mp), __FILE__, __LINE__) +#else /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) -#define isc_mutex_init(mp) \ - isc_mutex_init_errcheck((mp)) -#else -#define isc_mutex_init(mp) \ - isc__mutex_init((mp), __FILE__, __LINE__) -void isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line); -#endif -#endif +#define isc_mutex_init(mp) isc_mutex_init_errcheck((mp)) +#else /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */ +#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__) +void +isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line); +#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */ +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE +#define isc_mutex_lock(mp) isc_mutex_lock_profile((mp), __FILE__, __LINE__) +#else /* if ISC_MUTEX_PROFILE */ #define isc_mutex_lock(mp) \ - isc_mutex_lock_profile((mp), __FILE__, __LINE__) -#else -#define isc_mutex_lock(mp) \ - ((pthread_mutex_lock((mp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) -#endif + ((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE +#define isc_mutex_unlock(mp) isc_mutex_unlock_profile((mp), __FILE__, __LINE__) +#else /* if ISC_MUTEX_PROFILE */ #define isc_mutex_unlock(mp) \ - isc_mutex_unlock_profile((mp), __FILE__, __LINE__) -#else -#define isc_mutex_unlock(mp) \ - ((pthread_mutex_unlock((mp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) -#endif + ((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE +#define isc_mutex_trylock(mp) \ + ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? ISC_R_SUCCESS \ + : ISC_R_LOCKBUSY) +#else /* if ISC_MUTEX_PROFILE */ #define isc_mutex_trylock(mp) \ - ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_LOCKBUSY) -#else -#define isc_mutex_trylock(mp) \ - ((pthread_mutex_trylock((mp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_LOCKBUSY) -#endif + ((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY) +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE #define isc_mutex_destroy(mp) \ - (RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0)) -#else -#define isc_mutex_destroy(mp) \ - (RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)) -#endif + RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0) +#else /* if ISC_MUTEX_PROFILE */ +#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0) +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE #define isc_mutex_stats(fp) isc_mutex_statsprofile(fp); -#else +#else /* if ISC_MUTEX_PROFILE */ #define isc_mutex_stats(fp) -#endif +#endif /* if ISC_MUTEX_PROFILE */ #if ISC_MUTEX_PROFILE void -isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line); +isc_mutex_init_profile(isc_mutex_t *mp, const char *_file, int _line); isc_result_t -isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line); +isc_mutex_lock_profile(isc_mutex_t *mp, const char *_file, int _line); isc_result_t -isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line); +isc_mutex_unlock_profile(isc_mutex_t *mp, const char *_file, int _line); void isc_mutex_statsprofile(FILE *fp); +#endif /* ISC_MUTEX_PROFILE */ void isc_mutex_init_errcheck(isc_mutex_t *mp); -#endif /* ISC_MUTEX_PROFILE */ - ISC_LANG_ENDDECLS #endif /* ISC_MUTEX_H */ diff --git a/lib/isc/pthreads/include/isc/once.h b/lib/isc/pthreads/include/isc/once.h index 71cd16b8..3f9fe73a 100644 --- a/lib/isc/pthreads/include/isc/once.h +++ b/lib/isc/pthreads/include/isc/once.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_ONCE_H #define ISC_ONCE_H 1 @@ -27,7 +26,6 @@ typedef pthread_once_t isc_once_t; /* XXX We could do fancier error handling... */ #define isc_once_do(op, f) \ - ((pthread_once((op), (f)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) + ((pthread_once((op), (f)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif /* ISC_ONCE_H */ diff --git a/lib/isc/pthreads/include/isc/thread.h b/lib/isc/pthreads/include/isc/thread.h index 6d969500..f9d3f69f 100644 --- a/lib/isc/pthreads/include/isc/thread.h +++ b/lib/isc/pthreads/include/isc/thread.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_THREAD_H #define ISC_THREAD_H 1 @@ -19,7 +18,7 @@ #if defined(HAVE_PTHREAD_NP_H) #include <pthread_np.h> -#endif +#endif /* if defined(HAVE_PTHREAD_NP_H) */ #include <isc/lang.h> #include <isc/result.h> @@ -27,15 +26,17 @@ ISC_LANG_BEGINDECLS typedef pthread_t isc_thread_t; -typedef void * isc_threadresult_t; -typedef void * isc_threadarg_t; +typedef void * isc_threadresult_t; +typedef void * isc_threadarg_t; typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t); -typedef pthread_key_t isc_thread_key_t; -isc_result_t +void isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *); void +isc_thread_join(isc_thread_t thread, isc_threadresult_t *result); + +void isc_thread_setconcurrency(unsigned int level); void @@ -47,19 +48,24 @@ isc_thread_setname(isc_thread_t thread, const char *name); isc_result_t isc_thread_setaffinity(int cpu); -/* XXX We could do fancier error handling... */ - -#define isc_thread_join(t, rp) \ - ((pthread_join((t), (rp)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED) - -#define isc_thread_self \ - (unsigned long)pthread_self - -#define isc_thread_key_create pthread_key_create -#define isc_thread_key_getspecific pthread_getspecific -#define isc_thread_key_setspecific pthread_setspecific -#define isc_thread_key_delete pthread_key_delete +#define isc_thread_self (unsigned long)pthread_self + +/*** + *** Thread-Local Storage + ***/ + +#if defined(HAVE_TLS) +#if defined(HAVE_THREAD_LOCAL) +#include <threads.h> +#define ISC_THREAD_LOCAL static thread_local +#elif defined(HAVE___THREAD) +#define ISC_THREAD_LOCAL static __thread +#else /* if defined(HAVE_THREAD_LOCAL) */ +#error "Unknown method for defining a TLS variable!" +#endif /* if defined(HAVE_THREAD_LOCAL) */ +#else /* if defined(HAVE_TLS) */ +#error "Thread-local storage support is required!" +#endif /* if defined(HAVE_TLS) */ ISC_LANG_ENDDECLS diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c index 68b78240..1b5a8398 100644 --- a/lib/isc/pthreads/mutex.c +++ b/lib/isc/pthreads/mutex.c @@ -3,52 +3,49 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - +#include <errno.h> #include <stdbool.h> #include <stdio.h> -#include <time.h> #include <sys/time.h> -#include <errno.h> +#include <time.h> #include <isc/mutex.h> -#include <isc/util.h> +#include <isc/once.h> #include <isc/print.h> #include <isc/strerr.h> #include <isc/string.h> -#include <isc/once.h> +#include <isc/util.h> #if ISC_MUTEX_PROFILE /*@{*/ /*% Operations on timevals; adapted from FreeBSD's sys/time.h */ -#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) -#define timevaladd(vvp, uvp) \ - do { \ - (vvp)->tv_sec += (uvp)->tv_sec; \ - (vvp)->tv_usec += (uvp)->tv_usec; \ - if ((vvp)->tv_usec >= 1000000) { \ - (vvp)->tv_sec++; \ - (vvp)->tv_usec -= 1000000; \ - } \ +#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) +#define timevaladd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_usec += (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ } while (0) -#define timevalsub(vvp, uvp) \ - do { \ - (vvp)->tv_sec -= (uvp)->tv_sec; \ - (vvp)->tv_usec -= (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ +#define timevalsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_usec -= (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ } while (0) /*@}*/ @@ -56,33 +53,32 @@ #define ISC_MUTEX_MAX_LOCKERS 32 typedef struct { - const char * file; - int line; - unsigned count; - struct timeval locked_total; - struct timeval wait_total; + const char *file; + int line; + unsigned count; + struct timeval locked_total; + struct timeval wait_total; } isc_mutexlocker_t; struct isc_mutexstats { - const char * file; /*%< File mutex was created in. */ - int line; /*%< Line mutex was created on. */ - unsigned count; - struct timeval lock_t; - struct timeval locked_total; - struct timeval wait_total; - isc_mutexlocker_t * cur_locker; - isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS]; + const char *file; /*%< File mutex was created in. */ + int line; /*%< Line mutex was created on. */ + unsigned count; + struct timeval lock_t; + struct timeval locked_total; + struct timeval wait_total; + isc_mutexlocker_t *cur_locker; + isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS]; }; #ifndef ISC_MUTEX_PROFTABLESIZE #define ISC_MUTEX_PROFTABLESIZE (1024 * 1024) -#endif +#endif /* ifndef ISC_MUTEX_PROFTABLESIZE */ static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE]; static int stats_next = 0; static bool stats_init = false; static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER; - void isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) { int i, err; @@ -90,13 +86,15 @@ isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) { err = pthread_mutex_init(&mp->mutex, NULL); if (err != 0) { strerror_r(err, strbuf, sizeof(strbuf)); - isc_error_fatal(file, line, "pthread_mutex_init failed: %s", strbuf); + isc_error_fatal(file, line, "pthread_mutex_init failed: %s", + strbuf); } RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0); - if (stats_init == false) + if (!stats_init) { stats_init = true; + } /* * If all statistics entries have been used, give up and trigger an @@ -134,8 +132,9 @@ isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) { gettimeofday(&prelock_t, NULL); - if (pthread_mutex_lock(&mp->mutex) != 0) + if (pthread_mutex_lock(&mp->mutex) != 0) { return (ISC_R_UNEXPECTED); + } gettimeofday(&postlock_t, NULL); mp->stats->lock_t = postlock_t; @@ -152,7 +151,8 @@ isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) { locker->line = line; break; } else if (mp->stats->lockers[i].file == file && - mp->stats->lockers[i].line == line) { + mp->stats->lockers[i].line == line) + { locker = &mp->stats->lockers[i]; break; } @@ -183,11 +183,10 @@ isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) { mp->stats->cur_locker = NULL; } - return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \ - ISC_R_SUCCESS : ISC_R_UNEXPECTED); + return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? ISC_R_SUCCESS + : ISC_R_UNEXPECTED); } - void isc_mutex_statsprofile(FILE *fp) { isc_mutexlocker_t *locker; @@ -199,20 +198,20 @@ isc_mutex_statsprofile(FILE *fp) { stats[i].file, stats[i].line, stats[i].count, stats[i].locked_total.tv_sec, stats[i].locked_total.tv_usec, - stats[i].wait_total.tv_sec, - stats[i].wait_total.tv_usec, + stats[i].wait_total.tv_sec, stats[i].wait_total.tv_usec, i); for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) { locker = &stats[i].lockers[j]; - if (locker->file == NULL) + if (locker->file == NULL) { continue; - fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", + } + fprintf(fp, + " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", locker->file, locker->line, locker->count, locker->locked_total.tv_sec, locker->locked_total.tv_usec, locker->wait_total.tv_sec, - locker->wait_total.tv_usec, - i); + locker->wait_total.tv_usec, i); } } } @@ -228,8 +227,8 @@ static isc_once_t once_errcheck = ISC_ONCE_INIT; static void initialize_errcheck(void) { RUNTIME_CHECK(pthread_mutexattr_init(&errcheck) == 0); - RUNTIME_CHECK(pthread_mutexattr_settype - (&errcheck, PTHREAD_MUTEX_ERRORCHECK) == 0); + RUNTIME_CHECK(pthread_mutexattr_settype(&errcheck, + PTHREAD_MUTEX_ERRORCHECK) == 0); errcheck_initialized = true; } @@ -244,19 +243,22 @@ isc_mutex_init_errcheck(isc_mutex_t *mp) { err = pthread_mutex_init(mp, &errcheck); if (err != 0) { strerror_r(err, strbuf, sizeof(strbuf)); - isc_error_fatal(file, line, "pthread_mutex_init failed: %s", strbuf); + isc_error_fatal(file, line, "pthread_mutex_init failed: %s", + strbuf); } } -#endif +#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */ #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) pthread_mutexattr_t isc__mutex_attrs = { - PTHREAD_MUTEX_ERRORCHECK, /* m_type */ - 0 /* m_flags, which appears to be unused. */ + PTHREAD_MUTEX_ERRORCHECK, /* m_type */ + 0 /* m_flags, which appears to be unused. */ }; -#endif +#endif /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \ + * defined(PTHREAD_MUTEX_ERRORCHECK) */ -#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE +#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && \ + !ISC_MUTEX_PROFILE #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP static bool attr_initialized = false; @@ -268,8 +270,8 @@ static isc_once_t once_attr = ISC_ONCE_INIT; static void initialize_attr(void) { RUNTIME_CHECK(pthread_mutexattr_init(&attr) == 0); - RUNTIME_CHECK(pthread_mutexattr_settype - (&attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0); + RUNTIME_CHECK(pthread_mutexattr_settype( + &attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0); attr_initialized = true; } #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ @@ -284,13 +286,15 @@ isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) { RUNTIME_CHECK(result == ISC_R_SUCCESS); err = pthread_mutex_init(mp, &attr); -#else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ +#else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS); #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ if (err != 0) { char strbuf[ISC_STRERRORSIZE]; strerror_r(err, strbuf, sizeof(strbuf)); - isc_error_fatal(file, line, "pthread_mutex_init failed: %s", strbuf); + isc_error_fatal(file, line, "pthread_mutex_init failed: %s", + strbuf); } } -#endif +#endif /* if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && \ + * !ISC_MUTEX_PROFILE */ diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c index c40ccf1e..b17b36d2 100644 --- a/lib/isc/pthreads/thread.c +++ b/lib/isc/pthreads/thread.c @@ -3,77 +3,94 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #if defined(HAVE_SCHED_H) #include <sched.h> -#endif +#endif /* if defined(HAVE_SCHED_H) */ #if defined(HAVE_CPUSET_H) -#include <sys/param.h> #include <sys/cpuset.h> -#endif +#include <sys/param.h> +#endif /* if defined(HAVE_CPUSET_H) */ #if defined(HAVE_SYS_PROCSET_H) -#include <sys/types.h> #include <sys/processor.h> #include <sys/procset.h> -#endif +#include <sys/types.h> +#endif /* if defined(HAVE_SYS_PROCSET_H) */ +#include <isc/strerr.h> #include <isc/thread.h> #include <isc/util.h> #ifndef THREAD_MINSTACKSIZE -#define THREAD_MINSTACKSIZE (1024U * 1024) -#endif +#define THREAD_MINSTACKSIZE (1024U * 1024) +#endif /* ifndef THREAD_MINSTACKSIZE */ + +#define _FATAL(r, f) \ + { \ + char strbuf[ISC_STRERRORSIZE]; \ + strerror_r(r, strbuf, sizeof(strbuf)); \ + isc_error_fatal(__FILE__, __LINE__, f " failed: %s", strbuf); \ + } -isc_result_t +void isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg, - isc_thread_t *thread) -{ + isc_thread_t *thread) { pthread_attr_t attr; #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ - defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) + defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) size_t stacksize; -#endif +#endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ + * defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */ int ret; pthread_attr_init(&attr); #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ - defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) + defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) ret = pthread_attr_getstacksize(&attr, &stacksize); - if (ret != 0) - return (ISC_R_UNEXPECTED); + if (ret != 0) { + _FATAL(ret, "pthread_attr_getstacksize()"); + } if (stacksize < THREAD_MINSTACKSIZE) { ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE); - if (ret != 0) - return (ISC_R_UNEXPECTED); + if (ret != 0) { + _FATAL(ret, "pthread_attr_setstacksize()"); + } } -#endif +#endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ + * defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */ ret = pthread_create(thread, &attr, func, arg); - if (ret != 0) - return (ISC_R_UNEXPECTED); + if (ret != 0) { + _FATAL(ret, "pthread_create()"); + } pthread_attr_destroy(&attr); - return (ISC_R_SUCCESS); + return; +} + +void +isc_thread_join(isc_thread_t thread, isc_threadresult_t *result) { + int ret = pthread_join(thread, result); + if (ret != 0) { + _FATAL(ret, "pthread_join()"); + } } #ifdef __NetBSD__ -#define pthread_setconcurrency(a) (void) a/* nothing */ -#endif +#define pthread_setconcurrency(a) (void)a /* nothing */ +#endif /* ifdef __NetBSD__ */ void isc_thread_setconcurrency(unsigned int level) { @@ -86,29 +103,29 @@ isc_thread_setname(isc_thread_t thread, const char *name) { /* * macOS has pthread_setname_np but only works on the * current thread so it's not used here - */ + */ #if defined(__NetBSD__) (void)pthread_setname_np(thread, name, NULL); -#else +#else /* if defined(__NetBSD__) */ (void)pthread_setname_np(thread, name); -#endif +#endif /* if defined(__NetBSD__) */ #elif defined(HAVE_PTHREAD_SET_NAME_NP) (void)pthread_set_name_np(thread, name); -#else +#else /* if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) */ UNUSED(thread); UNUSED(name); -#endif +#endif /* if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) */ } void isc_thread_yield(void) { #if defined(HAVE_SCHED_YIELD) sched_yield(); -#elif defined( HAVE_PTHREAD_YIELD) +#elif defined(HAVE_PTHREAD_YIELD) pthread_yield(); -#elif defined( HAVE_PTHREAD_YIELD_NP) +#elif defined(HAVE_PTHREAD_YIELD_NP) pthread_yield_np(); -#endif +#endif /* if defined(HAVE_SCHED_YIELD) */ } isc_result_t @@ -126,23 +143,22 @@ isc_thread_setaffinity(int cpu) { #if defined(__NetBSD__) cpuset_t *cset; cset = cpuset_create(); - if (cset == NULL) + if (cset == NULL) { return (ISC_R_FAILURE); + } cpuset_set(cpu, cset); - if (pthread_setaffinity_np(pthread_self(), - cpuset_size(cset), cset) != 0) - { + if (pthread_setaffinity_np(pthread_self(), cpuset_size(cset), cset) != + 0) { cpuset_destroy(cset); return (ISC_R_FAILURE); } cpuset_destroy(cset); -#else /* linux? */ +#else /* linux? */ cpu_set_t set; CPU_ZERO(&set); CPU_SET(cpu, &set); - if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), - &set) != 0) - { + if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &set) != + 0) { return (ISC_R_FAILURE); } #endif /* __NetBSD__ */ @@ -150,8 +166,8 @@ isc_thread_setaffinity(int cpu) { if (processor_bind(P_LWPID, P_MYID, cpu, NULL) != 0) { return (ISC_R_FAILURE); } -#else +#else /* if defined(HAVE_CPUSET_SETAFFINITY) */ UNUSED(cpu); -#endif +#endif /* if defined(HAVE_CPUSET_SETAFFINITY) */ return (ISC_R_SUCCESS); } diff --git a/lib/isc/queue.c b/lib/isc/queue.c new file mode 100644 index 00000000..d16c8e69 --- /dev/null +++ b/lib/isc/queue.c @@ -0,0 +1,232 @@ +/* + * 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. + */ + +#include <inttypes.h> + +#include <isc/align.h> +#include <isc/atomic.h> +#include <isc/hp.h> +#include <isc/mem.h> +#include <isc/queue.h> +#include <isc/string.h> + +#define BUFFER_SIZE 1024 + +#define MAX_THREADS 128 + +#define ALIGNMENT 128 + +static uintptr_t nulluintptr = (uintptr_t)NULL; + +typedef struct node { + atomic_uint_fast32_t deqidx; + atomic_uintptr_t items[BUFFER_SIZE]; + atomic_uint_fast32_t enqidx; + atomic_uintptr_t next; + isc_mem_t *mctx; +} node_t; + +/* we just need one Hazard Pointer */ +#define HP_TAIL 0 +#define HP_HEAD 0 + +struct isc_queue { + alignas(ALIGNMENT) atomic_uintptr_t head; + alignas(ALIGNMENT) atomic_uintptr_t tail; + isc_mem_t *mctx; + int max_threads; + int taken; + isc_hp_t *hp; + void *alloced_ptr; +}; + +static node_t * +node_new(isc_mem_t *mctx, uintptr_t item) { + node_t *node = isc_mem_get(mctx, sizeof(*node)); + *node = (node_t){ .mctx = NULL }; + + atomic_init(&node->deqidx, 0); + atomic_init(&node->enqidx, 1); + atomic_init(&node->next, 0); + atomic_init(&node->items[0], item); + + for (int i = 1; i < BUFFER_SIZE; i++) { + atomic_init(&node->items[i], 0); + } + + isc_mem_attach(mctx, &node->mctx); + + return (node); +} + +static void +node_destroy(void *node0) { + node_t *node = (node_t *)node0; + + isc_mem_putanddetach(&node->mctx, node, sizeof(*node)); +} + +static bool +node_cas_next(node_t *node, node_t *cmp, const node_t *val) { + return (atomic_compare_exchange_strong(&node->next, (uintptr_t *)&cmp, + (uintptr_t)val)); +} + +static bool +queue_cas_tail(isc_queue_t *queue, node_t *cmp, const node_t *val) { + return (atomic_compare_exchange_strong(&queue->tail, (uintptr_t *)&cmp, + (uintptr_t)val)); +} + +static bool +queue_cas_head(isc_queue_t *queue, node_t *cmp, const node_t *val) { + return (atomic_compare_exchange_strong(&queue->head, (uintptr_t *)&cmp, + (uintptr_t)val)); +} + +isc_queue_t * +isc_queue_new(isc_mem_t *mctx, int max_threads) { + isc_queue_t *queue = NULL; + node_t *sentinel = NULL; + void *qbuf = NULL; + uintptr_t qptr; + + /* + * A trick to allocate an aligned isc_queue_t structure + */ + qbuf = isc_mem_get(mctx, sizeof(*queue) + ALIGNMENT); + qptr = (uintptr_t)qbuf; + queue = (isc_queue_t *)(qptr + (ALIGNMENT - (qptr % ALIGNMENT))); + + if (max_threads == 0) { + max_threads = MAX_THREADS; + } + + *queue = (isc_queue_t){ + .max_threads = max_threads, + .alloced_ptr = qbuf, + }; + + isc_mem_attach(mctx, &queue->mctx); + + queue->hp = isc_hp_new(mctx, 1, node_destroy); + + sentinel = node_new(mctx, nulluintptr); + atomic_init(&sentinel->enqidx, 0); + + atomic_init(&queue->head, (uintptr_t)sentinel); + atomic_init(&queue->tail, (uintptr_t)sentinel); + + return (queue); +} + +void +isc_queue_enqueue(isc_queue_t *queue, uintptr_t item) { + REQUIRE(item != nulluintptr); + + while (true) { + node_t *lt = NULL; + uint_fast32_t idx; + uintptr_t n = nulluintptr; + + lt = (node_t *)isc_hp_protect(queue->hp, 0, &queue->tail); + idx = atomic_fetch_add(<->enqidx, 1); + if (idx > BUFFER_SIZE - 1) { + node_t *lnext = NULL; + + if (lt != (node_t *)atomic_load(&queue->tail)) { + continue; + } + + lnext = (node_t *)atomic_load(<->next); + if (lnext == NULL) { + node_t *newnode = node_new(queue->mctx, item); + if (node_cas_next(lt, NULL, newnode)) { + queue_cas_tail(queue, lt, newnode); + isc_hp_clear(queue->hp); + return; + } + node_destroy(newnode); + } else { + queue_cas_tail(queue, lt, lnext); + } + + continue; + } + + if (atomic_compare_exchange_strong(<->items[idx], &n, item)) { + isc_hp_clear(queue->hp); + return; + } + } +} + +uintptr_t +isc_queue_dequeue(isc_queue_t *queue) { + REQUIRE(queue != NULL); + + while (true) { + node_t *lh = NULL; + uint_fast32_t idx; + uintptr_t item; + + lh = (node_t *)isc_hp_protect(queue->hp, 0, &queue->head); + if (atomic_load(&lh->deqidx) >= atomic_load(&lh->enqidx) && + atomic_load(&lh->next) == nulluintptr) + { + break; + } + + idx = atomic_fetch_add(&lh->deqidx, 1); + if (idx > BUFFER_SIZE - 1) { + node_t *lnext = (node_t *)atomic_load(&lh->next); + if (lnext == NULL) { + break; + } + if (queue_cas_head(queue, lh, lnext)) { + isc_hp_retire(queue->hp, (uintptr_t)lh); + } + + continue; + } + + item = atomic_exchange(&(lh->items[idx]), + (uintptr_t)&queue->taken); + if (item == nulluintptr) { + continue; + } + + isc_hp_clear(queue->hp); + return (item); + } + + isc_hp_clear(queue->hp); + return (nulluintptr); +} + +void +isc_queue_destroy(isc_queue_t *queue) { + node_t *last = NULL; + void *alloced = NULL; + + REQUIRE(queue != NULL); + + while (isc_queue_dequeue(queue) != nulluintptr) { + /* do nothing */ + } + + last = (node_t *)atomic_load_relaxed(&queue->head); + node_destroy(last); + isc_hp_destroy(queue->hp); + + alloced = queue->alloced_ptr; + isc_mem_putanddetach(&queue->mctx, alloced, sizeof(*queue) + ALIGNMENT); +} diff --git a/lib/isc/quota.c b/lib/isc/quota.c index cf63e05f..b0f14ac7 100644 --- a/lib/isc/quota.c +++ b/lib/isc/quota.c @@ -3,47 +3,49 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stddef.h> #include <isc/atomic.h> #include <isc/quota.h> #include <isc/util.h> - void isc_quota_init(isc_quota_t *quota, unsigned int max) { - atomic_store("a->max, max); - atomic_store("a->used, 0); - atomic_store("a->soft, 0); + atomic_init("a->max, max); + atomic_init("a->used, 0); + atomic_init("a->soft, 0); + atomic_init("a->waiting, 0); + ISC_LIST_INIT(quota->cbs); + isc_mutex_init("a->cblock); } void isc_quota_destroy(isc_quota_t *quota) { INSIST(atomic_load("a->used) == 0); - atomic_store("a->max, 0); - atomic_store("a->used, 0); - atomic_store("a->soft, 0); + INSIST(atomic_load("a->waiting) == 0); + INSIST(ISC_LIST_EMPTY(quota->cbs)); + atomic_store_release("a->max, 0); + atomic_store_release("a->used, 0); + atomic_store_release("a->soft, 0); + isc_mutex_destroy("a->cblock); } void isc_quota_soft(isc_quota_t *quota, unsigned int soft) { - atomic_store("a->soft, soft); + atomic_store_release("a->soft, soft); } void isc_quota_max(isc_quota_t *quota, unsigned int max) { - atomic_store("a->max, max); + atomic_store_release("a->max, max); } unsigned int @@ -61,43 +63,77 @@ isc_quota_getused(isc_quota_t *quota) { return (atomic_load_relaxed("a->used)); } -isc_result_t -isc_quota_reserve(isc_quota_t *quota) { +static isc_result_t +quota_reserve(isc_quota_t *quota) { isc_result_t result; - uint32_t max = atomic_load("a->max); - uint32_t soft = atomic_load("a->soft); - uint32_t used = atomic_fetch_add("a->used, 1); - if (max == 0 || used < max) { - if (soft == 0 || used < soft) { - result = ISC_R_SUCCESS; - } else { + uint_fast32_t max = atomic_load_acquire("a->max); + uint_fast32_t soft = atomic_load_acquire("a->soft); + uint_fast32_t used = atomic_load_acquire("a->used); + do { + if (max != 0 && used >= max) { + return (ISC_R_QUOTA); + } + if (soft != 0 && used >= soft) { result = ISC_R_SOFTQUOTA; + } else { + result = ISC_R_SUCCESS; } - } else { - INSIST(atomic_fetch_sub("a->used, 1) > 0); - result = ISC_R_QUOTA; - } + } while (!atomic_compare_exchange_weak_acq_rel("a->used, &used, + used + 1)); return (result); } -void -isc_quota_release(isc_quota_t *quota) { - INSIST(atomic_fetch_sub("a->used, 1) > 0); +/* Must be quota->cbslock locked */ +static void +enqueue(isc_quota_t *quota, isc_quota_cb_t *cb) { + REQUIRE(cb != NULL); + ISC_LIST_ENQUEUE(quota->cbs, cb, link); + atomic_fetch_add_release("a->waiting, 1); +} + +/* Must be quota->cbslock locked */ +static isc_quota_cb_t * +dequeue(isc_quota_t *quota) { + isc_quota_cb_t *cb = ISC_LIST_HEAD(quota->cbs); + INSIST(cb != NULL); + ISC_LIST_DEQUEUE(quota->cbs, cb, link); + atomic_fetch_sub_relaxed("a->waiting, 1); + return (cb); +} + +static void +quota_release(isc_quota_t *quota) { + /* + * This is opportunistic - we might race with a failing quota_attach_cb + * and not detect that something is waiting, but eventually someone will + * be releasing quota and will detect it, so we don't need to worry - + * and we're saving a lot by not locking cblock every time. + */ + + if (atomic_load_acquire("a->waiting) > 0) { + isc_quota_cb_t *cb = NULL; + LOCK("a->cblock); + if (atomic_load_relaxed("a->waiting) > 0) { + cb = dequeue(quota); + } + UNLOCK("a->cblock); + if (cb != NULL) { + cb->cb_func(quota, cb->data); + return; + } + } + + INSIST(atomic_fetch_sub_release("a->used, 1) > 0); } static isc_result_t -doattach(isc_quota_t *quota, isc_quota_t **p, bool force) { +doattach(isc_quota_t *quota, isc_quota_t **p) { isc_result_t result; REQUIRE(p != NULL && *p == NULL); - result = isc_quota_reserve(quota); + result = quota_reserve(quota); if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { *p = quota; - } else if (result == ISC_R_QUOTA && force) { - /* attach anyway */ - atomic_fetch_add("a->used, 1); - *p = quota; - result = ISC_R_SUCCESS; } return (result); @@ -105,17 +141,30 @@ doattach(isc_quota_t *quota, isc_quota_t **p, bool force) { isc_result_t isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) { - return (doattach(quota, p, false)); + return (isc_quota_attach_cb(quota, p, NULL)); } isc_result_t -isc_quota_force(isc_quota_t *quota, isc_quota_t **p) { - return (doattach(quota, p, true)); +isc_quota_attach_cb(isc_quota_t *quota, isc_quota_t **p, isc_quota_cb_t *cb) { + isc_result_t result = doattach(quota, p); + if (result == ISC_R_QUOTA && cb != NULL) { + LOCK("a->cblock); + enqueue(quota, cb); + UNLOCK("a->cblock); + } + return (result); +} + +void +isc_quota_cb_init(isc_quota_cb_t *cb, isc_quota_cb_func_t cb_func, void *data) { + ISC_LINK_INIT(cb, link); + cb->cb_func = cb_func; + cb->data = data; } void isc_quota_detach(isc_quota_t **p) { INSIST(p != NULL && *p != NULL); - isc_quota_release(*p); + quota_release(*p); *p = NULL; } diff --git a/lib/isc/radix.c b/lib/isc/radix.c index 1e8f15a5..f24542f1 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -15,20 +15,18 @@ * Id: prefix.c,v 1.37.2.9 2000/03/10 02:53:19 labovit Exp */ -#include <config.h> - #include <inttypes.h> #include <isc/mem.h> +#include <isc/radix.h> #include <isc/types.h> #include <isc/util.h> -#include <isc/radix.h> -#define BIT_TEST(f, b) (((f) & (b)) != 0) +#define BIT_TEST(f, b) (((f) & (b)) != 0) static isc_result_t -_new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, - void *dest, int bitlen); +_new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, + int bitlen); static void _deref_prefix(isc_prefix_t *prefix); @@ -44,18 +42,16 @@ _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); static isc_result_t _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, - int bitlen) -{ + int bitlen) { isc_prefix_t *prefix; REQUIRE(target != NULL); - if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC) + if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC) { return (ISC_R_NOTIMPLEMENTED); + } prefix = isc_mem_get(mctx, sizeof(isc_prefix_t)); - if (prefix == NULL) - return (ISC_R_NOMEMORY); if (family == AF_INET6) { prefix->bitlen = (bitlen >= 0) ? bitlen : 128; @@ -102,8 +98,8 @@ _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) { */ if (isc_refcount_current(&prefix->refcount) == 0) { isc_result_t ret; - ret = _new_prefix(mctx, target, prefix->family, - &prefix->add, prefix->bitlen); + ret = _new_prefix(mctx, target, prefix->family, &prefix->add, + prefix->bitlen); return (ret); } @@ -115,18 +111,19 @@ _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) { static int _comp_with_mask(void *addr, void *dest, u_int mask) { - /* Mask length of zero matches everything */ - if (mask == 0) + if (mask == 0) { return (1); + } if (memcmp(addr, dest, mask / 8) == 0) { u_int n = mask / 8; u_int m = ((~0U) << (8 - (mask % 8))); if ((mask % 8) == 0 || - (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m)) + (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m)) { return (1); + } } return (0); } @@ -138,8 +135,6 @@ isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) { REQUIRE(target != NULL && *target == NULL); radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t)); - if (radix == NULL) - return (ISC_R_NOMEMORY); radix->mctx = NULL; isc_mem_attach(mctx, &radix->mctx); @@ -160,11 +155,10 @@ isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) { static void _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { - REQUIRE(radix != NULL); if (radix->head != NULL) { - isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; + isc_radix_node_t *Xstack[RADIX_MAXBITS + 1]; isc_radix_node_t **Xsp = Xstack; isc_radix_node_t *Xrn = radix->head; @@ -174,8 +168,9 @@ _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { if (Xrn->prefix != NULL) { _deref_prefix(Xrn->prefix); - if (func != NULL) + if (func != NULL) { func(Xrn->data); + } } else { INSIST(Xrn->data[RADIX_V4] == NULL && Xrn->data[RADIX_V6] == NULL); @@ -201,7 +196,6 @@ _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { RUNTIME_CHECK(radix->num_active_node == 0); } - void isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { REQUIRE(radix != NULL); @@ -209,7 +203,6 @@ isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { isc_mem_putanddetach(&radix->mctx, radix, sizeof(*radix)); } - /* * func will be called as func(node->prefix, node->data) */ @@ -219,16 +212,13 @@ isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) { REQUIRE(func != NULL); - RADIX_WALK(radix->head, node) { - func(node->prefix, node->data); - } RADIX_WALK_END; + RADIX_WALK(radix->head, node) { func(node->prefix, node->data); } + RADIX_WALK_END; } - isc_result_t isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, - isc_prefix_t *prefix) -{ + isc_prefix_t *prefix) { isc_radix_node_t *node; isc_radix_node_t *stack[RADIX_MAXBITS + 1]; u_char *addr; @@ -242,35 +232,38 @@ isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, *target = NULL; - if (radix->head == NULL) { + node = radix->head; + + if (node == NULL) { return (ISC_R_NOTFOUND); } - node = radix->head; addr = isc_prefix_touchar(prefix); bitlen = prefix->bitlen; - while (node->bit < bitlen) { - if (node->prefix) + while (node != NULL && node->bit < bitlen) { + if (node->prefix) { stack[cnt++] = node; + } if (BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) + { node = node->r; - else + } else { node = node->l; - - if (node == NULL) - break; + } } - if (node && node->prefix) + if (node != NULL && node->prefix) { stack[cnt++] = node; + } while (cnt-- > 0) { node = stack[cnt]; - if (prefix->bitlen < node->bit) + if (prefix->bitlen < node->bit) { continue; + } if (_comp_with_mask(isc_prefix_tochar(node->prefix), isc_prefix_tochar(prefix), @@ -296,8 +289,7 @@ isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_result_t isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, - isc_radix_node_t *source, isc_prefix_t *prefix) -{ + isc_radix_node_t *source, isc_prefix_t *prefix) { isc_radix_node_t *node, *new_node, *parent, *glue = NULL; u_char *addr, *test_addr; uint32_t bitlen, fam, check_bit, differ_bit; @@ -309,8 +301,9 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, REQUIRE(prefix != NULL || (source != NULL && source->prefix != NULL)); RUNTIME_CHECK(prefix == NULL || prefix->bitlen <= radix->maxbits); - if (prefix == NULL) + if (prefix == NULL) { prefix = source->prefix; + } INSIST(prefix != NULL); @@ -319,8 +312,6 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, if (radix->head == NULL) { node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); - if (node == NULL) - return (ISC_R_NOMEMORY); node->bit = bitlen; for (i = 0; i < RADIX_FAMILIES; i++) { node->node_num[i] = -1; @@ -377,12 +368,14 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, if (node->bit < radix->maxbits && BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { - if (node->r == NULL) + if (node->r == NULL) { break; + } node = node->r; } else { - if (node->l == NULL) + if (node->l == NULL) { break; + } node = node->l; } @@ -402,8 +395,9 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, } /* I know the better way, but for now. */ for (j = 0; j < 8; j++) { - if (BIT_TEST(r, (0x80 >> j))) + if (BIT_TEST(r, (0x80 >> j))) { break; + } } /* Must be found. */ INSIST(j < 8); @@ -411,8 +405,9 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, break; } - if (differ_bit > check_bit) + if (differ_bit > check_bit) { differ_bit = check_bit; + } parent = node->parent; while (parent != NULL && parent->bit >= differ_bit) { @@ -427,8 +422,7 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, /* Merging nodes */ for (i = 0; i < RADIX_FAMILIES; i++) { if (node->node_num[i] == -1 && - source->node_num[i] != -1) - { + source->node_num[i] != -1) { node->node_num[i] = radix->num_added_node + source->node_num[i]; @@ -439,8 +433,7 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, if (fam == AF_UNSPEC) { /* "any" or "none" */ int next = radix->num_added_node + 1; - for (i = 0; i < RADIX_FAMILIES; i++) - { + for (i = 0; i < RADIX_FAMILIES; i++) { if (node->node_num[i] == -1) { node->node_num[i] = next; @@ -459,10 +452,11 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, *target = node; return (ISC_R_SUCCESS); } else { - result = _ref_prefix(radix->mctx, - &node->prefix, prefix); - if (result != ISC_R_SUCCESS) + result = _ref_prefix(radix->mctx, &node->prefix, + prefix); + if (result != ISC_R_SUCCESS) { return (result); + } } INSIST(node->data[RADIX_V4] == NULL && node->node_num[RADIX_V4] == -1 && @@ -494,24 +488,18 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, } new_node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); - if (new_node == NULL) - return (ISC_R_NOMEMORY); if (node->bit != differ_bit && bitlen != differ_bit) { glue = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); - if (glue == NULL) { - isc_mem_put(radix->mctx, new_node, - sizeof(isc_radix_node_t)); - return (ISC_R_NOMEMORY); - } } new_node->bit = bitlen; new_node->prefix = NULL; result = _ref_prefix(radix->mctx, &new_node->prefix, prefix); if (result != ISC_R_SUCCESS) { isc_mem_put(radix->mctx, new_node, sizeof(isc_radix_node_t)); - if (glue != NULL) + if (glue != NULL) { isc_mem_put(radix->mctx, glue, sizeof(isc_radix_node_t)); + } return (result); } new_node->parent = NULL; @@ -527,8 +515,8 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, for (i = 0; i < RADIX_FAMILIES; i++) { int cur = radix->num_added_node; if (source->node_num[i] != -1) { - new_node->node_num[i] = - source->node_num[i] + cur; + new_node->node_num[i] = source->node_num[i] + + cur; new_node->data[i] = source->data[i]; } } @@ -536,8 +524,9 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, int next = ++radix->num_added_node; if (fam == AF_UNSPEC) { /* "any" or "none" */ - for (i = 0; i < RADIX_FAMILIES; i++) + for (i = 0; i < RADIX_FAMILIES; i++) { new_node->node_num[i] = next; + } } else { new_node->node_num[ISC_RADIX_FAMILY(prefix)] = next; } @@ -563,7 +552,8 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, if (bitlen == differ_bit) { INSIST(glue == NULL); if (bitlen < radix->maxbits && - BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) { + BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) + { new_node->r = node; } else { new_node->l = node; @@ -589,7 +579,8 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, } radix->num_active_node++; if (differ_bit < radix->maxbits && - BIT_TEST(addr[differ_bit>>3], 0x80 >> (differ_bit & 07))) { + BIT_TEST(addr[differ_bit >> 3], 0x80 >> (differ_bit & 07))) + { glue->r = new_node; glue->l = node; } else { @@ -625,8 +616,9 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { * This might be a placeholder node -- have to check and * make sure there is a prefix associated with it! */ - if (node->prefix != NULL) + if (node->prefix != NULL) { _deref_prefix(node->prefix); + } node->prefix = NULL; memset(node->data, 0, sizeof(node->data)); @@ -657,8 +649,9 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; - if (parent->prefix) + if (parent->prefix) { return; + } /* We need to remove parent too. */ if (parent->parent == NULL) { diff --git a/lib/isc/random.c b/lib/isc/random.c index 4be92924..753453ff 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -28,21 +28,19 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <config.h> - #include <inttypes.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <isc/once.h> #include <isc/platform.h> #include <isc/random.h> #include <isc/result.h> +#include <isc/thread.h> #include <isc/types.h> #include <isc/util.h> -#include <isc/once.h> - #include "entropy_private.h" /* @@ -62,54 +60,41 @@ */ #include "xoshiro128starstar.c" -#if defined(HAVE_TLS) -#if defined(HAVE_THREAD_LOCAL) -#include <threads.h> -static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT; -#elif defined(HAVE___THREAD) -static __thread isc_once_t isc_random_once = ISC_ONCE_INIT; -#elif defined(HAVE___DECLSPEC_THREAD) -static __declspec( thread ) isc_once_t isc_random_once = ISC_ONCE_INIT; -#else -#error "Unknown method for defining a TLS variable!" -#endif -#else -static isc_once_t isc_random_once = ISC_ONCE_INIT; -#endif +ISC_THREAD_LOCAL isc_once_t isc_random_once = ISC_ONCE_INIT; static void isc_random_initialize(void) { - int useed[4] = {0,0,0,1}; + int useed[4] = { 0, 0, 0, 1 }; #if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* * Set a constant seed to help in problem reproduction should fuzzing * find a crash or a hang. The seed array must be non-zero else * xoshiro128starstar will generate an infinite series of zeroes. */ -#else +#else /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ isc_entropy_get(useed, sizeof(useed)); -#endif - memcpy(seed, useed, sizeof(seed)); +#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + memmove(seed, useed, sizeof(seed)); } uint8_t isc_random8(void) { - RUNTIME_CHECK(isc_once_do(&isc_random_once, - isc_random_initialize) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) == + ISC_R_SUCCESS); return (next() & 0xff); } uint16_t isc_random16(void) { - RUNTIME_CHECK(isc_once_do(&isc_random_once, - isc_random_initialize) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) == + ISC_R_SUCCESS); return (next() & 0xffff); } uint32_t isc_random32(void) { - RUNTIME_CHECK(isc_once_do(&isc_random_once, - isc_random_initialize) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) == + ISC_R_SUCCESS); return (next()); } @@ -121,8 +106,8 @@ isc_random_buf(void *buf, size_t buflen) { REQUIRE(buf != NULL); REQUIRE(buflen > 0); - RUNTIME_CHECK(isc_once_do(&isc_random_once, - isc_random_initialize) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) == + ISC_R_SUCCESS); for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) { r = next(); @@ -138,8 +123,8 @@ isc_random_uniform(uint32_t upper_bound) { /* Copy of arc4random_uniform from OpenBSD */ uint32_t r, min; - RUNTIME_CHECK(isc_once_do(&isc_random_once, - isc_random_initialize) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) == + ISC_R_SUCCESS); if (upper_bound < 2) { return (0); @@ -150,7 +135,7 @@ isc_random_uniform(uint32_t upper_bound) { #else /* if (ULONG_MAX > 0xffffffffUL) */ /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ if (upper_bound > 0x80000000) { - min = 1 + ~upper_bound; /* 2**32 - upper_bound */ + min = 1 + ~upper_bound; /* 2**32 - upper_bound */ } else { /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index cd8755a5..de3077a1 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -3,22 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <inttypes.h> #include <stdbool.h> #include <isc/mem.h> #include <isc/ratelimiter.h> +#include <isc/refcount.h> #include <isc/task.h> #include <isc/time.h> #include <isc/timer.h> @@ -32,17 +30,17 @@ typedef enum { } isc_ratelimiter_state_t; struct isc_ratelimiter { - isc_mem_t * mctx; - isc_mutex_t lock; - int refs; - isc_task_t * task; - isc_timer_t * timer; - isc_interval_t interval; - uint32_t pertic; - bool pushpop; - isc_ratelimiter_state_t state; - isc_event_t shutdownevent; - ISC_LIST(isc_event_t) pending; + isc_mem_t *mctx; + isc_mutex_t lock; + isc_refcount_t references; + isc_task_t *task; + isc_timer_t *timer; + isc_interval_t interval; + uint32_t pertic; + bool pushpop; + isc_ratelimiter_state_t state; + isc_event_t shutdownevent; + ISC_LIST(isc_event_t) pending; }; #define ISC_RATELIMITEREVENT_SHUTDOWN (ISC_EVENTCLASS_RATELIMITER + 1) @@ -55,48 +53,47 @@ ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event); isc_result_t isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, - isc_task_t *task, isc_ratelimiter_t **ratelimiterp) -{ + isc_task_t *task, isc_ratelimiter_t **ratelimiterp) { isc_result_t result; isc_ratelimiter_t *rl; INSIST(ratelimiterp != NULL && *ratelimiterp == NULL); rl = isc_mem_get(mctx, sizeof(*rl)); - if (rl == NULL) - return ISC_R_NOMEMORY; - rl->mctx = mctx; - rl->refs = 1; - rl->task = task; + *rl = (isc_ratelimiter_t){ + .mctx = mctx, + .task = task, + .pertic = 1, + .state = isc_ratelimiter_idle, + }; + + isc_refcount_init(&rl->references, 1); isc_interval_set(&rl->interval, 0, 0); - rl->timer = NULL; - rl->pertic = 1; - rl->pushpop = false; - rl->state = isc_ratelimiter_idle; ISC_LIST_INIT(rl->pending); isc_mutex_init(&rl->lock); - result = isc_timer_create(timermgr, isc_timertype_inactive, - NULL, NULL, rl->task, ratelimiter_tick, - rl, &rl->timer); - if (result != ISC_R_SUCCESS) + result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, + rl->task, ratelimiter_tick, rl, &rl->timer); + if (result != ISC_R_SUCCESS) { goto free_mutex; + } /* * Increment the reference count to indicate that we may * (soon) have events outstanding. */ - rl->refs++; + isc_refcount_increment(&rl->references); - ISC_EVENT_INIT(&rl->shutdownevent, - sizeof(isc_event_t), - 0, NULL, ISC_RATELIMITEREVENT_SHUTDOWN, + ISC_EVENT_INIT(&rl->shutdownevent, sizeof(isc_event_t), 0, NULL, + ISC_RATELIMITEREVENT_SHUTDOWN, ratelimiter_shutdowncomplete, rl, rl, NULL, NULL); *ratelimiterp = rl; return (ISC_R_SUCCESS); free_mutex: + isc_refcount_decrementz(&rl->references); + isc_refcount_destroy(&rl->references); isc_mutex_destroy(&rl->lock); isc_mem_put(mctx, rl, sizeof(*rl)); return (result); @@ -124,17 +121,16 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) { void isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, uint32_t pertic) { - REQUIRE(rl != NULL); - if (pertic == 0) + if (pertic == 0) { pertic = 1; + } rl->pertic = pertic; } void isc_ratelimiter_setpushpop(isc_ratelimiter_t *rl, bool pushpop) { - REQUIRE(rl != NULL); rl->pushpop = pushpop; @@ -142,8 +138,7 @@ isc_ratelimiter_setpushpop(isc_ratelimiter_t *rl, bool pushpop) { isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, - isc_event_t **eventp) -{ + isc_event_t **eventp) { isc_result_t result = ISC_R_SUCCESS; isc_event_t *ev; @@ -155,13 +150,15 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, LOCK(&rl->lock); if (rl->state == isc_ratelimiter_ratelimited || - rl->state == isc_ratelimiter_stalled) { + rl->state == isc_ratelimiter_stalled) + { ev->ev_sender = task; *eventp = NULL; - if (rl->pushpop) + if (rl->pushpop) { ISC_LIST_PREPEND(rl->pending, ev, ev_ratelink); - else + } else { ISC_LIST_APPEND(rl->pending, ev, ev_ratelink); + } } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, false); @@ -174,8 +171,9 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, result = ISC_R_SHUTTINGDOWN; } UNLOCK(&rl->lock); - if (*eventp != NULL && result == ISC_R_SUCCESS) + if (*eventp != NULL && result == ISC_R_SUCCESS) { isc_task_send(task, eventp); + } return (result); } @@ -190,15 +188,15 @@ isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event) { if (ISC_LINK_LINKED(event, ev_ratelink)) { ISC_LIST_UNLINK(rl->pending, event, ev_ratelink); event->ev_sender = NULL; - } else + } else { result = ISC_R_NOTFOUND; + } UNLOCK(&rl->lock); return (result); } static void ratelimiter_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result = ISC_R_SUCCESS; isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg; isc_event_t *p; uint32_t pertic; @@ -222,12 +220,12 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) { * No work left to do. Stop the timer so that we don't * waste resources by having it fire periodically. */ - result = isc_timer_reset(rl->timer, - isc_timertype_inactive, - NULL, NULL, false); + isc_result_t result = isc_timer_reset( + rl->timer, isc_timertype_inactive, NULL, NULL, + false); RUNTIME_CHECK(result == ISC_R_SUCCESS); rl->state = isc_ratelimiter_idle; - pertic = 0; /* Force the loop to exit. */ + pertic = 0; /* Force the loop to exit. */ } UNLOCK(&rl->lock); if (p != NULL) { @@ -247,14 +245,16 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) { LOCK(&rl->lock); rl->state = isc_ratelimiter_shuttingdown; - (void)isc_timer_reset(rl->timer, isc_timertype_inactive, - NULL, NULL, false); + (void)isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, + false); while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) { + task = ev->ev_sender; ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink); ev->ev_attributes |= ISC_EVENTATTR_CANCELED; - task = ev->ev_sender; isc_task_send(task, &ev); } + task = NULL; + isc_task_attach(rl->task, &task); isc_timer_detach(&rl->timer); /* @@ -274,48 +274,38 @@ ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event) { UNUSED(task); isc_ratelimiter_detach(&rl); + isc_task_detach(&task); } static void ratelimiter_free(isc_ratelimiter_t *rl) { + isc_refcount_destroy(&rl->references); isc_mutex_destroy(&rl->lock); isc_mem_put(rl->mctx, rl, sizeof(*rl)); } void isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) { - REQUIRE(source != NULL); REQUIRE(target != NULL && *target == NULL); - LOCK(&source->lock); - REQUIRE(source->refs > 0); - source->refs++; - INSIST(source->refs > 0); - UNLOCK(&source->lock); + isc_refcount_increment(&source->references); + *target = source; } void isc_ratelimiter_detach(isc_ratelimiter_t **rlp) { isc_ratelimiter_t *rl; - bool free_now = false; REQUIRE(rlp != NULL && *rlp != NULL); rl = *rlp; + *rlp = NULL; - LOCK(&rl->lock); - REQUIRE(rl->refs > 0); - rl->refs--; - if (rl->refs == 0) - free_now = true; - UNLOCK(&rl->lock); - - if (free_now) + if (isc_refcount_decrement(&rl->references) == 1) { ratelimiter_free(rl); - - *rlp = NULL; + } } isc_result_t @@ -333,7 +323,7 @@ isc_ratelimiter_stall(isc_ratelimiter_t *rl) { result = isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, false); RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* FALLTHROUGH */ + /* FALLTHROUGH */ case isc_ratelimiter_idle: case isc_ratelimiter_stalled: rl->state = isc_ratelimiter_stalled; @@ -359,10 +349,12 @@ isc_ratelimiter_release(isc_ratelimiter_t *rl) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, false); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { rl->state = isc_ratelimiter_ratelimited; - } else + } + } else { rl->state = isc_ratelimiter_idle; + } break; case isc_ratelimiter_ratelimited: case isc_ratelimiter_idle: diff --git a/lib/isc/regex.c b/lib/isc/regex.c index 63261bbb..953457f2 100644 --- a/lib/isc/regex.c +++ b/lib/isc/regex.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <stdbool.h> #include <isc/file.h> @@ -19,26 +17,30 @@ #include <isc/string.h> #if VALREGEX_REPORT_REASON -#define FAIL(x) do { reason = (x); goto error; } while(0) -#else +#define FAIL(x) \ + do { \ + reason = (x); \ + goto error; \ + } while (0) +#else /* if VALREGEX_REPORT_REASON */ #define FAIL(x) goto error -#endif +#endif /* if VALREGEX_REPORT_REASON */ /* * Validate the regular expression 'C' locale. */ int isc_regex_validate(const char *c) { - enum { - none, parse_bracket, parse_bound, - parse_ce, parse_ec, parse_cc - } state = none; + enum { none, + parse_bracket, + parse_bound, + parse_ce, + parse_ec, + parse_cc } state = none; /* Well known character classes. */ - const char *cc[] = { - ":alnum:", ":digit:", ":punct:", ":alpha:", ":graph:", - ":space:", ":blank:", ":lower:", ":upper:", ":cntrl:", - ":print:", ":xdigit:" - }; + const char *cc[] = { ":alnum:", ":digit:", ":punct:", ":alpha:", + ":graph:", ":space:", ":blank:", ":lower:", + ":upper:", ":cntrl:", ":print:", ":xdigit:" }; bool seen_comma = false; bool seen_high = false; bool seen_char = false; @@ -57,23 +59,31 @@ isc_regex_validate(const char *c) { int range_start = 0; #if VALREGEX_REPORT_REASON const char *reason = ""; -#endif +#endif /* if VALREGEX_REPORT_REASON */ - if (c == NULL || *c == 0) + if (c == NULL || *c == 0) { FAIL("empty string"); + } while (c != NULL && *c != 0) { switch (state) { case none: switch (*c) { - case '\\': /* make literal */ + case '\\': /* make literal */ ++c; switch (*c) { - case '1': case '2': case '3': - case '4': case '5': case '6': - case '7': case '8': case '9': - if ((*c - '0') > sub) + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if ((*c - '0') > sub) { FAIL("bad back reference"); + } have_atom = true; was_multiple = false; break; @@ -84,22 +94,31 @@ isc_regex_validate(const char *c) { } ++c; break; - case '[': /* bracket start */ + case '[': /* bracket start */ ++c; neg = false; was_multiple = false; seen_char = false; state = parse_bracket; break; - case '{': /* bound start */ + case '{': /* bound start */ switch (c[1]) { - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': - if (!have_atom) + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (!have_atom) { FAIL("no atom"); - if (was_multiple) + } + if (was_multiple) { FAIL("was multiple"); + } seen_comma = false; seen_high = false; low = high = 0; @@ -114,7 +133,7 @@ isc_regex_validate(const char *c) { break; case '}': goto literal; - case '(': /* group start */ + case '(': /* group start */ have_atom = false; was_multiple = false; empty_ok = true; @@ -122,18 +141,21 @@ isc_regex_validate(const char *c) { ++sub; ++c; break; - case ')': /* group end */ - if (group && !have_atom && !empty_ok) + case ')': /* group end */ + if (group && !have_atom && !empty_ok) { FAIL("empty alternative"); + } have_atom = true; was_multiple = false; - if (group != 0) + if (group != 0) { --group; + } ++c; break; - case '|': /* alternative seperator */ - if (!have_atom) + case '|': /* alternative separator */ + if (!have_atom) { FAIL("no atom"); + } have_atom = false; empty_ok = false; was_multiple = false; @@ -148,10 +170,12 @@ isc_regex_validate(const char *c) { case '+': case '*': case '?': - if (was_multiple) + if (was_multiple) { FAIL("was multiple"); - if (!have_atom) + } + if (!have_atom) { FAIL("no atom"); + } have_atom = true; was_multiple = true; ++c; @@ -167,23 +191,34 @@ isc_regex_validate(const char *c) { break; case parse_bound: switch (*c) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': if (!seen_comma) { low = low * 10 + *c - '0'; - if (low > 255) + if (low > 255) { FAIL("lower bound too big"); + } } else { seen_high = true; high = high * 10 + *c - '0'; - if (high > 255) + if (high > 255) { FAIL("upper bound too big"); + } } ++c; break; case ',': - if (seen_comma) + if (seen_comma) { FAIL("multiple commas"); + } seen_comma = true; ++c; break; @@ -191,8 +226,9 @@ isc_regex_validate(const char *c) { case '{': FAIL("non digit/comma"); case '}': - if (seen_high && low > high) + if (seen_high && low > high) { FAIL("bad parse bound"); + } seen_comma = false; state = none; ++c; @@ -202,37 +238,50 @@ isc_regex_validate(const char *c) { case parse_bracket: switch (*c) { case '^': - if (seen_char || neg) goto inside; + if (seen_char || neg) { + goto inside; + } neg = true; ++c; break; case '-': - if (range == 2) goto inside; - if (!seen_char) goto inside; - if (range == 1) + if (range == 2) { + goto inside; + } + if (!seen_char) { + goto inside; + } + if (range == 1) { FAIL("bad range"); + } range = 2; ++c; break; case '[': ++c; switch (*c) { - case '.': /* collating element */ - if (range != 0) --range; + case '.': /* collating element */ + if (range != 0) { + --range; + } ++c; state = parse_ce; seen_ce = false; break; - case '=': /* equivalence class */ - if (range == 2) - FAIL("equivalence class in range"); + case '=': /* equivalence class */ + if (range == 2) { + FAIL("equivalence class in " + "range"); + } ++c; state = parse_ec; seen_ec = false; break; - case ':': /* character class */ - if (range == 2) - FAIL("character class in range"); + case ':': /* character class */ + if (range == 2) { + FAIL("character class in " + "range"); + } ccname = c; ++c; state = parse_cc; @@ -241,10 +290,12 @@ isc_regex_validate(const char *c) { seen_char = true; break; case ']': - if (!c[1] && !seen_char) + if (!c[1] && !seen_char) { FAIL("unfinished brace"); - if (!seen_char) + } + if (!seen_char) { goto inside; + } ++c; range = 0; have_atom = true; @@ -253,14 +304,16 @@ isc_regex_validate(const char *c) { default: inside: seen_char = true; - if (range == 2 && (*c & 0xff) < range_start) + if (range == 2 && (*c & 0xff) < range_start) { FAIL("out of order range"); - if (range != 0) + } + if (range != 0) { --range; + } range_start = *c & 0xff; ++c; break; - }; + } break; case parse_ce: switch (*c) { @@ -268,25 +321,28 @@ isc_regex_validate(const char *c) { ++c; switch (*c) { case ']': - if (!seen_ce) - FAIL("empty ce"); + if (!seen_ce) { + FAIL("empty ce"); + } ++c; state = parse_bracket; break; default: - if (seen_ce) + if (seen_ce) { range_start = 256; - else + } else { range_start = '.'; + } seen_ce = true; break; } break; default: - if (seen_ce) + if (seen_ce) { range_start = 256; - else + } else { range_start = *c; + } seen_ce = true; ++c; break; @@ -298,8 +354,9 @@ isc_regex_validate(const char *c) { ++c; switch (*c) { case ']': - if (!seen_ec) + if (!seen_ec) { FAIL("no ec"); + } ++c; state = parse_bracket; break; @@ -323,24 +380,28 @@ isc_regex_validate(const char *c) { unsigned int i; bool found = false; for (i = 0; - i < sizeof(cc)/sizeof(*cc); - i++) + i < sizeof(cc) / sizeof(*cc); i++) { unsigned int len; len = strlen(cc[i]); if (len != (unsigned int)(c - ccname)) + { continue; + } if (strncmp(cc[i], ccname, len)) + { continue; + } found = true; } - if (!found) + if (!found) { FAIL("unknown cc"); + } ++c; state = parse_bracket; break; - } + } default: break; } @@ -352,17 +413,20 @@ isc_regex_validate(const char *c) { break; } } - if (group != 0) + if (group != 0) { FAIL("group open"); - if (state != none) + } + if (state != none) { FAIL("incomplete"); - if (!have_atom) + } + if (!have_atom) { FAIL("no atom"); + } return (sub); - error: +error: #if VALREGEX_REPORT_REASON fprintf(stderr, "%s\n", reason); -#endif +#endif /* if VALREGEX_REPORT_REASON */ return (-1); } diff --git a/lib/isc/region.c b/lib/isc/region.c index 2f858427..ea3028bc 100644 --- a/lib/isc/region.c +++ b/lib/isc/region.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdlib.h> #include <string.h> @@ -30,9 +27,11 @@ isc_region_compare(isc_region_t *r1, isc_region_t *r2) { l = (r1->length < r2->length) ? r1->length : r2->length; - if ((result = memcmp(r1->base, r2->base, l)) != 0) + if ((result = memcmp(r1->base, r2->base, l)) != 0) { return ((result < 0) ? -1 : 1); - else - return ((r1->length == r2->length) ? 0 : - (r1->length < r2->length) ? -1 : 1); + } else { + return ((r1->length == r2->length) + ? 0 + : (r1->length < r2->length) ? -1 : 1); + } } diff --git a/lib/isc/result.c b/lib/isc/result.c index 7eb42840..8b2258c0 100644 --- a/lib/isc/result.c +++ b/lib/isc/result.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,96 +11,96 @@ /*! \file */ -#include <config.h> - #include <stddef.h> #include <stdlib.h> #include <isc/lib.h> -#include <isc/mutex.h> #include <isc/once.h> #include <isc/resultclass.h> +#include <isc/rwlock.h> #include <isc/util.h> typedef struct resulttable { - unsigned int base; - unsigned int last; - const char ** text; - int set; - ISC_LINK(struct resulttable) link; + unsigned int base; + unsigned int last; + const char **text; + int set; + ISC_LINK(struct resulttable) link; } resulttable; typedef ISC_LIST(resulttable) resulttable_list_t; static const char *description[ISC_R_NRESULTS] = { - "success", /*%< 0 */ - "out of memory", /*%< 1 */ - "timed out", /*%< 2 */ - "no available threads", /*%< 3 */ - "address not available", /*%< 4 */ - "address in use", /*%< 5 */ - "permission denied", /*%< 6 */ - "no pending connections", /*%< 7 */ - "network unreachable", /*%< 8 */ - "host unreachable", /*%< 9 */ - "network down", /*%< 10 */ - "host down", /*%< 11 */ - "connection refused", /*%< 12 */ - "not enough free resources", /*%< 13 */ - "end of file", /*%< 14 */ - "socket already bound", /*%< 15 */ - "reload", /*%< 16 */ - "lock busy", /*%< 17 */ - "already exists", /*%< 18 */ - "ran out of space", /*%< 19 */ - "operation canceled", /*%< 20 */ - "socket is not bound", /*%< 21 */ - "shutting down", /*%< 22 */ - "not found", /*%< 23 */ - "unexpected end of input", /*%< 24 */ - "failure", /*%< 25 */ - "I/O error", /*%< 26 */ - "not implemented", /*%< 27 */ - "unbalanced parentheses", /*%< 28 */ - "no more", /*%< 29 */ - "invalid file", /*%< 30 */ - "bad base64 encoding", /*%< 31 */ - "unexpected token", /*%< 32 */ - "quota reached", /*%< 33 */ - "unexpected error", /*%< 34 */ - "already running", /*%< 35 */ - "ignore", /*%< 36 */ - "address mask not contiguous", /*%< 37 */ - "file not found", /*%< 38 */ - "file already exists", /*%< 39 */ - "socket is not connected", /*%< 40 */ - "out of range", /*%< 41 */ - "out of entropy", /*%< 42 */ - "invalid use of multicast address", /*%< 43 */ - "not a file", /*%< 44 */ - "not a directory", /*%< 45 */ - "queue is full", /*%< 46 */ - "address family mismatch", /*%< 47 */ - "address family not supported", /*%< 48 */ - "bad hex encoding", /*%< 49 */ - "too many open files", /*%< 50 */ - "not blocking", /*%< 51 */ - "unbalanced quotes", /*%< 52 */ - "operation in progress", /*%< 53 */ - "connection reset", /*%< 54 */ - "soft quota reached", /*%< 55 */ - "not a valid number", /*%< 56 */ - "disabled", /*%< 57 */ - "max size", /*%< 58 */ - "invalid address format", /*%< 59 */ - "bad base32 encoding", /*%< 60 */ - "unset", /*%< 61 */ - "multiple", /*%< 62 */ - "would block", /*%< 63 */ - "complete", /*%< 64 */ - "crypto failure", /*%< 65 */ - "disc quota", /*%< 66 */ - "disc full", /*%< 67 */ + "success", /*%< 0 */ + "out of memory", /*%< 1 */ + "timed out", /*%< 2 */ + "no available threads", /*%< 3 */ + "address not available", /*%< 4 */ + "address in use", /*%< 5 */ + "permission denied", /*%< 6 */ + "no pending connections", /*%< 7 */ + "network unreachable", /*%< 8 */ + "host unreachable", /*%< 9 */ + "network down", /*%< 10 */ + "host down", /*%< 11 */ + "connection refused", /*%< 12 */ + "not enough free resources", /*%< 13 */ + "end of file", /*%< 14 */ + "socket already bound", /*%< 15 */ + "reload", /*%< 16 */ + "lock busy", /*%< 17 */ + "already exists", /*%< 18 */ + "ran out of space", /*%< 19 */ + "operation canceled", /*%< 20 */ + "socket is not bound", /*%< 21 */ + "shutting down", /*%< 22 */ + "not found", /*%< 23 */ + "unexpected end of input", /*%< 24 */ + "failure", /*%< 25 */ + "I/O error", /*%< 26 */ + "not implemented", /*%< 27 */ + "unbalanced parentheses", /*%< 28 */ + "no more", /*%< 29 */ + "invalid file", /*%< 30 */ + "bad base64 encoding", /*%< 31 */ + "unexpected token", /*%< 32 */ + "quota reached", /*%< 33 */ + "unexpected error", /*%< 34 */ + "already running", /*%< 35 */ + "ignore", /*%< 36 */ + "address mask not contiguous", /*%< 37 */ + "file not found", /*%< 38 */ + "file already exists", /*%< 39 */ + "socket is not connected", /*%< 40 */ + "out of range", /*%< 41 */ + "out of entropy", /*%< 42 */ + "invalid use of multicast address", /*%< 43 */ + "not a file", /*%< 44 */ + "not a directory", /*%< 45 */ + "queue is full", /*%< 46 */ + "address family mismatch", /*%< 47 */ + "address family not supported", /*%< 48 */ + "bad hex encoding", /*%< 49 */ + "too many open files", /*%< 50 */ + "not blocking", /*%< 51 */ + "unbalanced quotes", /*%< 52 */ + "operation in progress", /*%< 53 */ + "connection reset", /*%< 54 */ + "soft quota reached", /*%< 55 */ + "not a valid number", /*%< 56 */ + "disabled", /*%< 57 */ + "max size", /*%< 58 */ + "invalid address format", /*%< 59 */ + "bad base32 encoding", /*%< 60 */ + "unset", /*%< 61 */ + "multiple", /*%< 62 */ + "would block", /*%< 63 */ + "complete", /*%< 64 */ + "crypto failure", /*%< 65 */ + "disc quota", /*%< 66 */ + "disc full", /*%< 67 */ + "default", /*%< 68 */ + "IPv4 prefix", /*%< 69 */ }; static const char *identifier[ISC_R_NRESULTS] = { @@ -172,21 +172,21 @@ static const char *identifier[ISC_R_NRESULTS] = { "ISC_R_CRYPTOFAILURE", "ISC_R_DISCQUOTA", "ISC_R_DISCFULL", + "ISC_R_DEFAULT", + "ISC_R_IPV4PREFIX", }; -#define ISC_RESULT_RESULTSET 2 -#define ISC_RESULT_UNAVAILABLESET 3 +#define ISC_RESULT_RESULTSET 2 +#define ISC_RESULT_UNAVAILABLESET 3 -static isc_once_t once = ISC_ONCE_INIT; -static resulttable_list_t description_tables; -static resulttable_list_t identifier_tables; -static isc_mutex_t lock; +static isc_once_t once = ISC_ONCE_INIT; +static resulttable_list_t description_tables; +static resulttable_list_t identifier_tables; +static isc_rwlock_t lock; static isc_result_t register_table(resulttable_list_t *tables, unsigned int base, - unsigned int nresults, const char **text, - int set) -{ + unsigned int nresults, const char **text, int set) { resulttable *table; REQUIRE(base % ISC_RESULTCLASS_SIZE == 0); @@ -198,19 +198,20 @@ register_table(resulttable_list_t *tables, unsigned int base, * isc_result_totext() even if there is no memory context. */ table = malloc(sizeof(*table)); - if (table == NULL) + if (table == NULL) { return (ISC_R_NOMEMORY); + } table->base = base; table->last = base + nresults - 1; table->text = text; table->set = set; ISC_LINK_INIT(table, link); - LOCK(&lock); + RWLOCK(&lock, isc_rwlocktype_write); ISC_LIST_APPEND(*tables, table, link); - UNLOCK(&lock); + RWUNLOCK(&lock, isc_rwlocktype_write); return (ISC_R_SUCCESS); } @@ -219,26 +220,24 @@ static void initialize_action(void) { isc_result_t result; - isc_mutex_init(&lock); + isc_rwlock_init(&lock, 0, 0); ISC_LIST_INIT(description_tables); ISC_LIST_INIT(identifier_tables); - result = register_table(&description_tables, - ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, - description, ISC_RESULT_RESULTSET); + result = register_table(&description_tables, ISC_RESULTCLASS_ISC, + ISC_R_NRESULTS, description, + ISC_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, - "register_table() failed: %u", - result); + "register_table() failed: %u", result); } - result = register_table(&identifier_tables, - ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, - identifier, ISC_RESULT_RESULTSET); + result = register_table(&identifier_tables, ISC_RESULTCLASS_ISC, + ISC_R_NRESULTS, identifier, + ISC_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, - "register_table() failed: %u", - result); + "register_table() failed: %u", result); } } @@ -255,12 +254,12 @@ isc_result_tomany_helper(resulttable_list_t *tables, isc_result_t result) { initialize(); - LOCK(&lock); + RWLOCK(&lock, isc_rwlocktype_read); text = NULL; - for (table = ISC_LIST_HEAD(*tables); - table != NULL; - table = ISC_LIST_NEXT(table, link)) { + for (table = ISC_LIST_HEAD(*tables); table != NULL; + table = ISC_LIST_NEXT(table, link)) + { if (result >= table->base && result <= table->last) { index = (int)(result - table->base); text = table->text[index]; @@ -271,7 +270,7 @@ isc_result_tomany_helper(resulttable_list_t *tables, isc_result_t result) { text = "(result code text not available)"; } - UNLOCK(&lock); + RWUNLOCK(&lock, isc_rwlocktype_read); return (text); } @@ -287,21 +286,17 @@ isc_result_toid(isc_result_t result) { } isc_result_t -isc_result_register(unsigned int base, unsigned int nresults, - const char **text, int set) -{ +isc_result_register(unsigned int base, unsigned int nresults, const char **text, + int set) { initialize(); - return (register_table(&description_tables, base, nresults, text, - set)); + return (register_table(&description_tables, base, nresults, text, set)); } isc_result_t isc_result_registerids(unsigned int base, unsigned int nresults, - const char **ids, int set) -{ + const char **ids, int set) { initialize(); - return (register_table(&identifier_tables, base, nresults, ids, - set)); + return (register_table(&identifier_tables, base, nresults, ids, set)); } diff --git a/lib/isc/rwlock.c b/lib/isc/rwlock.c index 3780b98c..e75f63e0 100644 --- a/lib/isc/rwlock.c +++ b/lib/isc/rwlock.c @@ -3,24 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - +#include <inttypes.h> #include <stdbool.h> #include <stddef.h> -#include <inttypes.h> #if defined(sun) && (defined(__sparc) || defined(__sparc__)) #include <synch.h> /* for smt_pause(3c) */ -#endif +#endif /* if defined(sun) && (defined(__sparc) || defined(__sparc__)) */ #include <isc/atomic.h> #include <isc/magic.h> @@ -29,50 +26,152 @@ #include <isc/rwlock.h> #include <isc/util.h> -#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k') -#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC) +#if USE_PTHREAD_RWLOCK + +#include <errno.h> +#include <pthread.h> + +isc_result_t +isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, + unsigned int write_quota) { + UNUSED(read_quota); + UNUSED(write_quota); + REQUIRE(pthread_rwlock_init(&rwl->rwlock, NULL) == 0); + atomic_init(&rwl->downgrade, false); + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { + switch (type) { + case isc_rwlocktype_read: + REQUIRE(pthread_rwlock_rdlock(&rwl->rwlock) == 0); + break; + case isc_rwlocktype_write: + while (true) { + REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0); + /* Unlock if in middle of downgrade operation */ + if (atomic_load_acquire(&rwl->downgrade)) { + REQUIRE(pthread_rwlock_unlock(&rwl->rwlock) == + 0); + while (atomic_load_acquire(&rwl->downgrade)) { + } + continue; + } + break; + } + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { + int ret = 0; + switch (type) { + case isc_rwlocktype_read: + ret = pthread_rwlock_tryrdlock(&rwl->rwlock); + break; + case isc_rwlocktype_write: + ret = pthread_rwlock_trywrlock(&rwl->rwlock); + if ((ret == 0) && atomic_load_acquire(&rwl->downgrade)) { + isc_rwlock_unlock(rwl, type); + return (ISC_R_LOCKBUSY); + } + break; + default: + INSIST(0); + } + + switch (ret) { + case 0: + return (ISC_R_SUCCESS); + case EBUSY: + return (ISC_R_LOCKBUSY); + case EAGAIN: + return (ISC_R_LOCKBUSY); + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + +isc_result_t +isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { + UNUSED(type); + REQUIRE(pthread_rwlock_unlock(&rwl->rwlock) == 0); + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { + UNUSED(rwl); + return (ISC_R_LOCKBUSY); +} + +void +isc_rwlock_downgrade(isc_rwlock_t *rwl) { + atomic_store_release(&rwl->downgrade, true); + isc_rwlock_unlock(rwl, isc_rwlocktype_write); + isc_rwlock_lock(rwl, isc_rwlocktype_read); + atomic_store_release(&rwl->downgrade, false); +} + +void +isc_rwlock_destroy(isc_rwlock_t *rwl) { + pthread_rwlock_destroy(&rwl->rwlock); +} + +#else /* if USE_PTHREAD_RWLOCK */ + +#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k') +#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC) #ifndef RWLOCK_DEFAULT_READ_QUOTA #define RWLOCK_DEFAULT_READ_QUOTA 4 -#endif +#endif /* ifndef RWLOCK_DEFAULT_READ_QUOTA */ #ifndef RWLOCK_DEFAULT_WRITE_QUOTA #define RWLOCK_DEFAULT_WRITE_QUOTA 4 -#endif +#endif /* ifndef RWLOCK_DEFAULT_WRITE_QUOTA */ #ifndef RWLOCK_MAX_ADAPTIVE_COUNT #define RWLOCK_MAX_ADAPTIVE_COUNT 100 -#endif +#endif /* ifndef RWLOCK_MAX_ADAPTIVE_COUNT */ #if defined(_MSC_VER) -# include <intrin.h> -# define isc_rwlock_pause() YieldProcessor() +#include <intrin.h> +#define isc_rwlock_pause() YieldProcessor() #elif defined(__x86_64__) -# include <immintrin.h> -# define isc_rwlock_pause() _mm_pause() +#include <immintrin.h> +#define isc_rwlock_pause() _mm_pause() #elif defined(__i386__) -# define isc_rwlock_pause() __asm__ __volatile__ ("rep; nop") +#define isc_rwlock_pause() __asm__ __volatile__("rep; nop") #elif defined(__ia64__) -# define isc_rwlock_pause() __asm__ __volatile__ ("hint @pause") +#define isc_rwlock_pause() __asm__ __volatile__("hint @pause") #elif defined(__arm__) && HAVE_ARM_YIELD -# define isc_rwlock_pause() __asm__ __volatile__ ("yield") +#define isc_rwlock_pause() __asm__ __volatile__("yield") #elif defined(sun) && (defined(__sparc) || defined(__sparc__)) -# define isc_rwlock_pause() smt_pause() -#elif defined(__sparc) || defined(__sparc__) -# define isc_rwlock_pause() __asm__ __volatile__ ("pause") -#elif defined(__ppc__) || defined(_ARCH_PPC) || \ - defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) -# define isc_rwlock_pause() __asm__ volatile ("or 27,27,27") -#else -# define isc_rwlock_pause() -#endif +#define isc_rwlock_pause() smt_pause() +#elif (defined(__sparc) || defined(__sparc__)) && HAVE_SPARC_PAUSE +#define isc_rwlock_pause() __asm__ __volatile__("pause") +#elif defined(__ppc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || \ + defined(_ARCH_PWR2) || defined(_POWER) +#define isc_rwlock_pause() __asm__ volatile("or 27,27,27") +#else /* if defined(_MSC_VER) */ +#define isc_rwlock_pause() +#endif /* if defined(_MSC_VER) */ static isc_result_t isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type); #ifdef ISC_RWLOCK_TRACE -#include <stdio.h> /* Required for fprintf/stderr. */ -#include <isc/thread.h> /* Required for isc_thread_self(). */ +#include <stdio.h> /* Required for fprintf/stderr. */ + +#include <isc/thread.h> /* Required for isc_thread_self(). */ static void print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) { @@ -83,18 +182,16 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) { "write_granted=%u, write_quota=%u\n", rwl, isc_thread_self(), operation, (type == isc_rwlocktype_read ? "read" : "write"), - atomic_load_explicit(&rwl->write_requests, memory_order_relaxed), - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed), - atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed), - rwl->readers_waiting, - rwl->write_granted, rwl->write_quota); + atomic_load_acquire(&rwl->write_requests), + atomic_load_acquire(&rwl->write_completions), + atomic_load_acquire(&rwl->cnt_and_flag), rwl->readers_waiting, + atomic_load_acquire(&rwl->write_granted), rwl->write_quota); } -#endif /* ISC_RWLOCK_TRACE */ +#endif /* ISC_RWLOCK_TRACE */ isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, - unsigned int write_quota) -{ + unsigned int write_quota) { REQUIRE(rwl != NULL); /* @@ -103,18 +200,19 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, */ rwl->magic = 0; - rwl->spins = 0; + atomic_init(&rwl->spins, 0); atomic_init(&rwl->write_requests, 0); atomic_init(&rwl->write_completions, 0); atomic_init(&rwl->cnt_and_flag, 0); rwl->readers_waiting = 0; - rwl->write_granted = 0; + atomic_init(&rwl->write_granted, 0); if (read_quota != 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "read quota is not supported"); } - if (write_quota == 0) + if (write_quota == 0) { write_quota = RWLOCK_DEFAULT_WRITE_QUOTA; + } rwl->write_quota = write_quota; isc_mutex_init(&rwl->lock); @@ -131,9 +229,10 @@ void isc_rwlock_destroy(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); - REQUIRE(atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) == - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) && - atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) == 0 && rwl->readers_waiting == 0); + REQUIRE(atomic_load_acquire(&rwl->write_requests) == + atomic_load_acquire(&rwl->write_completions) && + atomic_load_acquire(&rwl->cnt_and_flag) == 0 && + rwl->readers_waiting == 0); rwl->magic = 0; (void)isc_condition_destroy(&rwl->readable); @@ -203,8 +302,8 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) { * really necessary.) */ -#define WRITER_ACTIVE 0x1 -#define READER_INCR 0x2 +#define WRITER_ACTIVE 0x1 +#define READER_INCR 0x2 static isc_result_t isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { @@ -214,16 +313,17 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { #ifdef ISC_RWLOCK_TRACE print_lock("prelock", rwl, type); -#endif +#endif /* ifdef ISC_RWLOCK_TRACE */ if (type == isc_rwlocktype_read) { - if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) + if (atomic_load_acquire(&rwl->write_requests) != + atomic_load_acquire(&rwl->write_completions)) { /* there is a waiting or active writer */ LOCK(&rwl->lock); - if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) { + if (atomic_load_acquire(&rwl->write_requests) != + atomic_load_acquire(&rwl->write_completions)) + { rwl->readers_waiting++; WAIT(&rwl->readable, &rwl->lock); rwl->readers_waiting--; @@ -231,18 +331,20 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { UNLOCK(&rwl->lock); } - cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag, - READER_INCR, - memory_order_relaxed); + cntflag = atomic_fetch_add_release(&rwl->cnt_and_flag, + READER_INCR); POST(cntflag); while (1) { - if ((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE) == 0) + if ((atomic_load_acquire(&rwl->cnt_and_flag) & + WRITER_ACTIVE) == 0) { break; + } /* A writer is still working */ LOCK(&rwl->lock); rwl->readers_waiting++; - if ((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE) != 0) { + if ((atomic_load_acquire(&rwl->cnt_and_flag) & + WRITER_ACTIVE) != 0) { WAIT(&rwl->readable, &rwl->lock); } rwl->readers_waiting--; @@ -279,16 +381,17 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { * quota, reset the condition (race among readers doesn't * matter). */ - rwl->write_granted = 0; + atomic_store_release(&rwl->write_granted, 0); } else { int32_t prev_writer; /* enter the waiting queue, and wait for our turn */ - prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1, - memory_order_relaxed); - while (atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != prev_writer) { + prev_writer = atomic_fetch_add_release(&rwl->write_requests, 1); + while (atomic_load_acquire(&rwl->write_completions) != + prev_writer) { LOCK(&rwl->lock); - if (atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != prev_writer) { + if (atomic_load_acquire(&rwl->write_completions) != + prev_writer) { WAIT(&rwl->writeable, &rwl->lock); UNLOCK(&rwl->lock); continue; @@ -297,30 +400,26 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { break; } - while (1) { - int_fast32_t zero = 0; - if (atomic_compare_exchange_strong_explicit - (&rwl->cnt_and_flag, &zero, WRITER_ACTIVE, - memory_order_relaxed, memory_order_relaxed)) - { - break; - } - + while (!atomic_compare_exchange_weak_acq_rel( + &rwl->cnt_and_flag, &(int_fast32_t){ 0 }, + WRITER_ACTIVE)) + { /* Another active reader or writer is working. */ LOCK(&rwl->lock); - if (atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) != 0) { + if (atomic_load_acquire(&rwl->cnt_and_flag) != 0) { WAIT(&rwl->writeable, &rwl->lock); } UNLOCK(&rwl->lock); } - INSIST((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE)); - rwl->write_granted++; + INSIST((atomic_load_acquire(&rwl->cnt_and_flag) & + WRITER_ACTIVE)); + atomic_fetch_add_release(&rwl->write_granted, 1); } #ifdef ISC_RWLOCK_TRACE print_lock("postlock", rwl, type); -#endif +#endif /* ifdef ISC_RWLOCK_TRACE */ return (ISC_R_SUCCESS); } @@ -328,12 +427,10 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { int32_t cnt = 0; - int32_t max_cnt = rwl->spins * 2 + 10; + int32_t spins = atomic_load_acquire(&rwl->spins) * 2 + 10; + int32_t max_cnt = ISC_MAX(spins, RWLOCK_MAX_ADAPTIVE_COUNT); isc_result_t result = ISC_R_SUCCESS; - if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT) - max_cnt = RWLOCK_MAX_ADAPTIVE_COUNT; - do { if (cnt++ >= max_cnt) { result = isc__rwlock_lock(rwl, type); @@ -342,7 +439,7 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_rwlock_pause(); } while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS); - rwl->spins += (cnt - rwl->spins) / 8; + atomic_fetch_add_release(&rwl->spins, (cnt - spins) / 8); return (result); } @@ -355,33 +452,34 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { #ifdef ISC_RWLOCK_TRACE print_lock("prelock", rwl, type); -#endif +#endif /* ifdef ISC_RWLOCK_TRACE */ if (type == isc_rwlocktype_read) { /* If a writer is waiting or working, we fail. */ - if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) + if (atomic_load_acquire(&rwl->write_requests) != + atomic_load_acquire(&rwl->write_completions)) + { return (ISC_R_LOCKBUSY); + } /* Otherwise, be ready for reading. */ - cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag, - READER_INCR, - memory_order_relaxed); + cntflag = atomic_fetch_add_release(&rwl->cnt_and_flag, + READER_INCR); if ((cntflag & WRITER_ACTIVE) != 0) { /* * A writer is working. We lose, and cancel the read * request. */ - cntflag = atomic_fetch_sub_explicit - (&rwl->cnt_and_flag, READER_INCR, - memory_order_relaxed); + cntflag = atomic_fetch_sub_release(&rwl->cnt_and_flag, + READER_INCR); /* * If no other readers are waiting and we've suspended * new writers in this short period, wake them up. */ if (cntflag == READER_INCR && - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_requests, memory_order_relaxed)) { + atomic_load_acquire(&rwl->write_completions) != + atomic_load_acquire(&rwl->write_requests)) + { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); @@ -392,9 +490,8 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { } else { /* Try locking without entering the waiting queue. */ int_fast32_t zero = 0; - if (!atomic_compare_exchange_strong_explicit - (&rwl->cnt_and_flag, &zero, WRITER_ACTIVE, - memory_order_relaxed, memory_order_relaxed)) + if (!atomic_compare_exchange_strong_acq_rel( + &rwl->cnt_and_flag, &zero, WRITER_ACTIVE)) { return (ISC_R_LOCKBUSY); } @@ -403,15 +500,13 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { * XXXJT: jump into the queue, possibly breaking the writer * order. */ - atomic_fetch_sub_explicit(&rwl->write_completions, 1, - memory_order_relaxed); - - rwl->write_granted++; + atomic_fetch_sub_release(&rwl->write_completions, 1); + atomic_fetch_add_release(&rwl->write_granted, 1); } #ifdef ISC_RWLOCK_TRACE print_lock("postlock", rwl, type); -#endif +#endif /* ifdef ISC_RWLOCK_TRACE */ return (ISC_R_SUCCESS); } @@ -420,30 +515,26 @@ isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); - { - int_fast32_t reader_incr = READER_INCR; + int_fast32_t reader_incr = READER_INCR; + + /* Try to acquire write access. */ + atomic_compare_exchange_strong_acq_rel(&rwl->cnt_and_flag, &reader_incr, + WRITER_ACTIVE); + /* + * There must have been no writer, and there must have + * been at least one reader. + */ + INSIST((reader_incr & WRITER_ACTIVE) == 0 && + (reader_incr & ~WRITER_ACTIVE) != 0); - /* Try to acquire write access. */ - atomic_compare_exchange_strong_explicit - (&rwl->cnt_and_flag, &reader_incr, WRITER_ACTIVE, - memory_order_relaxed, memory_order_relaxed); + if (reader_incr == READER_INCR) { /* - * There must have been no writer, and there must have - * been at least one reader. + * We are the only reader and have been upgraded. + * Now jump into the head of the writer waiting queue. */ - INSIST((reader_incr & WRITER_ACTIVE) == 0 && - (reader_incr & ~WRITER_ACTIVE) != 0); - - if (reader_incr == READER_INCR) { - /* - * We are the only reader and have been upgraded. - * Now jump into the head of the writer waiting queue. - */ - atomic_fetch_sub_explicit(&rwl->write_completions, 1, - memory_order_relaxed); - } else - return (ISC_R_LOCKBUSY); - + atomic_fetch_sub_release(&rwl->write_completions, 1); + } else { + return (ISC_R_LOCKBUSY); } return (ISC_R_SUCCESS); @@ -455,25 +546,21 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); - { - /* Become an active reader. */ - prev_readers = atomic_fetch_add_explicit(&rwl->cnt_and_flag, - READER_INCR, - memory_order_relaxed); - /* We must have been a writer. */ - INSIST((prev_readers & WRITER_ACTIVE) != 0); - - /* Complete write */ - atomic_fetch_sub_explicit(&rwl->cnt_and_flag, WRITER_ACTIVE, - memory_order_relaxed); - atomic_fetch_add_explicit(&rwl->write_completions, 1, - memory_order_relaxed); - } + /* Become an active reader. */ + prev_readers = atomic_fetch_add_release(&rwl->cnt_and_flag, + READER_INCR); + /* We must have been a writer. */ + INSIST((prev_readers & WRITER_ACTIVE) != 0); + + /* Complete write */ + atomic_fetch_sub_release(&rwl->cnt_and_flag, WRITER_ACTIVE); + atomic_fetch_add_release(&rwl->write_completions, 1); /* Resume other readers */ LOCK(&rwl->lock); - if (rwl->readers_waiting > 0) + if (rwl->readers_waiting > 0) { BROADCAST(&rwl->readable); + } UNLOCK(&rwl->lock); } @@ -485,20 +572,20 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { #ifdef ISC_RWLOCK_TRACE print_lock("preunlock", rwl, type); -#endif +#endif /* ifdef ISC_RWLOCK_TRACE */ if (type == isc_rwlocktype_read) { - prev_cnt = atomic_fetch_sub_explicit(&rwl->cnt_and_flag, - READER_INCR, - memory_order_relaxed); + prev_cnt = atomic_fetch_sub_release(&rwl->cnt_and_flag, + READER_INCR); /* * If we're the last reader and any writers are waiting, wake * them up. We need to wake up all of them to ensure the * FIFO order. */ if (prev_cnt == READER_INCR && - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_requests, memory_order_relaxed)) { + atomic_load_acquire(&rwl->write_completions) != + atomic_load_acquire(&rwl->write_requests)) + { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); @@ -510,15 +597,15 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { * Reset the flag, and (implicitly) tell other writers * we are done. */ - atomic_fetch_sub_explicit(&rwl->cnt_and_flag, WRITER_ACTIVE, - memory_order_relaxed); - atomic_fetch_add_explicit(&rwl->write_completions, 1, - memory_order_relaxed); - - if (rwl->write_granted >= rwl->write_quota || - (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) == - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) || - (atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & ~WRITER_ACTIVE)) { + atomic_fetch_sub_release(&rwl->cnt_and_flag, WRITER_ACTIVE); + atomic_fetch_add_release(&rwl->write_completions, 1); + + if ((atomic_load_acquire(&rwl->write_granted) >= + rwl->write_quota) || + (atomic_load_acquire(&rwl->write_requests) == + atomic_load_acquire(&rwl->write_completions)) || + (atomic_load_acquire(&rwl->cnt_and_flag) & ~WRITER_ACTIVE)) + { /* * We have passed the write quota, no writer is * waiting, or some readers are almost ready, pending @@ -535,9 +622,10 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { UNLOCK(&rwl->lock); } - if ((atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) != - atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) && - wakeup_writers) { + if ((atomic_load_acquire(&rwl->write_requests) != + atomic_load_acquire(&rwl->write_completions)) && + wakeup_writers) + { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); @@ -545,9 +633,10 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { } #ifdef ISC_RWLOCK_TRACE - print_lock("postunlock", - rwl, type); -#endif + print_lock("postunlock", rwl, type); +#endif /* ifdef ISC_RWLOCK_TRACE */ return (ISC_R_SUCCESS); } + +#endif /* USE_PTHREAD_RWLOCK */ diff --git a/lib/isc/safe.c b/lib/isc/safe.c new file mode 100644 index 00000000..1943f9ac --- /dev/null +++ b/lib/isc/safe.c @@ -0,0 +1,24 @@ +/* + * 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. + */ + +#include <openssl/crypto.h> + +#include <isc/safe.h> + +int +isc_safe_memequal(const void *s1, const void *s2, size_t len) { + return (!CRYPTO_memcmp(s1, s2, len)); +} + +void +isc_safe_memwipe(void *ptr, size_t len) { + OPENSSL_cleanse(ptr, len); +} diff --git a/lib/isc/serial.c b/lib/isc/serial.c index c98f0113..6b946a47 100644 --- a/lib/isc/serial.c +++ b/lib/isc/serial.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> #include <isc/serial.h> @@ -24,8 +21,9 @@ isc_serial_lt(uint32_t a, uint32_t b) { /* * Undefined => false */ - if (a == (b ^ 0x80000000U)) + if (a == (b ^ 0x80000000U)) { return (false); + } return (((int32_t)(a - b) < 0) ? true : false); } diff --git a/lib/isc/siphash.c b/lib/isc/siphash.c new file mode 100644 index 00000000..789942de --- /dev/null +++ b/lib/isc/siphash.c @@ -0,0 +1,229 @@ +/* + * 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. + */ + +#include <inttypes.h> +#include <string.h> +#include <unistd.h> + +#include <isc/endian.h> +#include <isc/siphash.h> +#include <isc/util.h> + +/* + * The implementation is based on SipHash reference C implementation by + * + * Copyright (c) 2012-2016 Jean-Philippe Aumasson + * <jeanphilippe.aumasson@gmail.com> Copyright (c) 2012-2014 Daniel J. Bernstein + * <djb@cr.yp.to> + * + * To the extent possible under law, the author(s) have dedicated all copyright + * and related and neighboring rights to this software to the public domain + * worldwide. This software is distributed without any warranty. You should + * have received a copy of the CC0 Public Domain Dedication along with this + * software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#define cROUNDS 2 +#define dROUNDS 4 + +#define ROTATE64(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) + +#define HALF_ROUND64(a, b, c, d, s, t) \ + a += b; \ + c += d; \ + b = ROTATE64(b, s) ^ a; \ + d = ROTATE64(d, t) ^ c; \ + a = ROTATE64(a, 32); + +#define FULL_ROUND64(v0, v1, v2, v3) \ + HALF_ROUND64(v0, v1, v2, v3, 13, 16); \ + HALF_ROUND64(v2, v1, v0, v3, 17, 21); + +#define SIPROUND FULL_ROUND64 + +#define ROTATE32(x, b) (uint32_t)(((x) << (b)) | ((x) >> (32 - (b)))) + +#define HALF_ROUND32(a, b, c, d, s, t) \ + a += b; \ + c += d; \ + b = ROTATE32(b, s) ^ a; \ + d = ROTATE32(d, t) ^ c; \ + a = ROTATE32(a, 16); + +#define FULL_ROUND32(v0, v1, v2, v3) \ + HALF_ROUND32(v0, v1, v2, v3, 5, 8); \ + HALF_ROUND32(v2, v1, v0, v3, 13, 7); + +#define HALFSIPROUND FULL_ROUND32 + +#define U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); + +#define U8TO32_LE(p) \ + (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) + +#define U64TO8_LE(p, v) \ + U32TO8_LE((p), (uint32_t)((v))); \ + U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); + +#define U8TO64_LE(p) \ + (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ + ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ + ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ + ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +void +isc_siphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, + uint8_t *out) { + REQUIRE(k != NULL); + REQUIRE(out != NULL); + + uint64_t k0 = U8TO64_LE(k); + uint64_t k1 = U8TO64_LE(k + 8); + + uint64_t v0 = UINT64_C(0x736f6d6570736575) ^ k0; + uint64_t v1 = UINT64_C(0x646f72616e646f6d) ^ k1; + uint64_t v2 = UINT64_C(0x6c7967656e657261) ^ k0; + uint64_t v3 = UINT64_C(0x7465646279746573) ^ k1; + + uint64_t b = ((uint64_t)inlen) << 56; + + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const size_t left = inlen & 7; + + for (; in != end; in += 8) { + uint64_t m = U8TO64_LE(in); + + v3 ^= m; + + for (size_t i = 0; i < cROUNDS; ++i) { + SIPROUND(v0, v1, v2, v3); + } + + v0 ^= m; + } + + switch (left) { + case 7: + b |= ((uint64_t)in[6]) << 48; + /* FALLTHROUGH */ + case 6: + b |= ((uint64_t)in[5]) << 40; + /* FALLTHROUGH */ + case 5: + b |= ((uint64_t)in[4]) << 32; + /* FALLTHROUGH */ + case 4: + b |= ((uint64_t)in[3]) << 24; + /* FALLTHROUGH */ + case 3: + b |= ((uint64_t)in[2]) << 16; + /* FALLTHROUGH */ + case 2: + b |= ((uint64_t)in[1]) << 8; + /* FALLTHROUGH */ + case 1: + b |= ((uint64_t)in[0]); + /* FALLTHROUGH */ + case 0: + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + + v3 ^= b; + + for (size_t i = 0; i < cROUNDS; ++i) { + SIPROUND(v0, v1, v2, v3); + } + + v0 ^= b; + + v2 ^= 0xff; + + for (size_t i = 0; i < dROUNDS; ++i) { + SIPROUND(v0, v1, v2, v3); + } + + b = v0 ^ v1 ^ v2 ^ v3; + + U64TO8_LE(out, b); +} + +void +isc_halfsiphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, + uint8_t *out) { + REQUIRE(k != NULL); + REQUIRE(out != NULL); + + uint32_t k0 = U8TO32_LE(k); + uint32_t k1 = U8TO32_LE(k + 4); + + uint32_t v0 = UINT32_C(0x00000000) ^ k0; + uint32_t v1 = UINT32_C(0x00000000) ^ k1; + uint32_t v2 = UINT32_C(0x6c796765) ^ k0; + uint32_t v3 = UINT32_C(0x74656462) ^ k1; + + uint32_t b = ((uint32_t)inlen) << 24; + + const uint8_t *end = in + inlen - (inlen % sizeof(uint32_t)); + const int left = inlen & 3; + + for (; in != end; in += 4) { + uint32_t m = U8TO32_LE(in); + v3 ^= m; + + for (size_t i = 0; i < cROUNDS; ++i) { + HALFSIPROUND(v0, v1, v2, v3); + } + + v0 ^= m; + } + + switch (left) { + case 3: + b |= ((uint32_t)in[2]) << 16; + /* FALLTHROUGH */ + case 2: + b |= ((uint32_t)in[1]) << 8; + /* FALLTHROUGH */ + case 1: + b |= ((uint32_t)in[0]); + /* FALLTHROUGH */ + case 0: + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + + v3 ^= b; + + for (size_t i = 0; i < cROUNDS; ++i) { + HALFSIPROUND(v0, v1, v2, v3); + } + + v0 ^= b; + + v2 ^= 0xff; + + for (size_t i = 0; i < dROUNDS; ++i) { + HALFSIPROUND(v0, v1, v2, v3); + } + + b = v1 ^ v3; + U32TO8_LE(out, b); +} diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index a417c252..315f68ce 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -3,19 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdbool.h> #include <stdio.h> +#if defined(WIN32) || defined(WIN64) +#include <malloc.h> +#endif /* if defined(WIN32) || defined(WIN64) */ #include <isc/buffer.h> #include <isc/hash.h> @@ -28,48 +28,56 @@ bool isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { - return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| - ISC_SOCKADDR_CMPPORT| - ISC_SOCKADDR_CMPSCOPE)); + return (isc_sockaddr_compare(a, b, + ISC_SOCKADDR_CMPADDR | + ISC_SOCKADDR_CMPPORT | + ISC_SOCKADDR_CMPSCOPE)); } bool isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { - return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| - ISC_SOCKADDR_CMPSCOPE)); + return (isc_sockaddr_compare( + a, b, ISC_SOCKADDR_CMPADDR | ISC_SOCKADDR_CMPSCOPE)); } bool isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, - unsigned int flags) -{ + unsigned int flags) { REQUIRE(a != NULL && b != NULL); - if (a->length != b->length) + if (a->length != b->length) { return (false); + } /* * We don't just memcmp because the sin_zero field isn't always * zero. */ - if (a->type.sa.sa_family != b->type.sa.sa_family) + if (a->type.sa.sa_family != b->type.sa.sa_family) { return (false); + } switch (a->type.sa.sa_family) { case AF_INET: if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, sizeof(a->type.sin.sin_addr)) != 0) + { return (false); + } if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && a->type.sin.sin_port != b->type.sin.sin_port) + { return (false); + } break; case AF_INET6: if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, sizeof(a->type.sin6.sin6_addr)) != 0) + { return (false); + } /* * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return * false if one of the scopes in zero. @@ -77,24 +85,28 @@ isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 && a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id && ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 || - (a->type.sin6.sin6_scope_id != 0 && - b->type.sin6.sin6_scope_id != 0))) + (a->type.sin6.sin6_scope_id != 0 && + b->type.sin6.sin6_scope_id != 0))) + { return (false); + } if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && a->type.sin6.sin6_port != b->type.sin6.sin6_port) + { return (false); + } break; default: - if (memcmp(&a->type, &b->type, a->length) != 0) + if (memcmp(&a->type, &b->type, a->length) != 0) { return (false); + } } return (true); } bool isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b, - unsigned int prefixlen) -{ + unsigned int prefixlen) { isc_netaddr_t na, nb; isc_netaddr_fromsockaddr(&na, a); isc_netaddr_fromsockaddr(&nb, b); @@ -118,18 +130,24 @@ isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) { */ switch (sockaddr->type.sa.sa_family) { case AF_INET: - snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin.sin_port)); + snprintf(pbuf, sizeof(pbuf), "%u", + ntohs(sockaddr->type.sin.sin_port)); break; case AF_INET6: - snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin6.sin6_port)); + snprintf(pbuf, sizeof(pbuf), "%u", + ntohs(sockaddr->type.sin6.sin6_port)); break; #ifdef ISC_PLAFORM_HAVESYSUNH case AF_UNIX: plen = strlen(sockaddr->type.sunix.sun_path); - if (plen >= isc_buffer_availablelength(target)) + if (plen >= isc_buffer_availablelength(target)) { return (ISC_R_NOSPACE); + } - isc_buffer_putmem(target, sockaddr->type.sunix.sun_path, plen); + isc_buffer_putmem( + target, + (const unsigned char *)sockaddr->type.sunix.sun_path, + plen); /* * Null terminate after used region. @@ -139,7 +157,7 @@ isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) { avail.base[0] = '\0'; return (ISC_R_SUCCESS); -#endif +#endif /* ifdef ISC_PLAFORM_HAVESYSUNH */ default: return (ISC_R_FAILURE); } @@ -149,11 +167,13 @@ isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) { isc_netaddr_fromsockaddr(&netaddr, sockaddr); result = isc_netaddr_totext(&netaddr, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } - if (1 + plen + 1 > isc_buffer_availablelength(target)) + if (1 + plen + 1 > isc_buffer_availablelength(target)) { return (ISC_R_NOSPACE); + } isc_buffer_putmem(target, (const unsigned char *)"#", 1); isc_buffer_putmem(target, (const unsigned char *)pbuf, plen); @@ -173,8 +193,9 @@ isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) { isc_result_t result; isc_buffer_t buf; - if (size == 0U) + if (size == 0U) { return; + } isc_buffer_init(&buf, array, size); result = isc_sockaddr_totext(sa, &buf); @@ -182,8 +203,7 @@ isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) { /* * The message is the same as in netaddr.c. */ - snprintf(array, size, - "<unknown address, family %u>", + snprintf(array, size, "<unknown address, family %u>", sa->type.sa.sa_family); array[size - 1] = '\0'; } @@ -211,8 +231,9 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only) { if (IN6_IS_ADDR_V4MAPPED(in6)) { s += 12; length = sizeof(sockaddr->type.sin.sin_addr.s_addr); - } else + } else { length = sizeof(sockaddr->type.sin6.sin6_addr); + } p = ntohs(sockaddr->type.sin6.sin6_port); break; default: @@ -224,16 +245,20 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only) { p = 0; } - h = isc_hash_function(s, length, true, NULL); - if (!address_only) - h = isc_hash_function(&p, sizeof(p), true, &h); + uint8_t buf[sizeof(struct sockaddr_storage) + sizeof(p)]; + memmove(buf, s, length); + if (!address_only) { + memmove(buf + length, &p, sizeof(p)); + h = isc_hash_function(buf, length + sizeof(p), true); + } else { + h = isc_hash_function(buf, length, true); + } return (h); } void -isc_sockaddr_any(isc_sockaddr_t *sockaddr) -{ +isc_sockaddr_any(isc_sockaddr_t *sockaddr) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = AF_INET; sockaddr->type.sin.sin_addr.s_addr = INADDR_ANY; @@ -243,8 +268,7 @@ isc_sockaddr_any(isc_sockaddr_t *sockaddr) } void -isc_sockaddr_any6(isc_sockaddr_t *sockaddr) -{ +isc_sockaddr_any6(isc_sockaddr_t *sockaddr) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; sockaddr->type.sin6.sin6_addr = in6addr_any; @@ -255,8 +279,7 @@ isc_sockaddr_any6(isc_sockaddr_t *sockaddr) void isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, - in_port_t port) -{ + in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = AF_INET; sockaddr->type.sin.sin_addr = *ina; @@ -267,23 +290,22 @@ isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, void isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int pf) { - switch (pf) { - case AF_INET: - isc_sockaddr_any(sockaddr); - break; - case AF_INET6: - isc_sockaddr_any6(sockaddr); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } + switch (pf) { + case AF_INET: + isc_sockaddr_any(sockaddr); + break; + case AF_INET6: + isc_sockaddr_any6(sockaddr); + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } } void isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6, - in_port_t port) -{ + in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; sockaddr->type.sin6.sin6_addr = *ina6; @@ -294,8 +316,7 @@ isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6, void isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, - in_port_t port) -{ + in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; sockaddr->type.sin6.sin6_addr.s6_addr[10] = 0xff; @@ -308,7 +329,6 @@ isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, int isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) { - /* * Get the protocol family of 'sockaddr'. */ @@ -318,24 +338,22 @@ isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) { * Assume that PF_xxx == AF_xxx for all AF and PF. */ return (sockaddr->type.sa.sa_family); -#else +#else /* if (AF_INET == PF_INET && AF_INET6 == PF_INET6) */ switch (sockaddr->type.sa.sa_family) { case AF_INET: return (PF_INET); case AF_INET6: return (PF_INET6); default: - FATAL_ERROR(__FILE__, __LINE__, - "unknown address family: %d", + FATAL_ERROR(__FILE__, __LINE__, "unknown address family: %d", (int)sockaddr->type.sa.sa_family); } -#endif +#endif /* if (AF_INET == PF_INET && AF_INET6 == PF_INET6) */ } void isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na, - in_port_t port) -{ + in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = na->family; switch (na->family) { @@ -367,8 +385,7 @@ isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port) { sockaddr->type.sin6.sin6_port = htons(port); break; default: - FATAL_ERROR(__FILE__, __LINE__, - "unknown address family: %d", + FATAL_ERROR(__FILE__, __LINE__, "unknown address family: %d", (int)sockaddr->type.sa.sa_family); } } @@ -385,8 +402,7 @@ isc_sockaddr_getport(const isc_sockaddr_t *sockaddr) { port = ntohs(sockaddr->type.sin6.sin6_port); break; default: - FATAL_ERROR(__FILE__, __LINE__, - "unknown address family: %d", + FATAL_ERROR(__FILE__, __LINE__, "unknown address family: %d", (int)sockaddr->type.sa.sa_family); } @@ -398,7 +414,8 @@ isc_sockaddr_ismulticast(const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; if (sockaddr->type.sa.sa_family == AF_INET || - sockaddr->type.sa.sa_family == AF_INET6) { + sockaddr->type.sa.sa_family == AF_INET6) + { isc_netaddr_fromsockaddr(&netaddr, sockaddr); return (isc_netaddr_ismulticast(&netaddr)); } @@ -452,17 +469,45 @@ isc_sockaddr_isnetzero(const isc_sockaddr_t *sockaddr) { isc_result_t isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) { #ifdef ISC_PLATFORM_HAVESYSUNH - if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path)) + if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path)) { return (ISC_R_NOSPACE); + } memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->length = sizeof(sockaddr->type.sunix); sockaddr->type.sunix.sun_family = AF_UNIX; strlcpy(sockaddr->type.sunix.sun_path, path, sizeof(sockaddr->type.sunix.sun_path)); return (ISC_R_SUCCESS); -#else +#else /* ifdef ISC_PLATFORM_HAVESYSUNH */ UNUSED(sockaddr); UNUSED(path); return (ISC_R_NOTIMPLEMENTED); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ +} + +isc_result_t +isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa) { + unsigned int length = 0; + + switch (sa->sa_family) { + case AF_INET: + length = sizeof(isa->type.sin); + break; + case AF_INET6: + length = sizeof(isa->type.sin6); + break; +#ifdef ISC_PLATFORM_HAVESYSUNH + case AF_UNIX: + length = sizeof(isa->type.sunix); + break; +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ + default: + return (ISC_R_NOTIMPLEMENTED); + } + + memset(isa, 0, sizeof(isc_sockaddr_t)); + memcpy(isa, sa, length); + isa->length = length; + + return (ISC_R_SUCCESS); } diff --git a/lib/isc/stats.c b/lib/isc/stats.c index 9a0e2f10..7fee22e2 100644 --- a/lib/isc/stats.c +++ b/lib/isc/stats.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <inttypes.h> #include <string.h> @@ -27,33 +24,35 @@ #include <isc/stats.h> #include <isc/util.h> -#define ISC_STATS_MAGIC ISC_MAGIC('S', 't', 'a', 't') -#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC) +#define ISC_STATS_MAGIC ISC_MAGIC('S', 't', 'a', 't') +#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC) #if defined(_WIN32) && !defined(_WIN64) -typedef atomic_int_fast32_t isc_stat_t; -#else -typedef atomic_int_fast64_t isc_stat_t; -#endif +typedef atomic_int_fast32_t isc__atomic_statcounter_t; +#else /* if defined(_WIN32) && !defined(_WIN64) */ +typedef atomic_int_fast64_t isc__atomic_statcounter_t; +#endif /* if defined(_WIN32) && !defined(_WIN64) */ struct isc_stats { - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t refs; - int ncounters; - isc_stat_t *counters; + unsigned int magic; + isc_mem_t *mctx; + isc_refcount_t references; + int ncounters; + isc__atomic_statcounter_t *counters; }; static isc_result_t create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) { isc_stats_t *stats; + size_t counters_alloc_size; REQUIRE(statsp != NULL && *statsp == NULL); stats = isc_mem_get(mctx, sizeof(*stats)); - stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters); - isc_refcount_init(&stats->refs, 1); - memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters); + counters_alloc_size = sizeof(isc__atomic_statcounter_t) * ncounters; + stats->counters = isc_mem_get(mctx, counters_alloc_size); + isc_refcount_init(&stats->references, 1); + memset(stats->counters, 0, counters_alloc_size); stats->mctx = NULL; isc_mem_attach(mctx, &stats->mctx); stats->ncounters = ncounters; @@ -68,7 +67,7 @@ isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(statsp != NULL && *statsp == NULL); - isc_refcount_increment(&stats->refs); + isc_refcount_increment(&stats->references); *statsp = stats; } @@ -81,9 +80,11 @@ isc_stats_detach(isc_stats_t **statsp) { stats = *statsp; *statsp = NULL; - if (isc_refcount_decrement(&stats->refs) == 1) { + if (isc_refcount_decrement(&stats->references) == 1) { + isc_refcount_destroy(&stats->references); isc_mem_put(stats->mctx, stats->counters, - sizeof(isc_stat_t) * stats->ncounters); + sizeof(isc__atomic_statcounter_t) * + stats->ncounters); isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats)); } } @@ -107,30 +108,25 @@ isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); - atomic_fetch_add_explicit(&stats->counters[counter], 1, - memory_order_relaxed); + atomic_fetch_add_relaxed(&stats->counters[counter], 1); } void isc_stats_decrement(isc_stats_t *stats, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); - - atomic_fetch_sub_explicit(&stats->counters[counter], 1, - memory_order_relaxed); + atomic_fetch_sub_release(&stats->counters[counter], 1); } void -isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, - void *arg, unsigned int options) -{ +isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg, + unsigned int options) { int i; REQUIRE(ISC_STATS_VALID(stats)); for (i = 0; i < stats->ncounters; i++) { - uint32_t counter = atomic_load_explicit(&stats->counters[i], - memory_order_relaxed); + uint32_t counter = atomic_load_acquire(&stats->counters[i]); if ((options & ISC_STATSDUMP_VERBOSE) == 0 && counter == 0) { continue; } @@ -139,12 +135,33 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, } void -isc_stats_set(isc_stats_t *stats, uint64_t val, - isc_statscounter_t counter) -{ +isc_stats_set(isc_stats_t *stats, uint64_t val, isc_statscounter_t counter) { + REQUIRE(ISC_STATS_VALID(stats)); + REQUIRE(counter < stats->ncounters); + + atomic_store_release(&stats->counters[counter], val); +} + +void +isc_stats_update_if_greater(isc_stats_t *stats, isc_statscounter_t counter, + isc_statscounter_t value) { + REQUIRE(ISC_STATS_VALID(stats)); + REQUIRE(counter < stats->ncounters); + + isc_statscounter_t curr_value = + atomic_load_acquire(&stats->counters[counter]); + do { + if (curr_value >= value) { + break; + } + } while (!atomic_compare_exchange_weak_acq_rel( + &stats->counters[counter], &curr_value, value)); +} + +isc_statscounter_t +isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); - atomic_store_explicit(&stats->counters[counter], val, - memory_order_relaxed); + return (atomic_load_acquire(&stats->counters[counter])); } diff --git a/lib/isc/string.c b/lib/isc/string.c index c0fefc8a..0a47d082 100644 --- a/lib/isc/string.c +++ b/lib/isc/string.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -40,19 +40,16 @@ /*! \file */ -#include <config.h> // IWYU pragma: keep - #ifdef _GNU_SOURCE #undef _GNU_SOURCE -#endif +#endif /* ifdef _GNU_SOURCE */ #include <string.h> -#include <isc/string.h> // IWYU pragma: keep +#include <isc/string.h> /* IWYU pragma: keep */ #if !defined(HAVE_STRLCPY) size_t -strlcpy(char *dst, const char *src, size_t size) -{ +strlcpy(char *dst, const char *src, size_t size) { char *d = dst; const char *s = src; size_t n = size; @@ -69,20 +66,19 @@ strlcpy(char *dst, const char *src, size_t size) /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0U) { if (size != 0U) { - *d = '\0'; /* NUL-terminate dst */ + *d = '\0'; /* NUL-terminate dst */ + } + while (*s++) { } - while (*s++) - ; } - return(s - src - 1); /* count does not include NUL */ + return (s - src - 1); /* count does not include NUL */ } #endif /* !defined(HAVE_STRLCPY) */ #if !defined(HAVE_STRLCAT) size_t -strlcat(char *dst, const char *src, size_t size) -{ +strlcat(char *dst, const char *src, size_t size) { char *d = dst; const char *s = src; size_t n = size; @@ -96,7 +92,7 @@ strlcat(char *dst, const char *src, size_t size) n = size - dlen; if (n == 0U) { - return(dlen + strlen(s)); + return (dlen + strlen(s)); } while (*s != '\0') { if (n != 1U) { @@ -107,7 +103,7 @@ strlcat(char *dst, const char *src, size_t size) } *d = '\0'; - return(dlen + (s - src)); /* count does not include NUL */ + return (dlen + (s - src)); /* count does not include NUL */ } #endif /* !defined(HAVE_STRLCAT) */ @@ -115,7 +111,7 @@ int isc_string_strerror_r(int errnum, char *buf, size_t buflen) { #if defined(_WIN32) || defined(_WIN64) return (strerror_s(buf, buflen, errnum)); -#else +#else /* if defined(_WIN32) || defined(_WIN64) */ return (strerror_r(errnum, buf, buflen)); -#endif +#endif /* if defined(_WIN32) || defined(_WIN64) */ } diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index b6466d3e..fa5332f5 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <ctype.h> #include <stdbool.h> @@ -24,58 +21,49 @@ #include <isc/util.h> typedef struct elt { - char * key; - unsigned int type; - isc_symvalue_t value; - LINK(struct elt) link; + char *key; + unsigned int type; + isc_symvalue_t value; + LINK(struct elt) link; } elt_t; -typedef LIST(elt_t) eltlist_t; +typedef LIST(elt_t) eltlist_t; -#define SYMTAB_MAGIC ISC_MAGIC('S', 'y', 'm', 'T') -#define VALID_SYMTAB(st) ISC_MAGIC_VALID(st, SYMTAB_MAGIC) +#define SYMTAB_MAGIC ISC_MAGIC('S', 'y', 'm', 'T') +#define VALID_SYMTAB(st) ISC_MAGIC_VALID(st, SYMTAB_MAGIC) struct isc_symtab { /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - unsigned int size; - unsigned int count; - unsigned int maxload; - eltlist_t * table; - isc_symtabaction_t undefine_action; - void * undefine_arg; - bool case_sensitive; + unsigned int magic; + isc_mem_t *mctx; + unsigned int size; + unsigned int count; + unsigned int maxload; + eltlist_t *table; + isc_symtabaction_t undefine_action; + void *undefine_arg; + bool case_sensitive; }; isc_result_t isc_symtab_create(isc_mem_t *mctx, unsigned int size, - isc_symtabaction_t undefine_action, - void *undefine_arg, - bool case_sensitive, - isc_symtab_t **symtabp) -{ + isc_symtabaction_t undefine_action, void *undefine_arg, + bool case_sensitive, isc_symtab_t **symtabp) { isc_symtab_t *symtab; unsigned int i; REQUIRE(mctx != NULL); REQUIRE(symtabp != NULL && *symtabp == NULL); - REQUIRE(size > 0); /* Should be prime. */ + REQUIRE(size > 0); /* Should be prime. */ - symtab = (isc_symtab_t *)isc_mem_get(mctx, sizeof(*symtab)); - if (symtab == NULL) - return (ISC_R_NOMEMORY); + symtab = isc_mem_get(mctx, sizeof(*symtab)); symtab->mctx = NULL; isc_mem_attach(mctx, &symtab->mctx); - symtab->table = (eltlist_t *)isc_mem_get(mctx, - size * sizeof(eltlist_t)); - if (symtab->table == NULL) { - isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); - return (ISC_R_NOMEMORY); - } - for (i = 0; i < size; i++) + symtab->table = isc_mem_get(mctx, size * sizeof(eltlist_t)); + for (i = 0; i < size; i++) { INIT_LIST(symtab->table[i]); + } symtab->size = size; symtab->count = 0; symtab->maxload = size * 3 / 4; @@ -97,16 +85,17 @@ isc_symtab_destroy(isc_symtab_t **symtabp) { REQUIRE(symtabp != NULL); symtab = *symtabp; + *symtabp = NULL; REQUIRE(VALID_SYMTAB(symtab)); for (i = 0; i < symtab->size; i++) { for (elt = HEAD(symtab->table[i]); elt != NULL; elt = nelt) { nelt = NEXT(elt, link); - if (symtab->undefine_action != NULL) - (symtab->undefine_action)(elt->key, - elt->type, - elt->value, - symtab->undefine_arg); + if (symtab->undefine_action != NULL) { + (symtab->undefine_action)(elt->key, elt->type, + elt->value, + symtab->undefine_arg); + } isc_mem_put(symtab->mctx, elt, sizeof(*elt)); } } @@ -114,8 +103,6 @@ isc_symtab_destroy(isc_symtab_t **symtabp) { symtab->size * sizeof(eltlist_t)); symtab->magic = 0; isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); - - *symtabp = NULL; } static inline unsigned int @@ -144,26 +131,25 @@ hash(const char *key, bool case_sensitive) { return (h); } -#define FIND(s, k, t, b, e) \ - b = hash((k), (s)->case_sensitive) % (s)->size; \ - if ((s)->case_sensitive) { \ +#define FIND(s, k, t, b, e) \ + b = hash((k), (s)->case_sensitive) % (s)->size; \ + if ((s)->case_sensitive) { \ for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ - if (((t) == 0 || e->type == (t)) && \ - strcmp(e->key, (k)) == 0) \ - break; \ - } \ - } else { \ + if (((t) == 0 || e->type == (t)) && \ + strcmp(e->key, (k)) == 0) \ + break; \ + } \ + } else { \ for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ - if (((t) == 0 || e->type == (t)) && \ - strcasecmp(e->key, (k)) == 0) \ - break; \ - } \ + if (((t) == 0 || e->type == (t)) && \ + strcasecmp(e->key, (k)) == 0) \ + break; \ + } \ } isc_result_t isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type, - isc_symvalue_t *value) -{ + isc_symvalue_t *value) { unsigned int bucket; elt_t *elt; @@ -172,11 +158,13 @@ isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type, FIND(symtab, key, type, bucket, elt); - if (elt == NULL) + if (elt == NULL) { return (ISC_R_NOTFOUND); + } - if (value != NULL) + if (value != NULL) { *value = elt->value; + } return (ISC_R_SUCCESS); } @@ -193,11 +181,10 @@ grow_table(isc_symtab_t *symtab) { INSIST(newsize > 0U && newmax > 0U); newtable = isc_mem_get(symtab->mctx, newsize * sizeof(eltlist_t)); - if (newtable == NULL) - return; - for (i = 0; i < newsize; i++) + for (i = 0; i < newsize; i++) { INIT_LIST(newtable[i]); + } for (i = 0; i < symtab->size; i++) { elt_t *elt, *nelt; @@ -223,8 +210,7 @@ grow_table(isc_symtab_t *symtab) { isc_result_t isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type, - isc_symvalue_t value, isc_symexists_t exists_policy) -{ + isc_symvalue_t value, isc_symexists_t exists_policy) { unsigned int bucket; elt_t *elt; @@ -235,18 +221,18 @@ isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type, FIND(symtab, key, type, bucket, elt); if (exists_policy != isc_symexists_add && elt != NULL) { - if (exists_policy == isc_symexists_reject) + if (exists_policy == isc_symexists_reject) { return (ISC_R_EXISTS); + } INSIST(exists_policy == isc_symexists_replace); UNLINK(symtab->table[bucket], elt, link); - if (symtab->undefine_action != NULL) + if (symtab->undefine_action != NULL) { (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); + } } else { - elt = (elt_t *)isc_mem_get(symtab->mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); + elt = isc_mem_get(symtab->mctx, sizeof(*elt)); ISC_LINK_INIT(elt, link); symtab->count++; } @@ -267,8 +253,9 @@ isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type, */ PREPEND(symtab->table[bucket], elt, link); - if (symtab->count > symtab->maxload) + if (symtab->count > symtab->maxload) { grow_table(symtab); + } return (ISC_R_SUCCESS); } @@ -283,12 +270,14 @@ isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type) { FIND(symtab, key, type, bucket, elt); - if (elt == NULL) + if (elt == NULL) { return (ISC_R_NOTFOUND); + } - if (symtab->undefine_action != NULL) - (symtab->undefine_action)(elt->key, elt->type, - elt->value, symtab->undefine_arg); + if (symtab->undefine_action != NULL) { + (symtab->undefine_action)(elt->key, elt->type, elt->value, + symtab->undefine_arg); + } UNLINK(symtab->table[bucket], elt, link); isc_mem_put(symtab->mctx, elt, sizeof(*elt)); symtab->count--; diff --git a/lib/isc/task.c b/lib/isc/task.c index 8d6d409d..da0f4d90 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -16,31 +16,37 @@ * for changing states. */ -#include <config.h> - #include <stdbool.h> #include <isc/app.h> #include <isc/atomic.h> #include <isc/condition.h> #include <isc/event.h> -#include <isc/json.h> #include <isc/magic.h> #include <isc/mem.h> #include <isc/once.h> #include <isc/platform.h> #include <isc/print.h> -#include <isc/string.h> #include <isc/random.h> +#include <isc/refcount.h> +#include <isc/string.h> #include <isc/task.h> #include <isc/thread.h> #include <isc/time.h> #include <isc/util.h> -#include <isc/xml.h> + +#ifdef HAVE_LIBXML2 +#include <libxml/xmlwriter.h> +#define ISC_XMLCHAR (const xmlChar *) +#endif /* HAVE_LIBXML2 */ + +#ifdef HAVE_JSON_C +#include <json_object.h> +#endif /* HAVE_JSON_C */ #ifdef OPENSSL_LEAKS #include <openssl/err.h> -#endif +#endif /* ifdef OPENSSL_LEAKS */ /* * Task manager is built around 'as little locking as possible' concept. @@ -55,35 +61,40 @@ */ #ifdef ISC_TASK_TRACE -#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \ - task, isc_thread_self(), (m)) -#define XTTRACE(t, m) fprintf(stderr, "task %p thread %lu: %s\n", \ - (t), isc_thread_self(), (m)) -#define XTHREADTRACE(m) fprintf(stderr, "thread %lu: %s\n", \ - isc_thread_self(), (m)) -#else +#define XTRACE(m) \ + fprintf(stderr, "task %p thread %lu: %s\n", task, isc_thread_self(), \ + (m)) +#define XTTRACE(t, m) \ + fprintf(stderr, "task %p thread %lu: %s\n", (t), isc_thread_self(), (m)) +#define XTHREADTRACE(m) \ + fprintf(stderr, "thread %lu: %s\n", isc_thread_self(), (m)) +#else /* ifdef ISC_TASK_TRACE */ #define XTRACE(m) #define XTTRACE(t, m) #define XTHREADTRACE(m) -#endif +#endif /* ifdef ISC_TASK_TRACE */ /*** *** Types. ***/ typedef enum { - task_state_idle, task_state_ready, task_state_running, - task_state_done + task_state_idle, /* not doing anything, events queue empty */ + task_state_ready, /* waiting in worker's queue */ + task_state_paused, /* not running, paused */ + task_state_pausing, /* running, waiting to be paused */ + task_state_running, /* actively processing events */ + task_state_done /* shutting down, no events or references */ } task_state_t; -#if defined(HAVE_LIBXML2) || defined(HAVE_JSON) +#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) static const char *statenames[] = { - "idle", "ready", "running", "done", + "idle", "ready", "paused", "pausing", "running", "done", }; -#endif +#endif /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */ -#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K') -#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC) +#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K') +#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC) typedef struct isc__task isc__task_t; typedef struct isc__taskmgr isc__taskmgr_t; @@ -91,83 +102,91 @@ typedef struct isc__taskqueue isc__taskqueue_t; struct isc__task { /* Not locked. */ - isc_task_t common; - isc__taskmgr_t * manager; - isc_mutex_t lock; + isc_task_t common; + isc__taskmgr_t *manager; + isc_mutex_t lock; /* Locked by task lock. */ - task_state_t state; - unsigned int references; - isc_eventlist_t events; - isc_eventlist_t on_shutdown; - unsigned int nevents; - unsigned int quantum; - unsigned int flags; - isc_stdtime_t now; - isc_time_t tnow; - char name[16]; - void * tag; - unsigned int threadid; - bool bound; + task_state_t state; + int pause_cnt; + isc_refcount_t references; + isc_eventlist_t events; + isc_eventlist_t on_shutdown; + unsigned int nevents; + unsigned int quantum; + isc_stdtime_t now; + isc_time_t tnow; + char name[16]; + void *tag; + unsigned int threadid; + bool bound; + /* Protected by atomics */ + atomic_uint_fast32_t flags; /* Locked by task manager lock. */ - LINK(isc__task_t) link; - LINK(isc__task_t) ready_link; - LINK(isc__task_t) ready_priority_link; + LINK(isc__task_t) link; + LINK(isc__task_t) ready_link; + LINK(isc__task_t) ready_priority_link; }; -#define TASK_F_SHUTTINGDOWN 0x01 -#define TASK_F_PRIVILEGED 0x02 +#define TASK_F_SHUTTINGDOWN 0x01 +#define TASK_F_PRIVILEGED 0x02 -#define TASK_SHUTTINGDOWN(t) (((t)->flags & TASK_F_SHUTTINGDOWN) \ - != 0) +#define TASK_SHUTTINGDOWN(t) \ + ((atomic_load_acquire(&(t)->flags) & TASK_F_SHUTTINGDOWN) != 0) +#define TASK_PRIVILEGED(t) \ + ((atomic_load_acquire(&(t)->flags) & TASK_F_PRIVILEGED) != 0) -#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC) +#define TASK_FLAG_SET(t, f) atomic_fetch_or_release(&(t)->flags, (f)) +#define TASK_FLAG_CLR(t, f) atomic_fetch_and_release(&(t)->flags, ~(f)) -typedef ISC_LIST(isc__task_t) isc__tasklist_t; +#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M') +#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC) + +typedef ISC_LIST(isc__task_t) isc__tasklist_t; struct isc__taskqueue { /* Everything locked by lock */ - isc_mutex_t lock; - isc__tasklist_t ready_tasks; - isc__tasklist_t ready_priority_tasks; - isc_condition_t work_available; - isc_thread_t thread; - unsigned int threadid; - isc__taskmgr_t *manager; + isc_mutex_t lock; + isc__tasklist_t ready_tasks; + isc__tasklist_t ready_priority_tasks; + isc_condition_t work_available; + isc_thread_t thread; + unsigned int threadid; + isc__taskmgr_t *manager; }; struct isc__taskmgr { /* Not locked. */ - isc_taskmgr_t common; - isc_mem_t * mctx; - isc_mutex_t lock; - isc_mutex_t halt_lock; - isc_condition_t halt_cond; - unsigned int workers; - atomic_uint_fast32_t tasks_running; - atomic_uint_fast32_t tasks_ready; - atomic_uint_fast32_t curq; - atomic_uint_fast32_t tasks_count; - isc__taskqueue_t *queues; + isc_taskmgr_t common; + isc_mem_t *mctx; + isc_mutex_t lock; + isc_mutex_t halt_lock; + isc_condition_t halt_cond; + unsigned int workers; + atomic_uint_fast32_t tasks_running; + atomic_uint_fast32_t tasks_ready; + atomic_uint_fast32_t curq; + atomic_uint_fast32_t tasks_count; + isc__taskqueue_t *queues; + isc_nm_t *nm; /* Locked by task manager lock. */ - unsigned int default_quantum; - LIST(isc__task_t) tasks; - atomic_uint_fast32_t mode; - atomic_bool pause_req; - atomic_bool exclusive_req; - atomic_bool exiting; + unsigned int default_quantum; + LIST(isc__task_t) tasks; + atomic_uint_fast32_t mode; + atomic_bool pause_req; + atomic_bool exclusive_req; + atomic_bool exiting; /* Locked by halt_lock */ - unsigned int halted; + unsigned int halted; /* * Multiple threads can read/write 'excl' at the same time, so we need * to protect the access. We can't use 'lock' since isc_task_detach() * will try to acquire it. */ - isc_mutex_t excl_lock; - isc__task_t *excl; + isc_mutex_t excl_lock; + isc__task_t *excl; }; void @@ -175,10 +194,10 @@ isc__taskmgr_pause(isc_taskmgr_t *manager0); void isc__taskmgr_resume(isc_taskmgr_t *manager0); - -#define DEFAULT_DEFAULT_QUANTUM 25 -#define FINISHED(m) (atomic_load_relaxed(&((m)->exiting)) == true && \ - atomic_load(&(m)->tasks_count) == 0) +#define DEFAULT_DEFAULT_QUANTUM 25 +#define FINISHED(m) \ + (atomic_load_relaxed(&((m)->exiting)) && \ + atomic_load(&(m)->tasks_count) == 0) /*% * The following are intended for internal use (indicated by "isc__" @@ -223,11 +242,12 @@ task_finished(isc__task_t *task) { REQUIRE(EMPTY(task->events)); REQUIRE(task->nevents == 0); REQUIRE(EMPTY(task->on_shutdown)); - REQUIRE(task->references == 0); REQUIRE(task->state == task_state_done); XTRACE("task_finished"); + isc_refcount_destroy(&task->references); + LOCK(&manager->lock); UNLINK(manager->tasks, task, link); atomic_fetch_sub(&manager->tasks_count, 1); @@ -249,15 +269,13 @@ task_finished(isc__task_t *task) { isc_result_t isc_task_create(isc_taskmgr_t *manager0, unsigned int quantum, - isc_task_t **taskp) -{ + isc_task_t **taskp) { return (isc_task_create_bound(manager0, quantum, taskp, -1)); } isc_result_t isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum, - isc_task_t **taskp, int threadid) -{ + isc_task_t **taskp, int threadid) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; isc__task_t *task; bool exiting; @@ -266,15 +284,13 @@ isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum, REQUIRE(taskp != NULL && *taskp == NULL); task = isc_mem_get(manager->mctx, sizeof(*task)); - if (task == NULL) - return (ISC_R_NOMEMORY); XTRACE("isc_task_create"); task->manager = manager; if (threadid == -1) { /* * Task is not pinned to a queue, it's threadid will be - * choosen when first task will be sent to it - either + * chosen when first task will be sent to it - either * randomly or specified by isc_task_sendto. */ task->bound = false; @@ -290,12 +306,14 @@ isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum, isc_mutex_init(&task->lock); task->state = task_state_idle; - task->references = 1; + task->pause_cnt = 0; + + isc_refcount_init(&task->references, 1); INIT_LIST(task->events); INIT_LIST(task->on_shutdown); task->nevents = 0; task->quantum = (quantum > 0) ? quantum : manager->default_quantum; - task->flags = 0; + atomic_init(&task->flags, 0); task->now = 0; isc_time_settoepoch(&task->tnow); memset(task->name, 0, sizeof(task->name)); @@ -340,9 +358,7 @@ isc_task_attach(isc_task_t *source0, isc_task_t **targetp) { XTTRACE(source, "isc_task_attach"); - LOCK(&source->lock); - source->references++; - UNLOCK(&source->lock); + isc_refcount_increment(&source->references); *targetp = (isc_task_t *)source; } @@ -358,22 +374,23 @@ task_shutdown(isc__task_t *task) { XTRACE("task_shutdown"); - if (! TASK_SHUTTINGDOWN(task)) { + if (!TASK_SHUTTINGDOWN(task)) { XTRACE("shutting down"); - task->flags |= TASK_F_SHUTTINGDOWN; + TASK_FLAG_SET(task, TASK_F_SHUTTINGDOWN); if (task->state == task_state_idle) { INSIST(EMPTY(task->events)); task->state = task_state_ready; was_idle = true; } INSIST(task->state == task_state_ready || + task->state == task_state_paused || + task->state == task_state_pausing || task->state == task_state_running); /* * Note that we post shutdown events LIFO. */ - for (event = TAIL(task->on_shutdown); - event != NULL; + for (event = TAIL(task->on_shutdown); event != NULL; event = prev) { prev = PREV(event, ev_link); DEQUEUE(task->on_shutdown, event, ev_link); @@ -388,15 +405,14 @@ task_shutdown(isc__task_t *task) { /* * Moves a task onto the appropriate run queue. * - * Caller must NOT hold manager lock. + * Caller must NOT hold queue lock. */ static inline void task_ready(isc__task_t *task) { isc__taskmgr_t *manager = task->manager; - bool has_privilege = isc_task_privilege((isc_task_t *) task); + bool has_privilege = isc_task_privilege((isc_task_t *)task); REQUIRE(VALID_MANAGER(manager)); - REQUIRE(task->state == task_state_ready); XTRACE("task_ready"); LOCK(&manager->queues[task->threadid].lock); @@ -410,17 +426,15 @@ task_ready(isc__task_t *task) { static inline bool task_detach(isc__task_t *task) { - /* * Caller must be holding the task lock. */ - REQUIRE(task->references > 0); - XTRACE("detach"); - task->references--; - if (task->references == 0 && task->state == task_state_idle) { + if (isc_refcount_decrement(&task->references) == 1 && + task->state == task_state_idle) + { INSIST(EMPTY(task->events)); /* * There are no references to this task, and no @@ -456,8 +470,9 @@ isc_task_detach(isc_task_t **taskp) { was_idle = task_detach(task); UNLOCK(&task->lock); - if (was_idle) + if (was_idle) { task_ready(task); + } *taskp = NULL; } @@ -473,6 +488,7 @@ task_send(isc__task_t *task, isc_event_t **eventp, int c) { REQUIRE(eventp != NULL); event = *eventp; + *eventp = NULL; REQUIRE(event != NULL); REQUIRE(event->ev_type > 0); REQUIRE(task->state != task_state_done); @@ -487,10 +503,11 @@ task_send(isc__task_t *task, isc_event_t **eventp, int c) { task->state = task_state_ready; } INSIST(task->state == task_state_ready || - task->state == task_state_running); + task->state == task_state_running || + task->state == task_state_paused || + task->state == task_state_pausing); ENQUEUE(task->events, event, ev_link); task->nevents++; - *eventp = NULL; return (was_idle); } @@ -517,7 +534,6 @@ isc_task_sendto(isc_task_t *task0, isc_event_t **eventp, int c) { REQUIRE(VALID_TASK(task)); XTRACE("isc_task_send"); - /* * We're trying hard to hold locks for as short a time as possible. * We're also trying to hold as few locks as possible. This is why @@ -589,19 +605,19 @@ isc_task_sendtoanddetach(isc_task_t **taskp, isc_event_t **eventp, int c) { */ INSIST(!(idle1 && idle2)); - if (idle1 || idle2) + if (idle1 || idle2) { task_ready(task); + } *taskp = NULL; } -#define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0) +#define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0) static unsigned int dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first, - isc_eventtype_t last, void *tag, - isc_eventlist_t *events, bool purging) -{ + isc_eventtype_t last, void *tag, isc_eventlist_t *events, + bool purging) { isc_event_t *event, *next_event; unsigned int count = 0; @@ -625,7 +641,8 @@ dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first, if (event->ev_type >= first && event->ev_type <= last && (sender == NULL || event->ev_sender == sender) && (tag == NULL || event->ev_tag == tag) && - (!purging || PURGE_OK(event))) { + (!purging || PURGE_OK(event))) + { DEQUEUE(task->events, event, ev_link); task->nevents--; ENQUEUE(*events, event, ev_link); @@ -640,8 +657,7 @@ dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first, unsigned int isc_task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first, - isc_eventtype_t last, void *tag) -{ + isc_eventtype_t last, void *tag) { isc__task_t *task = (isc__task_t *)task0; unsigned int count; isc_eventlist_t events; @@ -656,8 +672,7 @@ isc_task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first, ISC_LIST_INIT(events); - count = dequeue_events(task, sender, first, last, tag, &events, - true); + count = dequeue_events(task, sender, first, last, tag, &events, true); for (event = HEAD(events); event != NULL; event = next_event) { next_event = NEXT(event, ev_link); @@ -674,8 +689,7 @@ isc_task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first, unsigned int isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, - void *tag) -{ + void *tag) { /* * Purge events from a task's event queue. */ @@ -710,9 +724,9 @@ isc_task_purgeevent(isc_task_t *task0, isc_event_t *event) { */ LOCK(&task->lock); - for (curr_event = HEAD(task->events); - curr_event != NULL; - curr_event = next_event) { + for (curr_event = HEAD(task->events); curr_event != NULL; + curr_event = next_event) + { next_event = NEXT(curr_event, ev_link); if (curr_event == event && PURGE_OK(event)) { DEQUEUE(task->events, curr_event, ev_link); @@ -722,8 +736,9 @@ isc_task_purgeevent(isc_task_t *task0, isc_event_t *event) { } UNLOCK(&task->lock); - if (curr_event == NULL) + if (curr_event == NULL) { return (false); + } isc_event_free(&curr_event); @@ -732,9 +747,7 @@ isc_task_purgeevent(isc_task_t *task0, isc_event_t *event) { unsigned int isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, - isc_eventtype_t last, void *tag, - isc_eventlist_t *events) -{ + isc_eventtype_t last, void *tag, isc_eventlist_t *events) { /* * Remove events from a task's event queue. */ @@ -742,28 +755,25 @@ isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, XTRACE("isc_task_unsendrange"); - return (dequeue_events((isc__task_t *)task, sender, first, - last, tag, events, false)); + return (dequeue_events((isc__task_t *)task, sender, first, last, tag, + events, false)); } unsigned int -isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, - void *tag, isc_eventlist_t *events) -{ +isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, + isc_eventlist_t *events) { /* * Remove events from a task's event queue. */ XTRACE("isc_task_unsend"); - return (dequeue_events((isc__task_t *)task, sender, type, - type, tag, events, false)); + return (dequeue_events((isc__task_t *)task, sender, type, type, tag, + events, false)); } isc_result_t -isc_task_onshutdown(isc_task_t *task0, isc_taskaction_t action, - void *arg) -{ +isc_task_onshutdown(isc_task_t *task0, isc_taskaction_t action, void *arg) { isc__task_t *task = (isc__task_t *)task0; bool disallowed = false; isc_result_t result = ISC_R_SUCCESS; @@ -777,25 +787,22 @@ isc_task_onshutdown(isc_task_t *task0, isc_taskaction_t action, REQUIRE(VALID_TASK(task)); REQUIRE(action != NULL); - event = isc_event_allocate(task->manager->mctx, - NULL, - ISC_TASKEVENT_SHUTDOWN, - action, - arg, + event = isc_event_allocate(task->manager->mctx, NULL, + ISC_TASKEVENT_SHUTDOWN, action, arg, sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - LOCK(&task->lock); if (TASK_SHUTTINGDOWN(task)) { disallowed = true; result = ISC_R_SHUTTINGDOWN; - } else + } else { + LOCK(&task->lock); ENQUEUE(task->on_shutdown, event, ev_link); - UNLOCK(&task->lock); + UNLOCK(&task->lock); + } - if (disallowed) + if (disallowed) { isc_mem_put(task->manager->mctx, event, sizeof(*event)); + } return (result); } @@ -815,13 +822,13 @@ isc_task_shutdown(isc_task_t *task0) { was_idle = task_shutdown(task); UNLOCK(&task->lock); - if (was_idle) + if (was_idle) { task_ready(task); + } } void isc_task_destroy(isc_task_t **taskp) { - /* * Destroy '*taskp'. */ @@ -848,7 +855,6 @@ isc_task_setname(isc_task_t *task0, const char *name, void *tag) { UNLOCK(&task->lock); } - const char * isc_task_getname(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; @@ -947,12 +953,15 @@ pop_readyq(isc__taskmgr_t *manager, int c) { * Push 'task' onto the ready_tasks queue. If 'task' has the privilege * flag set, then also push it onto the ready_priority_tasks queue. * - * Caller must hold the task manager lock. + * Caller must hold the task queue lock. */ static inline void push_readyq(isc__taskmgr_t *manager, isc__task_t *task, int c) { + if (ISC_LINK_LINKED(task, ready_link)) { + return; + } ENQUEUE(manager->queues[c].ready_tasks, task, ready_link); - if ((task->flags & TASK_F_PRIVILEGED) != 0) { + if (TASK_PRIVILEGED(task)) { ENQUEUE(manager->queues[c].ready_priority_tasks, task, ready_priority_link); } @@ -1039,11 +1048,12 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { { XTHREADTRACE("wait"); XTHREADTRACE(atomic_load_relaxed(&manager->pause_req) - ? "paused" - : "notpaused"); - XTHREADTRACE(atomic_load_relaxed(&manager->exclusive_req) - ? "excreq" - : "notexcreq"); + ? "paused" + : "notpaused"); + XTHREADTRACE( + atomic_load_relaxed(&manager->exclusive_req) + ? "excreq" + : "notexcreq"); WAIT(&manager->queues[threadid].work_available, &manager->queues[threadid].lock); XTHREADTRACE("awake"); @@ -1051,7 +1061,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { XTHREADTRACE("working"); if (atomic_load_relaxed(&manager->pause_req) || - atomic_load_relaxed(&manager->exclusive_req)) { + atomic_load_relaxed(&manager->exclusive_req)) + { UNLOCK(&manager->queues[threadid].lock); XTHREADTRACE("halting"); @@ -1065,7 +1076,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { * bit. * * Broadcasting on halt_cond seems suboptimal, but - * exclusive tasks are rare enought that we don't + * exclusive tasks are rare enough that we don't * care. */ LOCK(&manager->halt_lock); @@ -1101,13 +1112,24 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { * lock before exiting the 'if (task != NULL)' block. */ UNLOCK(&manager->queues[threadid].lock); - RUNTIME_CHECK( - atomic_fetch_sub_explicit(&manager->tasks_ready, - 1, memory_order_release) > 0); + RUNTIME_CHECK(atomic_fetch_sub_explicit( + &manager->tasks_ready, 1, + memory_order_release) > 0); atomic_fetch_add_explicit(&manager->tasks_running, 1, memory_order_acquire); LOCK(&task->lock); + /* + * It is possible because that we have a paused task + * in the queue - it might have been paused in the + * meantime and we never hold both queue and task lock + * to avoid deadlocks, just bail then. + */ + if (task->state != task_state_ready) { + UNLOCK(&task->lock); + LOCK(&manager->queues[threadid].lock); + continue; + } INSIST(task->state == task_state_ready); task->state = task_state_running; XTRACE("running"); @@ -1132,12 +1154,15 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { event); LOCK(&task->lock); } + XTRACE("execution complete"); dispatch_count++; } - if (task->references == 0 && + if (isc_refcount_current(&task->references) == + 0 && EMPTY(task->events) && - !TASK_SHUTTINGDOWN(task)) { + !TASK_SHUTTINGDOWN(task)) + { bool was_idle; /* @@ -1172,7 +1197,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { * right now. */ XTRACE("empty"); - if (task->references == 0 && + if (isc_refcount_current( + &task->references) == 0 && TASK_SHUTTINGDOWN(task)) { /* * The task is done. @@ -1180,8 +1206,26 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { XTRACE("done"); finished = true; task->state = task_state_done; - } else - task->state = task_state_idle; + } else { + if (task->state == + task_state_running) { + task->state = + task_state_idle; + } else if (task->state == + task_state_pausing) { + task->state = + task_state_paused; + } + } + done = true; + } else if (task->state == task_state_pausing) { + /* + * We got a pause request on this task, + * stop working on it and switch the + * state to paused. + */ + XTRACE("pausing"); + task->state = task_state_paused; done = true; } else if (dispatch_count >= task->quantum) { /* @@ -1202,12 +1246,13 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { } while (!done); UNLOCK(&task->lock); - if (finished) + if (finished) { task_finished(task); + } - RUNTIME_CHECK( - atomic_fetch_sub_explicit(&manager->tasks_running, - 1, memory_order_release) > 0); + RUNTIME_CHECK(atomic_fetch_sub_explicit( + &manager->tasks_running, 1, + memory_order_release) > 0); LOCK(&manager->queues[threadid].lock); if (requeue) { /* @@ -1239,7 +1284,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { * we're stuck. Automatically drop privileges at that * point and continue with the regular ready queue. */ - if (manager->mode != isc_taskmgrmode_normal && + if (atomic_load_relaxed(&manager->mode) != + isc_taskmgrmode_normal && atomic_load_explicit(&manager->tasks_running, memory_order_acquire) == 0) { @@ -1252,7 +1298,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { * we'll end up in a deadlock over queue locks. * */ - if (manager->mode != isc_taskmgrmode_normal && + if (atomic_load(&manager->mode) != + isc_taskmgrmode_normal && atomic_load_explicit(&manager->tasks_running, memory_order_acquire) == 0) { @@ -1284,9 +1331,9 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) { static isc_threadresult_t #ifdef _WIN32 -WINAPI -#endif -run(void *queuep) { + WINAPI +#endif /* ifdef _WIN32 */ + run(void *queuep) { isc__taskqueue_t *tq = queuep; isc__taskmgr_t *manager = tq->manager; int threadid = tq->threadid; @@ -1300,7 +1347,7 @@ run(void *queuep) { #ifdef OPENSSL_LEAKS ERR_remove_state(0); -#endif +#endif /* ifdef OPENSSL_LEAKS */ return ((isc_threadresult_t)0); } @@ -1309,9 +1356,12 @@ static void manager_free(isc__taskmgr_t *manager) { for (unsigned int i = 0; i < manager->workers; i++) { isc_mutex_destroy(&manager->queues[i].lock); + isc_condition_destroy(&manager->queues[i].work_available); } isc_mutex_destroy(&manager->lock); + isc_mutex_destroy(&manager->excl_lock); isc_mutex_destroy(&manager->halt_lock); + isc_condition_destroy(&manager->halt_cond); isc_mem_put(manager->mctx, manager->queues, manager->workers * sizeof(isc__taskqueue_t)); manager->common.impmagic = 0; @@ -1321,8 +1371,8 @@ manager_free(isc__taskmgr_t *manager) { isc_result_t isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, - unsigned int default_quantum, isc_taskmgr_t **managerp) -{ + unsigned int default_quantum, isc_nm_t *nm, + isc_taskmgr_t **managerp) { unsigned int i; isc__taskmgr_t *manager; @@ -1334,11 +1384,10 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, REQUIRE(managerp != NULL && *managerp == NULL); manager = isc_mem_get(mctx, sizeof(*manager)); - RUNTIME_CHECK(manager != NULL); - manager->common.impmagic = TASK_MANAGER_MAGIC; - manager->common.magic = ISCAPI_TASKMGR_MAGIC; + *manager = (isc__taskmgr_t){ .common.impmagic = TASK_MANAGER_MAGIC, + .common.magic = ISCAPI_TASKMGR_MAGIC }; + atomic_store(&manager->mode, isc_taskmgrmode_normal); - manager->mctx = NULL; isc_mutex_init(&manager->lock); isc_mutex_init(&manager->excl_lock); @@ -1351,17 +1400,20 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, default_quantum = DEFAULT_DEFAULT_QUANTUM; } manager->default_quantum = default_quantum; + + if (nm != NULL) { + isc_nm_attach(nm, &manager->nm); + } + INIT_LIST(manager->tasks); atomic_store(&manager->tasks_count, 0); manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t)); RUNTIME_CHECK(manager->queues != NULL); - manager->tasks_running = 0; - manager->tasks_ready = 0; - manager->curq = 0; - manager->exiting = false; - manager->excl = NULL; - manager->halted = 0; + atomic_init(&manager->tasks_running, 0); + atomic_init(&manager->tasks_ready, 0); + atomic_init(&manager->curq, 0); + atomic_init(&manager->exiting, false); atomic_store_relaxed(&manager->exclusive_req, false); atomic_store_relaxed(&manager->pause_req, false); @@ -1379,9 +1431,8 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, manager->queues[i].manager = manager; manager->queues[i].threadid = i; - RUNTIME_CHECK(isc_thread_create(run, &manager->queues[i], - &manager->queues[i].thread) - == ISC_R_SUCCESS); + isc_thread_create(run, &manager->queues[i], + &manager->queues[i].thread); char name[21]; snprintf(name, sizeof(name), "isc-worker%04u", i); isc_thread_setname(manager->queues[i].thread, name); @@ -1423,8 +1474,9 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) { * Detach the exclusive task before acquiring the manager lock */ LOCK(&manager->excl_lock); - if (manager->excl != NULL) - isc_task_detach((isc_task_t **) &manager->excl); + if (manager->excl != NULL) { + isc_task_detach((isc_task_t **)&manager->excl); + } UNLOCK(&manager->excl_lock); /* @@ -1443,8 +1495,8 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) { */ exiting = false; - INSIST(!!atomic_compare_exchange_strong(&manager->exiting, - &exiting, true)); + INSIST(!!atomic_compare_exchange_strong(&manager->exiting, &exiting, + true)); /* * If privileged mode was on, turn it off. @@ -1456,9 +1508,8 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) { * posted). To make things easier post idle tasks to worker 0. */ LOCK(&manager->queues[0].lock); - for (task = HEAD(manager->tasks); - task != NULL; - task = NEXT(task, link)) { + for (task = HEAD(manager->tasks); task != NULL; task = NEXT(task, link)) + { LOCK(&task->lock); if (task_shutdown(task)) { task->threadid = 0; @@ -1479,8 +1530,16 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) { /* * Wait for all the worker threads to exit. */ - for (i = 0; i < manager->workers; i++) - (void)isc_thread_join(manager->queues[i].thread, NULL); + for (i = 0; i < manager->workers; i++) { + isc_thread_join(manager->queues[i].thread, NULL); + } + + /* + * Detach from the network manager if it was set. + */ + if (manager->nm != NULL) { + isc_nm_detach(&manager->nm); + } manager_free(manager); @@ -1506,7 +1565,8 @@ isc__taskmgr_pause(isc_taskmgr_t *manager0) { LOCK(&manager->halt_lock); while (atomic_load_relaxed(&manager->exclusive_req) || - atomic_load_relaxed(&manager->pause_req)) { + atomic_load_relaxed(&manager->pause_req)) + { UNLOCK(&manager->halt_lock); /* This is ugly but pause is used EXCLUSIVELY in tests */ isc_thread_yield(); @@ -1525,8 +1585,8 @@ void isc__taskmgr_resume(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; LOCK(&manager->halt_lock); - if (manager->pause_req) { - manager->pause_req = false; + if (atomic_load(&manager->pause_req)) { + atomic_store(&manager->pause_req, false); while (manager->halted > 0) { BROADCAST(&manager->halt_cond); WAIT(&manager->halt_cond, &manager->halt_lock); @@ -1537,31 +1597,33 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) { void isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) { - isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; - isc__task_t *task = (isc__task_t *) task0; + isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; + isc__task_t *task = (isc__task_t *)task0; REQUIRE(VALID_MANAGER(mgr)); REQUIRE(VALID_TASK(task)); LOCK(&mgr->excl_lock); - if (mgr->excl != NULL) - isc_task_detach((isc_task_t **) &mgr->excl); - isc_task_attach(task0, (isc_task_t **) &mgr->excl); + if (mgr->excl != NULL) { + isc_task_detach((isc_task_t **)&mgr->excl); + } + isc_task_attach(task0, (isc_task_t **)&mgr->excl); UNLOCK(&mgr->excl_lock); } isc_result_t isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) { - isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; + isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_MANAGER(mgr)); REQUIRE(taskp != NULL && *taskp == NULL); LOCK(&mgr->excl_lock); - if (mgr->excl != NULL) - isc_task_attach((isc_task_t *) mgr->excl, taskp); - else + if (mgr->excl != NULL) { + isc_task_attach((isc_task_t *)mgr->excl, taskp); + } else { result = ISC_R_NOTFOUND; + } UNLOCK(&mgr->excl_lock); return (result); @@ -1570,20 +1632,23 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) { isc_result_t isc_task_beginexclusive(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; - isc__taskmgr_t *manager = task->manager; + isc__taskmgr_t *manager; REQUIRE(VALID_TASK(task)); + manager = task->manager; + REQUIRE(task->state == task_state_running); LOCK(&manager->excl_lock); REQUIRE(task == task->manager->excl || (atomic_load_relaxed(&task->manager->exiting) && - task->manager->excl == NULL)); + task->manager->excl == NULL)); UNLOCK(&manager->excl_lock); if (atomic_load_relaxed(&manager->exclusive_req) || - atomic_load_relaxed(&manager->pause_req)) { + atomic_load_relaxed(&manager->pause_req)) + { return (ISC_R_LOCKBUSY); } @@ -1596,18 +1661,26 @@ isc_task_beginexclusive(isc_task_t *task0) { WAIT(&manager->halt_cond, &manager->halt_lock); } UNLOCK(&manager->halt_lock); + if (manager->nm != NULL) { + isc_nm_pause(manager->nm); + } return (ISC_R_SUCCESS); } void isc_task_endexclusive(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; - isc__taskmgr_t *manager = task->manager; + isc__taskmgr_t *manager; REQUIRE(VALID_TASK(task)); REQUIRE(task->state == task_state_running); + manager = task->manager; + + if (manager->nm != NULL) { + isc_nm_resume(manager->nm); + } LOCK(&manager->halt_lock); - REQUIRE(atomic_load_relaxed(&manager->exclusive_req) == true); + REQUIRE(atomic_load_relaxed(&manager->exclusive_req)); atomic_store_relaxed(&manager->exclusive_req, false); while (manager->halted > 0) { BROADCAST(&manager->halt_cond); @@ -1617,61 +1690,126 @@ isc_task_endexclusive(isc_task_t *task0) { } void -isc_task_setprivilege(isc_task_t *task0, bool priv) { +isc_task_pause(isc_task_t *task0) { REQUIRE(ISCAPI_TASK_VALID(task0)); isc__task_t *task = (isc__task_t *)task0; - isc__taskmgr_t *manager = task->manager; - bool oldpriv; LOCK(&task->lock); - oldpriv = ((task->flags & TASK_F_PRIVILEGED) != 0); - if (priv) - task->flags |= TASK_F_PRIVILEGED; - else - task->flags &= ~TASK_F_PRIVILEGED; + task->pause_cnt++; + if (task->pause_cnt > 1) { + /* + * Someone already paused this thread, just increase + * the number of pausing clients. + */ + UNLOCK(&task->lock); + return; + } + + INSIST(task->state == task_state_idle || + task->state == task_state_ready || + task->state == task_state_running); + if (task->state == task_state_running) { + task->state = task_state_pausing; + } else { + task->state = task_state_paused; + } UNLOCK(&task->lock); +} + +void +isc_task_unpause(isc_task_t *task0) { + isc__task_t *task = (isc__task_t *)task0; + bool was_idle = false; - if (priv == oldpriv) + REQUIRE(ISCAPI_TASK_VALID(task0)); + + LOCK(&task->lock); + task->pause_cnt--; + INSIST(task->pause_cnt >= 0); + if (task->pause_cnt > 0) { + UNLOCK(&task->lock); return; + } + + INSIST(task->state == task_state_paused || + task->state == task_state_pausing); + /* If the task was pausing we can't reschedule it */ + if (task->state == task_state_pausing) { + task->state = task_state_running; + } else { + task->state = task_state_idle; + } + if (task->state == task_state_idle && !EMPTY(task->events)) { + task->state = task_state_ready; + was_idle = true; + } + UNLOCK(&task->lock); + + if (was_idle) { + task_ready(task); + } +} + +void +isc_task_setprivilege(isc_task_t *task0, bool priv) { + REQUIRE(ISCAPI_TASK_VALID(task0)); + isc__task_t *task = (isc__task_t *)task0; + isc__taskmgr_t *manager = task->manager; + uint_fast32_t oldflags, newflags; + + oldflags = atomic_load_acquire(&task->flags); + do { + if (priv) { + newflags = oldflags | TASK_F_PRIVILEGED; + } else { + newflags = oldflags & ~TASK_F_PRIVILEGED; + } + if (newflags == oldflags) { + return; + } + } while (!atomic_compare_exchange_weak_acq_rel(&task->flags, &oldflags, + newflags)); LOCK(&manager->queues[task->threadid].lock); - if (priv && ISC_LINK_LINKED(task, ready_link)) + if (priv && ISC_LINK_LINKED(task, ready_link)) { ENQUEUE(manager->queues[task->threadid].ready_priority_tasks, task, ready_priority_link); - else if (!priv && ISC_LINK_LINKED(task, ready_priority_link)) + } else if (!priv && ISC_LINK_LINKED(task, ready_priority_link)) { DEQUEUE(manager->queues[task->threadid].ready_priority_tasks, task, ready_priority_link); + } UNLOCK(&manager->queues[task->threadid].lock); } bool isc_task_privilege(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; - bool priv; REQUIRE(VALID_TASK(task)); - LOCK(&task->lock); - priv = ((task->flags & TASK_F_PRIVILEGED) != 0); - UNLOCK(&task->lock); - return (priv); + return (TASK_PRIVILEGED(task)); } bool isc_task_exiting(isc_task_t *t) { isc__task_t *task = (isc__task_t *)t; - REQUIRE(VALID_TASK(task)); + return (TASK_SHUTTINGDOWN(task)); } - #ifdef HAVE_LIBXML2 -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +#define TRY0(a) \ + do { \ + xmlrc = (a); \ + if (xmlrc < 0) \ + goto error; \ + } while (0) int -isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { +isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, void *writer0) { isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc__task_t *task = NULL; int xmlrc; + xmlTextWriterPtr writer = (xmlTextWriterPtr)writer0; LOCK(&mgr->lock); @@ -1694,18 +1832,18 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-count")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - (int) atomic_load_relaxed(&mgr->tasks_count))); + TRY0(xmlTextWriterWriteFormatString( + writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_count))); TRY0(xmlTextWriterEndElement(writer)); /* tasks-count */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - (int) atomic_load_relaxed(&mgr->tasks_running))); + TRY0(xmlTextWriterWriteFormatString( + writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_running))); TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - (int) atomic_load_relaxed(&mgr->tasks_ready))); + TRY0(xmlTextWriterWriteFormatString( + writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_ready))); TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */ TRY0(xmlTextWriterEndElement(writer)); /* thread-model */ @@ -1720,14 +1858,15 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", - task->name)); + task->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "references")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - task->references)); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "reference" + "s")); + TRY0(xmlTextWriterWriteFormatString( + writer, "%" PRIuFAST32, + isc_refcount_current(&task->references))); TRY0(xmlTextWriterEndElement(writer)); /* references */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); @@ -1736,7 +1875,7 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", - statenames[task->state])); + statenames[task->state])); TRY0(xmlTextWriterEndElement(writer)); /* state */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum")); @@ -1756,29 +1895,32 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { } TRY0(xmlTextWriterEndElement(writer)); /* tasks */ - error: - if (task != NULL) +error: + if (task != NULL) { UNLOCK(&task->lock); + } UNLOCK(&mgr->lock); return (xmlrc); } #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) +#ifdef HAVE_JSON_C +#define CHECKMEM(m) \ + do { \ + if (m == NULL) { \ + result = ISC_R_NOMEMORY; \ + goto error; \ + } \ + } while (0) isc_result_t -isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) { +isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, void *tasks0) { isc_result_t result = ISC_R_SUCCESS; isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc__task_t *task = NULL; json_object *obj = NULL, *array = NULL, *taskobj = NULL; + json_object *tasks = (json_object *)tasks0; LOCK(&mgr->lock); @@ -1813,8 +1955,7 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) { array = json_object_new_array(); CHECKMEM(array); - for (task = ISC_LIST_HEAD(mgr->tasks); - task != NULL; + for (task = ISC_LIST_HEAD(mgr->tasks); task != NULL; task = ISC_LIST_NEXT(task, link)) { char buf[255]; @@ -1836,7 +1977,8 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) { json_object_object_add(taskobj, "name", obj); } - obj = json_object_new_int(task->references); + obj = json_object_new_int( + isc_refcount_current(&task->references)); CHECKMEM(obj); json_object_object_add(taskobj, "references", obj); @@ -1859,31 +2001,28 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) { array = NULL; result = ISC_R_SUCCESS; - error: - if (array != NULL) +error: + if (array != NULL) { json_object_put(array); + } - if (task != NULL) + if (task != NULL) { UNLOCK(&task->lock); + } UNLOCK(&mgr->lock); return (result); } -#endif - +#endif /* ifdef HAVE_JSON_C */ isc_result_t -isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - unsigned int workers, unsigned int default_quantum, - isc_taskmgr_t **managerp) -{ +isc_taskmgr_createinctx(isc_mem_t *mctx, unsigned int workers, + unsigned int default_quantum, + isc_taskmgr_t **managerp) { isc_result_t result; - result = isc_taskmgr_create(mctx, workers, default_quantum, - managerp); - - if (result == ISC_R_SUCCESS) - isc_appctx_settaskmgr(actx, *managerp); + result = isc_taskmgr_create(mctx, workers, default_quantum, NULL, + managerp); return (result); } diff --git a/lib/isc/task_p.h b/lib/isc/task_p.h index b3da61f4..ae8f0957 100644 --- a/lib/isc/task_p.h +++ b/lib/isc/task_p.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -23,5 +23,4 @@ isc__taskmgr_pause(isc_taskmgr_t *taskmgr); void isc__taskmgr_resume(isc_taskmgr_t *taskmgr); - #endif /* ISC_TASK_P_H */ diff --git a/lib/isc/taskpool.c b/lib/isc/taskpool.c index d227ec1f..ca794c8a 100644 --- a/lib/isc/taskpool.c +++ b/lib/isc/taskpool.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdbool.h> #include <isc/mem.h> @@ -26,27 +23,24 @@ ***/ struct isc_taskpool { - isc_mem_t * mctx; - isc_taskmgr_t * tmgr; - unsigned int ntasks; - unsigned int quantum; - isc_task_t ** tasks; + isc_mem_t *mctx; + isc_taskmgr_t *tmgr; + unsigned int ntasks; + unsigned int quantum; + isc_task_t **tasks; }; /*** *** Functions. ***/ -static isc_result_t +static void alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, - unsigned int quantum, isc_taskpool_t **poolp) -{ + unsigned int quantum, isc_taskpool_t **poolp) { isc_taskpool_t *pool; unsigned int i; pool = isc_mem_get(mctx, sizeof(*pool)); - if (pool == NULL) - return (ISC_R_NOMEMORY); pool->mctx = NULL; isc_mem_attach(mctx, &pool->mctx); @@ -54,22 +48,16 @@ alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, pool->quantum = quantum; pool->tmgr = tmgr; pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); - if (pool->tasks == NULL) { - isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); - return (ISC_R_NOMEMORY); - } - for (i = 0; i < ntasks; i++) + for (i = 0; i < ntasks; i++) { pool->tasks[i] = NULL; + } *poolp = pool; - return (ISC_R_SUCCESS); } isc_result_t -isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, - unsigned int ntasks, unsigned int quantum, - isc_taskpool_t **poolp) -{ +isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, + unsigned int quantum, isc_taskpool_t **poolp) { unsigned int i; isc_taskpool_t *pool = NULL; isc_result_t result; @@ -77,9 +65,7 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, INSIST(ntasks > 0); /* Allocate the pool structure */ - result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool); - if (result != ISC_R_SUCCESS) - return (result); + alloc_pool(tmgr, mctx, ntasks, quantum, &pool); /* Create the tasks */ for (i = 0; i < ntasks; i++) { @@ -108,8 +94,7 @@ isc_taskpool_size(isc_taskpool_t *pool) { isc_result_t isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, - isc_taskpool_t **targetp) -{ + isc_taskpool_t **targetp) { isc_result_t result; isc_taskpool_t *pool; @@ -117,15 +102,14 @@ isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, REQUIRE(targetp != NULL && *targetp == NULL); pool = *sourcep; + *sourcep = NULL; if (size > pool->ntasks) { isc_taskpool_t *newpool = NULL; unsigned int i; /* Allocate a new pool structure */ - result = alloc_pool(pool->tmgr, pool->mctx, size, - pool->quantum, &newpool); - if (result != ISC_R_SUCCESS) - return (result); + alloc_pool(pool->tmgr, pool->mctx, size, pool->quantum, + &newpool); /* Copy over the tasks from the old pool */ for (i = 0; i < pool->ntasks; i++) { @@ -138,6 +122,7 @@ isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, result = isc_task_create(pool->tmgr, pool->quantum, &newpool->tasks[i]); if (result != ISC_R_SUCCESS) { + *sourcep = pool; isc_taskpool_destroy(&newpool); return (result); } @@ -148,7 +133,6 @@ isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, pool = newpool; } - *sourcep = NULL; *targetp = pool; return (ISC_R_SUCCESS); } @@ -157,14 +141,15 @@ void isc_taskpool_destroy(isc_taskpool_t **poolp) { unsigned int i; isc_taskpool_t *pool = *poolp; + *poolp = NULL; for (i = 0; i < pool->ntasks; i++) { - if (pool->tasks[i] != NULL) + if (pool->tasks[i] != NULL) { isc_task_detach(&pool->tasks[i]); + } } isc_mem_put(pool->mctx, pool->tasks, pool->ntasks * sizeof(isc_task_t *)); isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); - *poolp = NULL; } void @@ -174,7 +159,8 @@ isc_taskpool_setprivilege(isc_taskpool_t *pool, bool priv) { REQUIRE(pool != NULL); for (i = 0; i < pool->ntasks; i++) { - if (pool->tasks[i] != NULL) + if (pool->tasks[i] != NULL) { isc_task_setprivilege(pool->tasks[i], priv); + } } } diff --git a/lib/isc/tests/Kyuafile b/lib/isc/tests/Kyuafile index e2b2498b..d07b11f5 100644 --- a/lib/isc/tests/Kyuafile +++ b/lib/isc/tests/Kyuafile @@ -16,11 +16,12 @@ tap_test_program{name='mem_test'} tap_test_program{name='netaddr_test'} tap_test_program{name='parse_test'} tap_test_program{name='pool_test'} -tap_test_program{name='queue_test'} tap_test_program{name='radix_test'} +tap_test_program{name='quota_test'} tap_test_program{name='regex_test'} tap_test_program{name='result_test'} tap_test_program{name='safe_test'} +tap_test_program{name='siphash_test'} tap_test_program{name='sockaddr_test'} tap_test_program{name='socket_test'} tap_test_program{name='symtab_test'} diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in index 57358297..c22bed08 100644 --- a/lib/isc/tests/Makefile.in +++ b/lib/isc/tests/Makefile.in @@ -15,10 +15,13 @@ VERSION=@BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ -CINCLUDES = -I. -Iinclude ${ISC_INCLUDES} @OPENSSL_INCLUDES@ @CMOCKA_CFLAGS@ +CINCLUDES = -I. -Iinclude ${ISC_INCLUDES} \ + ${OPENSSL_CFLAGS} @CMOCKA_CFLAGS@ \ + ${JSON_C_CFLAGS} \ + ${LIBXML2_CFLAGS} CDEFINES = -DTESTS="\"${top_builddir}/lib/isc/tests/\"" -ISCLIBS = ../libisc.@A@ @OPENSSL_LIBS@ +ISCLIBS = ../libisc.@A@ @NO_LIBTOOL_ISCLIBS@ ISCDEPLIBS = ../libisc.@A@ LIBS = @LIBS@ @CMOCKA_LIBS@ @@ -29,8 +32,8 @@ SRCS = isctest.c aes_test.c buffer_test.c \ counter_test.c crc64_test.c errno_test.c file_test.c hash_test.c \ heap_test.c hmac_test.c ht_test.c lex_test.c \ mem_test.c md_test.c netaddr_test.c parse_test.c pool_test.c \ - queue_test.c radix_test.c random_test.c \ - regex_test.c result_test.c safe_test.c sockaddr_test.c \ + quota_test.c radix_test.c random_test.c \ + regex_test.c result_test.c safe_test.c siphash_test.c sockaddr_test.c \ socket_test.c socket_test.c symtab_test.c task_test.c \ taskpool_test.c time_test.c timer_test.c @@ -42,9 +45,9 @@ TARGETS = aes_test@EXEEXT@ buffer_test@EXEEXT@ \ ht_test@EXEEXT@ \ lex_test@EXEEXT@ mem_test@EXEEXT@ md_test@EXEEXT@ \ netaddr_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \ - queue_test@EXEEXT@ radix_test@EXEEXT@ \ + quota_test@EXEEXT@ radix_test@EXEEXT@ \ random_test@EXEEXT@ regex_test@EXEEXT@ result_test@EXEEXT@ \ - safe_test@EXEEXT@ sockaddr_test@EXEEXT@ socket_test@EXEEXT@ \ + safe_test@EXEEXT@ siphash_test@EXEEXT@ sockaddr_test@EXEEXT@ socket_test@EXEEXT@ \ socket_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \ taskpool_test@EXEEXT@ time_test@EXEEXT@ timer_test@EXEEXT@ @@ -85,30 +88,30 @@ hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS} ${LDFLAGS} -o $@ hash_test.@O@ \ ${ISCLIBS} ${LIBS} -heap_test@EXEEXT@: heap_test.@O@ ${ISCDEPLIBS} +heap_test@EXEEXT@: heap_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ heap_test.@O@ \ + ${LDFLAGS} -o $@ heap_test.@O@ isctest.@O@ \ ${ISCLIBS} ${LIBS} hmac_test@EXEEXT@: hmac_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ ${LDFLAGS} -o $@ hmac_test.@O@ \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${OPENSSL_LIBS} ${LIBS} -ht_test@EXEEXT@: ht_test.@O@ ${ISCDEPLIBS} +ht_test@EXEEXT@: ht_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ ht_test.@O@ \ + ${LDFLAGS} -o $@ ht_test.@O@ isctest.@O@ \ ${ISCLIBS} ${LIBS} -lex_test@EXEEXT@: lex_test.@O@ ${ISCDEPLIBS} +lex_test@EXEEXT@: lex_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ lex_test.@O@ \ + ${LDFLAGS} -o $@ lex_test.@O@ isctest.@O@ \ ${ISCLIBS} ${LIBS} md_test@EXEEXT@: md_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ ${LDFLAGS} -o $@ md_test.@O@ \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${OPENSSL_LIBS} ${LIBS} mem_test@EXEEXT@: mem_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ @@ -130,9 +133,9 @@ pool_test@EXEEXT@: pool_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LDFLAGS} -o $@ pool_test.@O@ isctest.@O@ \ ${ISCLIBS} ${LIBS} -queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS} +quota_test@EXEEXT@: quota_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ queue_test.@O@ isctest.@O@ \ + ${LDFLAGS} -o $@ quota_test.@O@ isctest.@O@ \ ${ISCLIBS} ${LIBS} radix_test@EXEEXT@: radix_test.@O@ isctest.@O@ ${ISCDEPLIBS} @@ -160,6 +163,11 @@ safe_test@EXEEXT@: safe_test.@O@ ${ISCDEPLIBS} ${LDFLAGS} -o $@ safe_test.@O@ \ ${ISCLIBS} ${LIBS} +siphash_test@EXEEXT@: siphash_test.@O@ ../siphash.c ${ISCDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ + ${LDFLAGS} -o $@ siphash_test.@O@ \ + ${ISCLIBS} ${LIBS} + socket_test@EXEEXT@: socket_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ ${LDFLAGS} -o $@ socket_test.@O@ isctest.@O@ \ diff --git a/lib/isc/tests/aes_test.c b/lib/isc/tests/aes_test.c index c5481d4e..b808cd45 100644 --- a/lib/isc/tests/aes_test.c +++ b/lib/isc/tests/aes_test.c @@ -3,22 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA #include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <stdlib.h> - #include <stdio.h> +#include <stdlib.h> #include <string.h> #define UNIT_TESTING @@ -69,7 +66,7 @@ fromhexstr(const char *in, unsigned char *d) { if (ret != ISC_R_SUCCESS) { return (0); } - return isc_buffer_usedlength(&b); + return (isc_buffer_usedlength(&b)); } typedef struct aes_testcase { @@ -81,44 +78,31 @@ typedef struct aes_testcase { /* AES 128 test vectors */ static void isc_aes128_test(void **state) { - aes_testcase_t testcases[] = { - /* Test 1 (KAT ECBVarTxt128 #3) */ - { - "00000000000000000000000000000000", - "F0000000000000000000000000000000", - "96D9FD5CC4F07441727DF0F33E401A36" - }, - /* Test 2 (KAT ECBVarTxt128 #123) */ - { - "00000000000000000000000000000000", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "F9B0FDA0C4A898F5B9E6F661C4CE4D07" - }, - /* Test 3 (KAT ECBVarKey128 #3) */ - { - "F0000000000000000000000000000000", - "00000000000000000000000000000000", - "970014D634E2B7650777E8E84D03CCD8" - }, - /* Test 4 (KAT ECBVarKey128 #123) */ - { - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "00000000000000000000000000000000", - "41C78C135ED9E98C096640647265DA1E" - }, - /* Test 5 (KAT ECBGFSbox128 #3) */ - { - "00000000000000000000000000000000", - "6A118A874519E64E9963798A503F1D35", - "DC43BE40BE0E53712F7E2BF5CA707209" - }, - /* Test 6 (KAT ECBKeySbox128 #3) */ - { - "B6364AC4E1DE1E285EAF144A2415F7A0", - "00000000000000000000000000000000", - "5D9B05578FC944B3CF1CCF0E746CD581" - }, - { NULL, NULL, NULL } + aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt128 #3) */ + { "00000000000000000000000000000000", + "F0000000000000000000000000000000", + "96D9FD5CC4F07441727DF0F33E401A36" }, + /* Test 2 (KAT ECBVarTxt128 #123) */ + { "00000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "F9B0FDA0C4A898F5B9E6F661C4CE4D07" }, + /* Test 3 (KAT ECBVarKey128 #3) */ + { "F0000000000000000000000000000000", + "00000000000000000000000000000000", + "970014D634E2B7650777E8E84D03CCD8" }, + /* Test 4 (KAT ECBVarKey128 #123) */ + { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "00000000000000000000000000000000", + "41C78C135ED9E98C096640647265DA1E" }, + /* Test 5 (KAT ECBGFSbox128 #3) */ + { "00000000000000000000000000000000", + "6A118A874519E64E9963798A503F1D35", + "DC43BE40BE0E53712F7E2BF5CA707209" }, + /* Test 6 (KAT ECBKeySbox128 #3) */ + { "B6364AC4E1DE1E285EAF144A2415F7A0", + "00000000000000000000000000000000", + "5D9B05578FC944B3CF1CCF0E746CD581" }, + { NULL, NULL, NULL } }; aes_testcase_t *testcase = testcases; @@ -143,41 +127,29 @@ static void isc_aes192_test(void **state) { aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt192 #3) */ - { - "000000000000000000000000000000000000000000000000", - "F0000000000000000000000000000000", - "2A560364CE529EFC21788779568D5555" - }, + { "000000000000000000000000000000000000000000000000", + "F0000000000000000000000000000000", + "2A560364CE529EFC21788779568D5555" }, /* Test 2 (KAT ECBVarTxt192 #123) */ - { - "000000000000000000000000000000000000000000000000", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "2AABB999F43693175AF65C6C612C46FB" - }, + { "000000000000000000000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "2AABB999F43693175AF65C6C612C46FB" }, /* Test 3 (KAT ECBVarKey192 #3) */ - { - "F00000000000000000000000000000000000000000000000", - "00000000000000000000000000000000", - "180B09F267C45145DB2F826C2582D35C" - }, + { "F00000000000000000000000000000000000000000000000", + "00000000000000000000000000000000", + "180B09F267C45145DB2F826C2582D35C" }, /* Test 4 (KAT ECBVarKey192 #187) */ - { - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "00000000000000000000000000000000", - "EACF1E6C4224EFB38900B185AB1DFD42" - }, + { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "00000000000000000000000000000000", + "EACF1E6C4224EFB38900B185AB1DFD42" }, /* Test 5 (KAT ECBGFSbox192 #3) */ - { - "000000000000000000000000000000000000000000000000", - "51719783D3185A535BD75ADC65071CE1", - "4F354592FF7C8847D2D0870CA9481B7C" - }, + { "000000000000000000000000000000000000000000000000", + "51719783D3185A535BD75ADC65071CE1", + "4F354592FF7C8847D2D0870CA9481B7C" }, /* Test 6 (KAT ECBKeySbox192 #3) */ - { - "CD62376D5EBB414917F0C78F05266433DC9192A1EC943300", - "00000000000000000000000000000000", - "7F6C25FF41858561BB62F36492E93C29" - }, + { "CD62376D5EBB414917F0C78F05266433DC9192A1EC943300", + "00000000000000000000000000000000", + "7F6C25FF41858561BB62F36492E93C29" }, { NULL, NULL, NULL } }; @@ -201,50 +173,37 @@ isc_aes192_test(void **state) { /* AES 256 test vectors */ static void isc_aes256_test(void **state) { - aes_testcase_t testcases[] = { - /* Test 1 (KAT ECBVarTxt256 #3) */ - { - "00000000000000000000000000000000" - "00000000000000000000000000000000", - "F0000000000000000000000000000000", - "7F2C5ECE07A98D8BEE13C51177395FF7" - }, - /* Test 2 (KAT ECBVarTxt256 #123) */ - { - "00000000000000000000000000000000" - "00000000000000000000000000000000", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "7240E524BC51D8C4D440B1BE55D1062C" - }, - /* Test 3 (KAT ECBVarKey256 #3) */ - { - "F0000000000000000000000000000000" - "00000000000000000000000000000000", - "00000000000000000000000000000000", - "1C777679D50037C79491A94DA76A9A35" - }, - /* Test 4 (KAT ECBVarKey256 #251) */ - { - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", - "00000000000000000000000000000000", - "03720371A04962EAEA0A852E69972858" - }, - /* Test 5 (KAT ECBGFSbox256 #3) */ - { - "00000000000000000000000000000000" - "00000000000000000000000000000000", - "8A560769D605868AD80D819BDBA03771", - "38F2C7AE10612415D27CA190D27DA8B4" - }, - /* Test 6 (KAT ECBKeySbox256 #3) */ - { - "984CA75F4EE8D706F46C2D98C0BF4A45" - "F5B00D791C2DFEB191B5ED8E420FD627", - "00000000000000000000000000000000", - "4307456A9E67813B452E15FA8FFFE398" - }, - { NULL, NULL, NULL } + aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt256 #3) */ + { "00000000000000000000000000000000" + "00000000000000000000000000000000", + "F0000000000000000000000000000000", + "7F2C5ECE07A98D8BEE13C51177395FF7" }, + /* Test 2 (KAT ECBVarTxt256 #123) */ + { "00000000000000000000000000000000" + "00000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "7240E524BC51D8C4D440B1BE55D1062C" }, + /* Test 3 (KAT ECBVarKey256 #3) */ + { "F0000000000000000000000000000000" + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "1C777679D50037C79491A94DA76A9A35" }, + /* Test 4 (KAT ECBVarKey256 #251) */ + { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "00000000000000000000000000000000", + "03720371A04962EAEA0A852E69972858" }, + /* Test 5 (KAT ECBGFSbox256 #3) */ + { "00000000000000000000000000000000" + "00000000000000000000000000000000", + "8A560769D605868AD80D819BDBA03771", + "38F2C7AE10612415D27CA190D27DA8B4" }, + /* Test 6 (KAT ECBKeySbox256 #3) */ + { "984CA75F4EE8D706F46C2D98C0BF4A45" + "F5B00D791C2DFEB191B5ED8E420FD627", + "00000000000000000000000000000000", + "4307456A9E67813B452E15FA8FFFE398" }, + { NULL, NULL, NULL } }; aes_testcase_t *testcase = testcases; @@ -285,4 +244,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/buffer_test.c b/lib/isc/tests/buffer_test.c index 8cbb747e..228b0893 100644 --- a/lib/isc/tests/buffer_test.c +++ b/lib/isc/tests/buffer_test.c @@ -3,23 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> -#include <setjmp.h> - #include <fcntl.h> #include <limits.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> +#include <stdarg.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -66,8 +64,7 @@ isc_buffer_reserve_test(void **state) { UNUSED(state); b = NULL; - result = isc_buffer_allocate(mctx, &b, 1024); - assert_int_equal(result, ISC_R_SUCCESS); + isc_buffer_allocate(test_mctx, &b, 1024); assert_int_equal(b->length, 1024); /* @@ -128,7 +125,6 @@ isc_buffer_reserve_test(void **state) { /* dynamic buffer automatic reallocation */ static void isc_buffer_dynamic_test(void **state) { - isc_result_t result; isc_buffer_t *b; size_t last_length = 10; int i; @@ -136,8 +132,7 @@ isc_buffer_dynamic_test(void **state) { UNUSED(state); b = NULL; - result = isc_buffer_allocate(mctx, &b, last_length); - assert_int_equal(result, ISC_R_SUCCESS); + isc_buffer_allocate(test_mctx, &b, last_length); assert_non_null(b); assert_int_equal(b->length, last_length); @@ -148,35 +143,34 @@ isc_buffer_dynamic_test(void **state) { for (i = 0; i < 1000; i++) { isc_buffer_putstr(b, "thisisa24charslongstring"); } - assert_true(b->length-last_length >= 1000*24); - last_length+=1000*24; + assert_true(b->length - last_length >= 1000 * 24); + last_length += 1000 * 24; for (i = 0; i < 10000; i++) { isc_buffer_putuint8(b, 1); } - assert_true(b->length-last_length >= 10000*1); - last_length += 10000*1; + assert_true(b->length - last_length >= 10000 * 1); + last_length += 10000 * 1; for (i = 0; i < 10000; i++) { isc_buffer_putuint16(b, 1); } - assert_true(b->length-last_length >= 10000*2); + assert_true(b->length - last_length >= 10000 * 2); - last_length += 10000*2; + last_length += 10000 * 2; for (i = 0; i < 10000; i++) { isc_buffer_putuint24(b, 1); } - assert_true(b->length-last_length >= 10000*3); + assert_true(b->length - last_length >= 10000 * 3); - last_length+=10000*3; + last_length += 10000 * 3; for (i = 0; i < 10000; i++) { isc_buffer_putuint32(b, 1); } - assert_true(b->length-last_length >= 10000*4); - + assert_true(b->length - last_length >= 10000 * 4); isc_buffer_free(&b); } @@ -195,8 +189,7 @@ isc_buffer_copyregion_test(void **state) { UNUSED(state); - result = isc_buffer_allocate(mctx, &b, sizeof(data)); - assert_int_equal(result, ISC_R_SUCCESS); + isc_buffer_allocate(test_mctx, &b, sizeof(data)); /* * Fill originally allocated buffer space. @@ -235,8 +228,7 @@ isc_buffer_printf_test(void **state) { * Prepare a buffer with auto-reallocation enabled. */ b = NULL; - result = isc_buffer_allocate(mctx, &b, 0); - assert_int_equal(result, ISC_R_SUCCESS); + isc_buffer_allocate(test_mctx, &b, 0); isc_buffer_setautorealloc(b, true); /* @@ -331,14 +323,14 @@ isc_buffer_printf_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_buffer_reserve_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_buffer_dynamic_test, - _setup, _teardown), + cmocka_unit_test_setup_teardown(isc_buffer_reserve_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(isc_buffer_dynamic_test, _setup, + _teardown), cmocka_unit_test_setup_teardown(isc_buffer_copyregion_test, _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_buffer_printf_test, - _setup, _teardown), + cmocka_unit_test_setup_teardown(isc_buffer_printf_test, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -354,4 +346,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/counter_test.c b/lib/isc/tests/counter_test.c index 28c1fbb3..9642059e 100644 --- a/lib/isc/tests/counter_test.c +++ b/lib/isc/tests/counter_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> @@ -59,7 +57,7 @@ isc_counter_test(void **state) { UNUSED(state); - result = isc_counter_create(mctx, 0, &counter); + result = isc_counter_create(test_mctx, 0, &counter); assert_int_equal(result, ISC_R_SUCCESS); for (i = 0; i < 10; i++) { @@ -85,8 +83,8 @@ isc_counter_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_counter_test, - _setup, _teardown), + cmocka_unit_test_setup_teardown(isc_counter_test, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -102,4 +100,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/crc64_test.c b/lib/isc/tests/crc64_test.c index 187dcaff..8fd22aca 100644 --- a/lib/isc/tests/crc64_test.c +++ b/lib/isc/tests/crc64_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,26 +11,23 @@ /* ! \file */ -#include <config.h> - #if HAVE_CMOCKA +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> #include <stdlib.h> - #include <string.h> #define UNIT_TESTING #include <cmocka.h> #include <isc/crc64.h> +#include <isc/print.h> #include <isc/result.h> #include <isc/util.h> -#include <isc/print.h> -#define TEST_INPUT(x) (x), sizeof(x)-1 +#define TEST_INPUT(x) (x), sizeof(x) - 1 typedef struct hash_testcase { const char *input; @@ -50,9 +47,7 @@ isc_crc64_init_test(void **state) { } static void -_crc64(const char *buf, size_t buflen, - const char *result, const int repeats) -{ +_crc64(const char *buf, size_t buflen, const char *result, const int repeats) { uint64_t crc; isc_crc64_init(&crc); @@ -67,7 +62,7 @@ _crc64(const char *buf, size_t buflen, char hex[16 + 1]; snprintf(hex, sizeof(hex), "%016" PRIX64, crc); - assert_memory_equal(hex, result, (result?strlen(result):0)); + assert_memory_equal(hex, result, (result ? strlen(result) : 0)); } /* 64-bit cyclic redundancy check */ @@ -79,8 +74,7 @@ isc_crc64_test(void **state) { _crc64(TEST_INPUT("a"), "CE73F427ACC0A99A", 1); _crc64(TEST_INPUT("abc"), "048B813AF9F49702", 1); _crc64(TEST_INPUT("message digest"), "5273F9EA7A357BF4", 1); - _crc64(TEST_INPUT("abcdefghijklmnopqrstuvwxyz"), - "59F079F9218BAAA1", 1); + _crc64(TEST_INPUT("abcdefghijklmnopqrstuvwxyz"), "59F079F9218BAAA1", 1); _crc64(TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm" "nopqrstuvwxyz0123456789"), "A36DA8F71E78B6FB", 1); @@ -109,4 +103,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/errno_test.c b/lib/isc/tests/errno_test.c index 42a15d8c..4d66d9ef 100644 --- a/lib/isc/tests/errno_test.c +++ b/lib/isc/tests/errno_test.c @@ -3,23 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <errno.h> #include <setjmp.h> #include <stdarg.h> #include <stddef.h> #include <stdlib.h> - #include <string.h> -#include <sys/errno.h> #define UNIT_TESTING #include <cmocka.h> @@ -33,61 +30,59 @@ typedef struct { isc_result_t result; } testpair_t; -testpair_t testpair[] = { - { EPERM, ISC_R_NOPERM }, - { ENOENT, ISC_R_FILENOTFOUND }, - { EIO, ISC_R_IOERROR }, - { EBADF, ISC_R_INVALIDFILE }, - { ENOMEM, ISC_R_NOMEMORY }, - { EACCES, ISC_R_NOPERM }, - { EEXIST, ISC_R_FILEEXISTS }, - { ENOTDIR, ISC_R_INVALIDFILE }, - { EINVAL, ISC_R_INVALIDFILE }, - { ENFILE, ISC_R_TOOMANYOPENFILES }, - { EMFILE, ISC_R_TOOMANYOPENFILES }, - { EPIPE, ISC_R_CONNECTIONRESET }, - { ENAMETOOLONG, ISC_R_INVALIDFILE }, - { ELOOP, ISC_R_INVALIDFILE }, +testpair_t testpair[] = { { EPERM, ISC_R_NOPERM }, + { ENOENT, ISC_R_FILENOTFOUND }, + { EIO, ISC_R_IOERROR }, + { EBADF, ISC_R_INVALIDFILE }, + { ENOMEM, ISC_R_NOMEMORY }, + { EACCES, ISC_R_NOPERM }, + { EEXIST, ISC_R_FILEEXISTS }, + { ENOTDIR, ISC_R_INVALIDFILE }, + { EINVAL, ISC_R_INVALIDFILE }, + { ENFILE, ISC_R_TOOMANYOPENFILES }, + { EMFILE, ISC_R_TOOMANYOPENFILES }, + { EPIPE, ISC_R_CONNECTIONRESET }, + { ENAMETOOLONG, ISC_R_INVALIDFILE }, + { ELOOP, ISC_R_INVALIDFILE }, #ifdef EOVERFLOW - { EOVERFLOW, ISC_R_RANGE }, -#endif + { EOVERFLOW, ISC_R_RANGE }, +#endif /* ifdef EOVERFLOW */ #ifdef EAFNOSUPPORT - { EAFNOSUPPORT, ISC_R_FAMILYNOSUPPORT }, -#endif + { EAFNOSUPPORT, ISC_R_FAMILYNOSUPPORT }, +#endif /* ifdef EAFNOSUPPORT */ #ifdef EADDRINUSE - { EADDRINUSE, ISC_R_ADDRINUSE }, -#endif - { EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL }, + { EADDRINUSE, ISC_R_ADDRINUSE }, +#endif /* ifdef EADDRINUSE */ + { EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL }, #ifdef ENETDOWN - { ENETDOWN, ISC_R_NETDOWN }, -#endif + { ENETDOWN, ISC_R_NETDOWN }, +#endif /* ifdef ENETDOWN */ #ifdef ENETUNREACH - { ENETUNREACH, ISC_R_NETUNREACH }, -#endif + { ENETUNREACH, ISC_R_NETUNREACH }, +#endif /* ifdef ENETUNREACH */ #ifdef ECONNABORTED - { ECONNABORTED, ISC_R_CONNECTIONRESET }, -#endif + { ECONNABORTED, ISC_R_CONNECTIONRESET }, +#endif /* ifdef ECONNABORTED */ #ifdef ECONNRESET - { ECONNRESET, ISC_R_CONNECTIONRESET }, -#endif + { ECONNRESET, ISC_R_CONNECTIONRESET }, +#endif /* ifdef ECONNRESET */ #ifdef ENOBUFS - { ENOBUFS, ISC_R_NORESOURCES }, -#endif + { ENOBUFS, ISC_R_NORESOURCES }, +#endif /* ifdef ENOBUFS */ #ifdef ENOTCONN - { ENOTCONN, ISC_R_NOTCONNECTED }, -#endif + { ENOTCONN, ISC_R_NOTCONNECTED }, +#endif /* ifdef ENOTCONN */ #ifdef ETIMEDOUT - { ETIMEDOUT, ISC_R_TIMEDOUT }, -#endif - { ECONNREFUSED, ISC_R_CONNREFUSED }, + { ETIMEDOUT, ISC_R_TIMEDOUT }, +#endif /* ifdef ETIMEDOUT */ + { ECONNREFUSED, ISC_R_CONNREFUSED }, #ifdef EHOSTDOWN - { EHOSTDOWN, ISC_R_HOSTDOWN }, -#endif + { EHOSTDOWN, ISC_R_HOSTDOWN }, +#endif /* ifdef EHOSTDOWN */ #ifdef EHOSTUNREACH - { EHOSTUNREACH, ISC_R_HOSTUNREACH }, -#endif - { 0, ISC_R_UNEXPECTED } -}; + { EHOSTUNREACH, ISC_R_HOSTUNREACH }, +#endif /* ifdef EHOSTUNREACH */ + { 0, ISC_R_UNEXPECTED } }; /* convert errno to ISC result */ static void @@ -97,7 +92,7 @@ isc_errno_toresult_test(void **state) { UNUSED(state); - for (i = 0; i < sizeof(testpair)/sizeof(testpair[0]); i++) { + for (i = 0; i < sizeof(testpair) / sizeof(testpair[0]); i++) { result = isc_errno_toresult(testpair[i].err); expect = testpair[i].result; assert_int_equal(result, expect); @@ -123,4 +118,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/file_test.c b/lib/isc/tests/file_test.c index 86bc1ea7..2fa2a230 100644 --- a/lib/isc/tests/file_test.c +++ b/lib/isc/tests/file_test.c @@ -3,21 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <fcntl.h> +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - -#include <fcntl.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -29,14 +26,14 @@ #include <isc/result.h> #include <isc/util.h> -#define NAME "internal" -#define SHA "3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f" +#define NAME "internal" +#define SHA "3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f" #define TRUNC_SHA "3bed2cb3a3acf7b6" -#define BAD1 "in/internal" +#define BAD1 "in/internal" #define BADHASH1 "8bbb97a888791399" -#define BAD2 "Internal" +#define BAD2 "Internal" #define BADHASH2 "2ea1842b445b0c81" #define F(x) "testdata/file/" x ".test" @@ -98,18 +95,18 @@ isc_file_template_test(void **state) { assert_return_code(chdir(TESTS), 0); - result = isc_file_template("/absolute/path", "file-XXXXXXXX", - buf, sizeof(buf)); + result = isc_file_template("/absolute/path", "file-XXXXXXXX", buf, + sizeof(buf)); assert_int_equal(result, ISC_R_SUCCESS); assert_string_equal(buf, "/absolute/file-XXXXXXXX"); - result = isc_file_template("relative/path", "file-XXXXXXXX", - buf, sizeof(buf)); + result = isc_file_template("relative/path", "file-XXXXXXXX", buf, + sizeof(buf)); assert_int_equal(result, ISC_R_SUCCESS); assert_string_equal(buf, "relative/file-XXXXXXXX"); - result = isc_file_template("/trailing/slash/", "file-XXXXXXXX", - buf, sizeof(buf)); + result = isc_file_template("/trailing/slash/", "file-XXXXXXXX", buf, + sizeof(buf)); assert_int_equal(result, ISC_R_SUCCESS); assert_string_equal(buf, "/trailing/slash/file-XXXXXXXX"); @@ -122,8 +119,8 @@ isc_file_template_test(void **state) { assert_int_equal(result, ISC_R_SUCCESS); assert_string_equal(buf, "/file-XXXXXXXX"); - result = isc_file_template("noslash", "file-XXXXXXXX", - buf, sizeof(buf)); + result = isc_file_template("noslash", "file-XXXXXXXX", buf, + sizeof(buf)); assert_int_equal(result, ISC_R_SUCCESS); assert_string_equal(buf, "file-XXXXXXXX"); @@ -152,4 +149,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/hash_test.c b/lib/isc/tests/hash_test.c index 22bb6e47..3444f9f0 100644 --- a/lib/isc/tests/hash_test.c +++ b/lib/isc/tests/hash_test.c @@ -3,24 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <inttypes.h> +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - -#include <inttypes.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #define UNIT_TESTING @@ -29,22 +26,14 @@ #include <isc/buffer.h> #include <isc/hash.h> #include <isc/hex.h> -#include <isc/region.h> - -#include <isc/util.h> #include <isc/print.h> +#include <isc/region.h> #include <isc/string.h> +#include <isc/util.h> #include <pk11/site.h> -#define TEST_INPUT(x) (x), sizeof(x)-1 - -typedef struct hash_testcase { - const char *input; - size_t input_len; - const char *result; - int repeats; -} hash_testcase_t; +#define TEST_INPUT(x) (x), sizeof(x) - 1 /*Hash function test */ static void @@ -54,88 +43,31 @@ isc_hash_function_test(void **state) { UNUSED(state); - /* Incremental hashing */ - - h1 = isc_hash_function(NULL, 0, true, NULL); - h1 = isc_hash_function("This ", 5, true, &h1); - h1 = isc_hash_function("is ", 3, true, &h1); - h1 = isc_hash_function("a long test", 12, true, &h1); - - h2 = isc_hash_function("This is a long test", 20, - true, NULL); - - assert_int_equal(h1, h2); - /* Immutability of hash function */ - h1 = isc_hash_function(NULL, 0, true, NULL); - h2 = isc_hash_function(NULL, 0, true, NULL); + h1 = isc_hash_function(NULL, 0, true); + h2 = isc_hash_function(NULL, 0, true); assert_int_equal(h1, h2); /* Hash function characteristics */ - h1 = isc_hash_function("Hello world", 12, true, NULL); - h2 = isc_hash_function("Hello world", 12, true, NULL); + h1 = isc_hash_function("Hello world", 12, true); + h2 = isc_hash_function("Hello world", 12, true); assert_int_equal(h1, h2); /* Case */ - h1 = isc_hash_function("Hello world", 12, false, NULL); - h2 = isc_hash_function("heLLo WorLd", 12, false, NULL); + h1 = isc_hash_function("Hello world", 12, false); + h2 = isc_hash_function("heLLo WorLd", 12, false); assert_int_equal(h1, h2); /* Unequal */ - h1 = isc_hash_function("Hello world", 12, true, NULL); - h2 = isc_hash_function("heLLo WorLd", 12, true, NULL); + h1 = isc_hash_function("Hello world", 12, true); + h2 = isc_hash_function("heLLo WorLd", 12, true); assert_int_not_equal(h1, h2); } -/* Reverse hash function test */ -static void -isc_hash_function_reverse_test(void **state) { - unsigned int h1; - unsigned int h2; - - UNUSED(state); - - /* Incremental hashing */ - - h1 = isc_hash_function_reverse(NULL, 0, true, NULL); - h1 = isc_hash_function_reverse("\000", 1, true, &h1); - h1 = isc_hash_function_reverse("\003org", 4, true, &h1); - h1 = isc_hash_function_reverse("\007example", 8, true, &h1); - - h2 = isc_hash_function_reverse("\007example\003org\000", 13, - true, NULL); - - assert_int_equal(h1, h2); - - /* Immutability of hash function */ - h1 = isc_hash_function_reverse(NULL, 0, true, NULL); - h2 = isc_hash_function_reverse(NULL, 0, true, NULL); - - assert_int_equal(h1, h2); - - /* Hash function characteristics */ - h1 = isc_hash_function_reverse("Hello world", 12, true, NULL); - h2 = isc_hash_function_reverse("Hello world", 12, true, NULL); - - assert_int_equal(h1, h2); - - /* Case */ - h1 = isc_hash_function_reverse("Hello world", 12, false, NULL); - h2 = isc_hash_function_reverse("heLLo WorLd", 12, false, NULL); - - assert_int_equal(h1, h2); - - /* Unequal */ - h1 = isc_hash_function_reverse("Hello world", 12, true, NULL); - h2 = isc_hash_function_reverse("heLLo WorLd", 12, true, NULL); - - assert_true(h1 != h2); -} - /* Hash function initializer test */ static void isc_hash_initializer_test(void **state) { @@ -144,15 +76,15 @@ isc_hash_initializer_test(void **state) { UNUSED(state); - h1 = isc_hash_function("Hello world", 12, true, NULL); - h2 = isc_hash_function("Hello world", 12, true, NULL); + h1 = isc_hash_function("Hello world", 12, true); + h2 = isc_hash_function("Hello world", 12, true); assert_int_equal(h1, h2); isc_hash_set_initializer(isc_hash_get_initializer()); /* Hash value must not change */ - h2 = isc_hash_function("Hello world", 12, true, NULL); + h2 = isc_hash_function("Hello world", 12, true); assert_int_equal(h1, h2); } @@ -161,7 +93,6 @@ int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(isc_hash_function_test), - cmocka_unit_test(isc_hash_function_reverse_test), cmocka_unit_test(isc_hash_initializer_test), }; @@ -178,4 +109,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/heap_test.c b/lib/isc/tests/heap_test.c index ff975a26..b60aba28 100644 --- a/lib/isc/tests/heap_test.c +++ b/lib/isc/tests/heap_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,16 +11,14 @@ /* ! \file */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - -#include <string.h> #include <stdlib.h> +#include <string.h> #define UNIT_TESTING #include <cmocka.h> @@ -29,6 +27,29 @@ #include <isc/mem.h> #include <isc/util.h> +#include "isctest.h" + +static int +_setup(void **state) { + isc_result_t result; + + UNUSED(state); + + result = isc_test_begin(NULL, true, 0); + assert_int_equal(result, ISC_R_SUCCESS); + + return (0); +} + +static int +_teardown(void **state) { + UNUSED(state); + + isc_test_end(); + + return (0); +} + struct e { unsigned int value; unsigned int index; @@ -52,17 +73,13 @@ idx(void *p, unsigned int i) { /* test isc_heap_delete() */ static void isc_heap_delete_test(void **state) { - isc_mem_t *mctx = NULL; isc_heap_t *heap = NULL; isc_result_t result; struct e e1 = { 100, 0 }; UNUSED(state); - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_heap_create(mctx, compare, idx, 0, &heap); + result = isc_heap_create(test_mctx, compare, idx, 0, &heap); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(heap); @@ -75,9 +92,6 @@ isc_heap_delete_test(void **state) { isc_heap_destroy(&heap); assert_int_equal(heap, NULL); - - isc_mem_detach(&mctx); - assert_int_equal(mctx, NULL); } int @@ -86,7 +100,7 @@ main(void) { cmocka_unit_test(isc_heap_delete_test), }; - return (cmocka_run_group_tests(tests, NULL, NULL)); + return (cmocka_run_group_tests(tests, _setup, _teardown)); } #else /* HAVE_CMOCKA */ @@ -99,4 +113,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/hmac_test.c b/lib/isc/tests/hmac_test.c index 8cac0cfa..1cf40026 100644 --- a/lib/isc/tests/hmac_test.c +++ b/lib/isc/tests/hmac_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,15 +11,13 @@ /* ! \file */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> #include <stdlib.h> - #include <string.h> #define UNIT_TESTING @@ -27,13 +25,13 @@ #include <isc/buffer.h> #include <isc/hex.h> +#include <isc/hmac.h> #include <isc/region.h> #include <isc/result.h> -#include <isc/hmac.h> #include "../hmac.c" -#define TEST_INPUT(x) (x), sizeof(x)-1 +#define TEST_INPUT(x) (x), sizeof(x) - 1 static int _setup(void **state) { @@ -86,19 +84,18 @@ isc_hmac_free_test(void **state) { static void isc_hmac_test(isc_hmac_t *hmac, const void *key, size_t keylen, - isc_md_type_t type, const char *buf, size_t buflen, - const char *result, const int repeats) -{ + const isc_md_type_t *type, const char *buf, size_t buflen, + const char *result, const int repeats) { assert_non_null(hmac); assert_int_equal(isc_hmac_init(hmac, key, keylen, type), ISC_R_SUCCESS); int i; for (i = 0; i < repeats; i++) { - assert_int_equal( - isc_hmac_update(hmac, - (const unsigned char *)buf, buflen), - ISC_R_SUCCESS); + assert_int_equal(isc_hmac_update(hmac, + (const unsigned char *)buf, + buflen), + ISC_R_SUCCESS); } unsigned char digest[ISC_MAX_MD_SIZE]; @@ -107,15 +104,13 @@ isc_hmac_test(isc_hmac_t *hmac, const void *key, size_t keylen, ISC_R_SUCCESS); char hexdigest[ISC_MAX_MD_SIZE * 2 + 3]; - isc_region_t r = { .base = digest, - .length = digestlen - }; + isc_region_t r = { .base = digest, .length = digestlen }; isc_buffer_t b; isc_buffer_init(&b, hexdigest, sizeof(hexdigest)); assert_return_code(isc_hex_totext(&r, 0, "", &b), ISC_R_SUCCESS); - assert_memory_equal(hexdigest, result, (result?strlen(result):0)); + assert_memory_equal(hexdigest, result, (result ? strlen(result) : 0)); assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS); } @@ -171,8 +166,10 @@ isc_hmac_update_test(void **state) { static void isc_hmac_reset_test(void **state) { isc_hmac_t *hmac = *state; +#if 0 unsigned char digest[ISC_MAX_MD_SIZE] __attribute((unused)); unsigned int digestlen __attribute((unused)); +#endif /* if 0 */ assert_non_null(hmac); @@ -191,8 +188,8 @@ isc_hmac_reset_test(void **state) { * so this could be only manually checked that the test will * segfault when called by hand */ - expect_assert_failure(isc_hmac_final(hmac, digest, &digestlen)); -#endif + expect_assert_failure(isc_hmac_final(hmac,digest,&digestlen)); +#endif /* if 0 */ } static void @@ -219,8 +216,7 @@ isc_hmac_md5_test(void **state) { /* Test 0 */ isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_MD5, TEST_INPUT(""), - "74E6F7298A9C2D168935F58C001BAD88", - 1); + "74E6F7298A9C2D168935F58C001BAD88", 1); /* Test 1 */ isc_hmac_test(hmac, @@ -228,18 +224,14 @@ isc_hmac_md5_test(void **state) { "\x0b\x0b\x0b\x0b\x0b\x0b"), ISC_MD_MD5, TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), - "9294727A3638BB1C13F48EF8158BFC9D", - 1); + "9294727A3638BB1C13F48EF8158BFC9D", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_MD5, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_MD5, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79" "\x61\x20\x77\x61\x6e\x74\x20\x66\x6f" "\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), - "750C783E6AB0B503EAA86E310A5DB738", - 1); + "750C783E6AB0B503EAA86E310A5DB738", 1); /* Test 3 */ isc_hmac_test(hmac, @@ -251,8 +243,7 @@ isc_hmac_md5_test(void **state) { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), - "56BE34521D144C88DBB8C733F0E8B3F6", - 1); + "56BE34521D144C88DBB8C733F0E8B3F6", 1); /* Test 4 */ isc_hmac_test(hmac, TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" @@ -264,8 +255,7 @@ isc_hmac_md5_test(void **state) { "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), - "697EAF0ACA3A3AEA3A75164746FFAA79", - 1); + "697EAF0ACA3A3AEA3A75164746FFAA79", 1); #if 0 /* Test 5 -- unimplemented optional functionality */ isc_hmac_test(hmac, @@ -315,7 +305,7 @@ isc_hmac_md5_test(void **state) { "Larger Than One Block-Size Data"), "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91", 1); -#endif +#endif /* if 0 */ } static void @@ -324,8 +314,7 @@ isc_hmac_sha1_test(void **state) { /* Test 0 */ isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA1, TEST_INPUT(""), - "FBDB1D1B18AA6C08324B7D64B71FB76370690E1D", - 1); + "FBDB1D1B18AA6C08324B7D64B71FB76370690E1D", 1); /* Test 1 */ isc_hmac_test(hmac, @@ -333,17 +322,13 @@ isc_hmac_sha1_test(void **state) { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"), ISC_MD_SHA1, TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), - "B617318655057264E28BC0B6FB378C8EF146BE00", - 1); + "B617318655057264E28BC0B6FB378C8EF146BE00", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_SHA1, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_SHA1, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), - "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79", - 1); + "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79", 1); /* Test 3 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -354,8 +339,7 @@ isc_hmac_sha1_test(void **state) { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), - "125D7342B9AC11CD91A39AF48AA17B4F63F175D3", - 1); + "125D7342B9AC11CD91A39AF48AA17B4F63F175D3", 1); /* Test 4 */ isc_hmac_test(hmac, TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" @@ -367,8 +351,7 @@ isc_hmac_sha1_test(void **state) { "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), - "4C9007F4026250C6BC8414F9BF50C86C2D7235DA", - 1); + "4C9007F4026250C6BC8414F9BF50C86C2D7235DA", 1); #if 0 /* Test 5 */ isc_hmac_test(hmac, @@ -378,7 +361,7 @@ isc_hmac_sha1_test(void **state) { TEST_INPUT("Test With Truncation"), "4C1A03424B55E07FE7F27BE1", 1); -#endif +#endif /* if 0 */ /* Test 6 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -406,8 +389,7 @@ isc_hmac_sha1_test(void **state) { ISC_MD_SHA1, TEST_INPUT("Test Using Larger Than Block-Size Key and " "Larger Than One Block-Size Data"), - "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91", - 1); + "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91", 1); } static void @@ -430,9 +412,7 @@ isc_hmac_sha224_test(void **state) { "4F53684B22", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_SHA224, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_SHA224, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), @@ -475,7 +455,7 @@ isc_hmac_sha224_test(void **state) { TEST_INPUT("Test With Truncation"), "4C1A03424B55E07FE7F27BE1", 1); -#endif +#endif /* if 0 */ /* Test 6 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -490,7 +470,8 @@ isc_hmac_sha224_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA224, TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), @@ -511,7 +492,8 @@ isc_hmac_sha224_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA224, TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" @@ -554,9 +536,7 @@ isc_hmac_sha256_test(void **state) { "A726E9376C2E32CFF7", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_SHA256, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_SHA256, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), @@ -599,7 +579,7 @@ isc_hmac_sha256_test(void **state) { TEST_INPUT("Test With Truncation"), "4C1A03424B55E07FE7F27BE1", 1); -#endif +#endif /* if 0 */ /* Test 6 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -614,7 +594,8 @@ isc_hmac_sha256_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA256, TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), @@ -635,7 +616,8 @@ isc_hmac_sha256_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA256, TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" @@ -679,9 +661,7 @@ isc_hmac_sha384_test(void **state) { "E8B2FA9CB6", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_SHA384, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_SHA384, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), @@ -727,7 +707,7 @@ isc_hmac_sha384_test(void **state) { TEST_INPUT("Test With Truncation"), "4C1A03424B55E07FE7F27BE1", 1); -#endif +#endif /* if 0 */ /* Test 6 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -742,7 +722,8 @@ isc_hmac_sha384_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA384, TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), @@ -764,7 +745,8 @@ isc_hmac_sha384_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA384, TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" @@ -796,7 +778,8 @@ isc_hmac_sha512_test(void **state) { isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA512, TEST_INPUT(""), "B936CEE86C9F87AA5D3C6F2E84CB5A4239A5FE50480A6EC6" "6B70AB5B1F4AC6730C6C515421B327EC1D69402E53DFB49A" - "D7381EB067B338FD7B0CB22247225D47", 1); + "D7381EB067B338FD7B0CB22247225D47", + 1); /* Test 1 */ isc_hmac_test(hmac, @@ -809,9 +792,7 @@ isc_hmac_sha512_test(void **state) { "4EAEA3F4E4BE9D914EEB61F1702E696C203A126854", 1); /* Test 2 */ - isc_hmac_test(hmac, - TEST_INPUT("Jefe"), - ISC_MD_SHA512, + isc_hmac_test(hmac, TEST_INPUT("Jefe"), ISC_MD_SHA512, TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), @@ -857,7 +838,7 @@ isc_hmac_sha512_test(void **state) { TEST_INPUT("Test With Truncation"), "4C1A03424B55E07FE7F27BE1", 1); -#endif +#endif /* if 0 */ /* Test 6 */ isc_hmac_test(hmac, TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" @@ -872,7 +853,8 @@ isc_hmac_sha512_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA512, TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), @@ -894,7 +876,8 @@ isc_hmac_sha512_test(void **state) { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"), + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa"), ISC_MD_SHA512, TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" @@ -925,12 +908,12 @@ main(void) { cmocka_unit_test(isc_hmac_new_test), /* isc_hmac_init() */ - cmocka_unit_test_setup_teardown(isc_hmac_init_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_hmac_init_test, _reset, + _reset), /* isc_hmac_reset() */ - cmocka_unit_test_setup_teardown(isc_hmac_reset_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_hmac_reset_test, _reset, + _reset), /* isc_hmac_init() -> isc_hmac_update() -> isc_hmac_final() */ cmocka_unit_test(isc_hmac_md5_test), @@ -940,10 +923,10 @@ main(void) { cmocka_unit_test(isc_hmac_sha384_test), cmocka_unit_test(isc_hmac_sha512_test), - cmocka_unit_test_setup_teardown(isc_hmac_update_test, - _reset, _reset), - cmocka_unit_test_setup_teardown(isc_hmac_final_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_hmac_update_test, _reset, + _reset), + cmocka_unit_test_setup_teardown(isc_hmac_final_test, _reset, + _reset), cmocka_unit_test(isc_hmac_free_test), }; @@ -961,4 +944,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/ht_test.c b/lib/isc/tests/ht_test.c index 07f338a0..4b3e5222 100644 --- a/lib/isc/tests/ht_test.c +++ b/lib/isc/tests/ht_test.c @@ -3,21 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <inttypes.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - -#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -32,33 +30,36 @@ #include <isc/string.h> #include <isc/util.h> -static void * -default_memalloc(void *arg, size_t size) { - UNUSED(arg); - if (size == 0U) { - size = 1; - } - return (malloc(size)); +#include "isctest.h" + +static int +_setup(void **state) { + isc_result_t result; + + UNUSED(state); + + result = isc_test_begin(NULL, true, 0); + assert_int_equal(result, ISC_R_SUCCESS); + + return (0); } -static void -default_memfree(void *arg, void *ptr) { - UNUSED(arg); - free(ptr); +static int +_teardown(void **state) { + UNUSED(state); + + isc_test_end(); + + return (0); } static void test_ht_full(int bits, uintptr_t count) { isc_ht_t *ht = NULL; isc_result_t result; - isc_mem_t *mctx = NULL; uintptr_t i; - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx, 0); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_ht_init(&ht, mctx, bits); + result = isc_ht_init(&ht, test_mctx, bits); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(ht); @@ -70,7 +71,7 @@ test_ht_full(int bits, uintptr_t count) { unsigned char key[16]; snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); - result = isc_ht_add(ht, key, 16, (void *) i); + result = isc_ht_add(ht, key, 16, (void *)i); assert_int_equal(result, ISC_R_SUCCESS); } @@ -81,14 +82,14 @@ test_ht_full(int bits, uintptr_t count) { strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); result = isc_ht_find(ht, key, 16, &f); assert_int_equal(result, ISC_R_SUCCESS); - assert_ptr_equal((void *) i, (uintptr_t) f); + assert_ptr_equal((void *)i, (uintptr_t)f); } for (i = 1; i < count; i++) { unsigned char key[16]; snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); - result = isc_ht_add(ht, key, 16, (void *) i); + result = isc_ht_add(ht, key, 16, (void *)i); assert_int_equal(result, ISC_R_EXISTS); } @@ -100,8 +101,8 @@ test_ht_full(int bits, uintptr_t count) { */ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); - result = isc_ht_add(ht, (const unsigned char *) key, - strlen(key), (void *) i); + result = isc_ht_add(ht, (const unsigned char *)key, strlen(key), + (void *)i); assert_int_equal(result, ISC_R_SUCCESS); } @@ -123,10 +124,10 @@ test_ht_full(int bits, uintptr_t count) { void *f = NULL; snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); - result = isc_ht_find(ht, (const unsigned char *) key, + result = isc_ht_find(ht, (const unsigned char *)key, strlen(key), &f); assert_int_equal(result, ISC_R_SUCCESS); - assert_ptr_equal(f, (void *) i); + assert_ptr_equal(f, (void *)i); } for (i = 1; i < count; i++) { @@ -148,7 +149,7 @@ test_ht_full(int bits, uintptr_t count) { */ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " KEY of a raw hashtable!!", sizeof(key)); - result = isc_ht_add(ht, key, 16, (void *) i); + result = isc_ht_add(ht, key, 16, (void *)i); assert_int_equal(result, ISC_R_SUCCESS); } @@ -157,16 +158,15 @@ test_ht_full(int bits, uintptr_t count) { void *f = NULL; snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, " key of a raw hashtable!!", sizeof(key)); - result = isc_ht_delete(ht, (const unsigned char *) key, + result = isc_ht_delete(ht, (const unsigned char *)key, strlen(key)); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_ht_find(ht, (const unsigned char *) key, + result = isc_ht_find(ht, (const unsigned char *)key, strlen(key), &f); assert_int_equal(result, ISC_R_NOTFOUND); assert_null(f); } - for (i = 1; i < count; i++) { unsigned char key[16]; void *f = NULL; @@ -177,7 +177,7 @@ test_ht_full(int bits, uintptr_t count) { strlcat((char *)key, " KEY of a raw hashtable!!", sizeof(key)); result = isc_ht_find(ht, key, 16, &f); assert_int_equal(result, ISC_R_SUCCESS); - assert_ptr_equal((void *) i, (uintptr_t) f); + assert_ptr_equal((void *)i, (uintptr_t)f); } for (i = 1; i < count; i++) { @@ -192,27 +192,20 @@ test_ht_full(int bits, uintptr_t count) { isc_ht_destroy(&ht); assert_null(ht); - - isc_mem_detach(&mctx); } static void test_ht_iterator() { isc_ht_t *ht = NULL; isc_result_t result; - isc_mem_t *mctx = NULL; - isc_ht_iter_t * iter = NULL; + isc_ht_iter_t *iter = NULL; uintptr_t i; uintptr_t count = 10000; uint32_t walked; unsigned char key[16]; size_t tksize; - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx, 0); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_ht_init(&ht, mctx, 16); + result = isc_ht_init(&ht, test_mctx, 16); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(ht); for (i = 1; i <= count; i++) { @@ -222,7 +215,7 @@ test_ht_iterator() { */ snprintf((char *)key, sizeof(key), "%u", (unsigned int)i); strlcat((char *)key, "key of a raw hashtable!!", sizeof(key)); - result = isc_ht_add(ht, key, 16, (void *) i); + result = isc_ht_add(ht, key, 16, (void *)i); assert_int_equal(result, ISC_R_SUCCESS); } @@ -230,8 +223,7 @@ test_ht_iterator() { result = isc_ht_iter_create(ht, &iter); assert_int_equal(result, ISC_R_SUCCESS); - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; + for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS; result = isc_ht_iter_next(iter)) { unsigned char *tkey = NULL; @@ -295,11 +287,10 @@ test_ht_iterator() { walked++; } assert_int_equal(result, ISC_R_NOMORE); - assert_int_equal(walked, count/2); + assert_int_equal(walked, count / 2); walked = 0; - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; + for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS; result = isc_ht_iter_next(iter)) { walked++; @@ -313,8 +304,6 @@ test_ht_iterator() { isc_ht_destroy(&ht); assert_null(ht); - - isc_mem_detach(&mctx); } /* 20 bit, 200K elements test */ @@ -324,7 +313,6 @@ isc_ht_20(void **state) { test_ht_full(20, 200000); } - /* 8 bit, 20000 elements crowded test */ static void isc_ht_8(void **state) { @@ -355,7 +343,7 @@ main(void) { cmocka_unit_test(isc_ht_iterator_test), }; - return (cmocka_run_group_tests(tests, NULL, NULL)); + return (cmocka_run_group_tests(tests, _setup, _teardown)); } #else /* HAVE_CMOCKA */ @@ -368,4 +356,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/isctest.c b/lib/isc/tests/isctest.c index 66ca877e..66c70e50 100644 --- a/lib/isc/tests/isctest.c +++ b/lib/isc/tests/isctest.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,7 @@ /*! \file */ -#include <config.h> - +#include "isctest.h" #include <inttypes.h> #include <stdbool.h> #include <stdlib.h> @@ -28,13 +27,12 @@ #include <isc/timer.h> #include <isc/util.h> -#include "isctest.h" - -isc_mem_t *mctx = NULL; -isc_log_t *lctx = NULL; +isc_mem_t *test_mctx = NULL; +isc_log_t *test_lctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; +isc_nm_t *netmgr = NULL; isc_task_t *maintask = NULL; int ncpus; @@ -43,17 +41,15 @@ static bool test_running = false; /* * Logging categories: this needs to match the list in bin/named/log.c. */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { "query-errors", 0 }, - { NULL, 0 } -}; +static isc_logcategory_t categories[] = { { "", 0 }, + { "client", 0 }, + { "network", 0 }, + { "update", 0 }, + { "queries", 0 }, + { "unmatched", 0 }, + { "update-security", 0 }, + { "query-errors", 0 }, + { NULL, 0 } }; static void cleanup_managers(void) { @@ -70,6 +66,9 @@ cleanup_managers(void) { if (timermgr != NULL) { isc_timermgr_destroy(&timermgr); } + if (netmgr != NULL) { + isc_nm_detach(&netmgr); + } } static isc_result_t @@ -86,23 +85,22 @@ create_managers(unsigned int workers) { workers = atoi(p); } - CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr)); + netmgr = isc_nm_start(test_mctx, workers); + CHECK(isc_taskmgr_create(test_mctx, workers, 0, netmgr, &taskmgr)); CHECK(isc_task_create(taskmgr, 0, &maintask)); isc_taskmgr_setexcltask(taskmgr, maintask); - CHECK(isc_timermgr_create(mctx, &timermgr)); - CHECK(isc_socketmgr_create(mctx, &socketmgr)); + CHECK(isc_timermgr_create(test_mctx, &timermgr)); + CHECK(isc_socketmgr_create(test_mctx, &socketmgr)); return (ISC_R_SUCCESS); - cleanup: +cleanup: cleanup_managers(); return (result); } isc_result_t -isc_test_begin(FILE *logfile, bool start_managers, - unsigned int workers) -{ +isc_test_begin(FILE *logfile, bool start_managers, unsigned int workers) { isc_result_t result; INSIST(!test_running); @@ -110,27 +108,24 @@ isc_test_begin(FILE *logfile, bool start_managers, isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - INSIST(mctx == NULL); - CHECK(isc_mem_create(0, 0, &mctx)); + INSIST(test_mctx == NULL); + isc_mem_create(&test_mctx); if (logfile != NULL) { isc_logdestination_t destination; isc_logconfig_t *logconfig = NULL; - INSIST(lctx == NULL); - CHECK(isc_log_create(mctx, &lctx, &logconfig)); - - isc_log_registercategories(lctx, categories); - isc_log_setcontext(lctx); + INSIST(test_lctx == NULL); + isc_log_create(test_mctx, &test_lctx, &logconfig); + isc_log_registercategories(test_lctx, categories); + isc_log_setcontext(test_lctx); destination.file.stream = logfile; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; - CHECK(isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - ISC_LOG_DYNAMIC, - &destination, 0)); + isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, + ISC_LOG_DYNAMIC, &destination, 0); CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL)); } @@ -142,7 +137,7 @@ isc_test_begin(FILE *logfile, bool start_managers, return (ISC_R_SUCCESS); - cleanup: +cleanup: isc_test_end(); return (result); } @@ -158,11 +153,11 @@ isc_test_end(void) { cleanup_managers(); - if (lctx != NULL) { - isc_log_destroy(&lctx); + if (test_lctx != NULL) { + isc_log_destroy(&test_lctx); } - if (mctx != NULL) { - isc_mem_destroy(&mctx); + if (test_mctx != NULL) { + isc_mem_destroy(&test_mctx); } test_running = false; @@ -181,11 +176,11 @@ isc_test_nap(uint32_t usec) { nanosleep(&ts, NULL); #elif HAVE_USLEEP usleep(usec); -#else +#else /* ifdef HAVE_NANOSLEEP */ /* * No fractional-second sleep function is available, so we * round up to the nearest second and sleep instead */ sleep((usec / 1000000) + 1); -#endif +#endif /* ifdef HAVE_NANOSLEEP */ } diff --git a/lib/isc/tests/isctest.h b/lib/isc/tests/isctest.h index 58ba7995..8551bcfd 100644 --- a/lib/isc/tests/isctest.h +++ b/lib/isc/tests/isctest.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,6 @@ /*! \file */ -#include <config.h> - #include <inttypes.h> #include <stdbool.h> @@ -20,6 +18,7 @@ #include <isc/hash.h> #include <isc/log.h> #include <isc/mem.h> +#include <isc/netmgr.h> #include <isc/print.h> #include <isc/result.h> #include <isc/string.h> @@ -27,23 +26,23 @@ #include <isc/timer.h> #include <isc/util.h> -#define CHECK(r) \ - do { \ - result = (r); \ +#define CHECK(r) \ + do { \ + result = (r); \ if (result != ISC_R_SUCCESS) \ - goto cleanup; \ + goto cleanup; \ } while (0) -extern isc_mem_t *mctx; -extern isc_log_t *lctx; +extern isc_mem_t *test_mctx; +extern isc_log_t *test_lctx; extern isc_taskmgr_t *taskmgr; extern isc_timermgr_t *timermgr; extern isc_socketmgr_t *socketmgr; +extern isc_nm_t *netmgr; extern int ncpus; isc_result_t -isc_test_begin(FILE *logfile, bool start_managers, - unsigned int workers); +isc_test_begin(FILE *logfile, bool start_managers, unsigned int workers); /*%< * Begin test, logging to 'logfile' or default if not specified. * diff --git a/lib/isc/tests/lex_test.c b/lib/isc/tests/lex_test.c index ca3f97f9..34ae9ba9 100644 --- a/lib/isc/tests/lex_test.c +++ b/lib/isc/tests/lex_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -29,10 +27,32 @@ #include <isc/mem.h> #include <isc/util.h> +#include "isctest.h" + +static int +_setup(void **state) { + isc_result_t result; + + UNUSED(state); + + result = isc_test_begin(NULL, true, 0); + assert_int_equal(result, ISC_R_SUCCESS); + + return (0); +} + +static int +_teardown(void **state) { + UNUSED(state); + + isc_test_end(); + + return (0); +} + /* check handling of 0xff */ static void lex_0xff(void **state) { - isc_mem_t *mctx = NULL; isc_result_t result; isc_lex_t *lex = NULL; isc_buffer_t death_buf; @@ -42,10 +62,7 @@ lex_0xff(void **state) { UNUSED(state); - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_lex_create(mctx, 1024, &lex); + result = isc_lex_create(test_mctx, 1024, &lex); assert_int_equal(result, ISC_R_SUCCESS); isc_buffer_init(&death_buf, &death[0], sizeof(death)); @@ -58,14 +75,11 @@ lex_0xff(void **state) { assert_int_equal(result, ISC_R_SUCCESS); isc_lex_destroy(&lex); - - isc_mem_destroy(&mctx); } /* check setting of source line */ static void lex_setline(void **state) { - isc_mem_t *mctx = NULL; isc_result_t result; isc_lex_t *lex = NULL; unsigned char text[] = "text\nto\nbe\nprocessed\nby\nlexer"; @@ -76,10 +90,7 @@ lex_setline(void **state) { UNUSED(state); - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_lex_create(mctx, 1024, &lex); + result = isc_lex_create(test_mctx, 1024, &lex); assert_int_equal(result, ISC_R_SUCCESS); isc_buffer_init(&buf, &text[0], sizeof(text)); @@ -106,8 +117,6 @@ lex_setline(void **state) { assert_int_equal(line, 105U); isc_lex_destroy(&lex); - - isc_mem_destroy(&mctx); } int @@ -117,7 +126,7 @@ main(void) { cmocka_unit_test(lex_setline), }; - return (cmocka_run_group_tests(tests, NULL, NULL)); + return (cmocka_run_group_tests(tests, _setup, _teardown)); } #else /* HAVE_CMOCKA */ @@ -130,4 +139,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/md_test.c b/lib/isc/tests/md_test.c index 5ec2c873..a41471a0 100644 --- a/lib/isc/tests/md_test.c +++ b/lib/isc/tests/md_test.c @@ -3,20 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <string.h> /* For FIPS_mode() */ @@ -27,13 +24,13 @@ #include <isc/buffer.h> #include <isc/hex.h> +#include <isc/md.h> #include <isc/region.h> #include <isc/result.h> -#include <isc/md.h> #include "../md.c" -#define TEST_INPUT(x) (x), sizeof(x)-1 +#define TEST_INPUT(x) (x), sizeof(x) - 1 static int _setup(void **state) { @@ -80,14 +77,13 @@ isc_md_free_test(void **state) { isc_md_t *md = isc_md_new(); assert_non_null(md); - isc_md_free(md); /* Test freeing valid message digest context */ + isc_md_free(md); /* Test freeing valid message digest context */ isc_md_free(NULL); /* Test freeing NULL argument */ } static void -isc_md_test(isc_md_t *md, isc_md_type_t type, const char *buf, size_t buflen, - const char *result, const int repeats) -{ +isc_md_test(isc_md_t *md, const isc_md_type_t *type, const char *buf, + size_t buflen, const char *result, const int repeats) { assert_non_null(md); assert_int_equal(isc_md_init(md, type), ISC_R_SUCCESS); @@ -104,14 +100,13 @@ isc_md_test(isc_md_t *md, isc_md_type_t type, const char *buf, size_t buflen, assert_int_equal(isc_md_final(md, digest, &digestlen), ISC_R_SUCCESS); char hexdigest[ISC_MAX_MD_SIZE * 2 + 3]; - isc_region_t r = { .base = digest, - .length = digestlen }; + isc_region_t r = { .base = digest, .length = digestlen }; isc_buffer_t b; isc_buffer_init(&b, hexdigest, sizeof(hexdigest)); assert_return_code(isc_hex_totext(&r, 0, "", &b), ISC_R_SUCCESS); - assert_memory_equal(hexdigest, result, (result?strlen(result):0)); + assert_memory_equal(hexdigest, result, (result ? strlen(result) : 0)); assert_int_equal(isc_md_reset(md), ISC_R_SUCCESS); } @@ -159,8 +154,10 @@ isc_md_update_test(void **state) { static void isc_md_reset_test(void **state) { isc_md_t *md = *state; +#if 0 unsigned char digest[ISC_MAX_MD_SIZE] __attribute((unused)); unsigned int digestlen __attribute((unused)); +#endif /* if 0 */ assert_non_null(md); @@ -178,8 +175,8 @@ isc_md_reset_test(void **state) { * so this could be only manually checked that the test will * segfault when called by hand */ - expect_assert_failure(isc_md_final(md, digest, &digestlen)); -#endif + expect_assert_failure(isc_md_final(md,digest,&digestlen)); +#endif /* if 0 */ } static void @@ -236,20 +233,16 @@ isc_md_sha1_test(void **state) { "ljklmklmnlmnomnopnopq"), "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", 1); isc_md_test(md, ISC_MD_SHA1, TEST_INPUT("a"), - "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", - 1000000); + "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", 1000000); isc_md_test(md, ISC_MD_SHA1, TEST_INPUT("01234567012345670123456701234567"), - "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452", - 20); + "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452", 20); isc_md_test(md, ISC_MD_SHA1, TEST_INPUT("\x5e"), - "5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2", - 1); + "5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2", 1); isc_md_test(md, ISC_MD_SHA1, TEST_INPUT("\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46" "\xaa\x55\xfe\x75\x71\x46"), - "82ABFF6605DBE1C17DEF12A394FA22A82B544A35", - 1); + "82ABFF6605DBE1C17DEF12A394FA22A82B544A35", 1); isc_md_test(md, ISC_MD_SHA1, TEST_INPUT("\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b" "\x4f\xba\x15\xa1\xd5\x9f\x3f\xd8\x4d\x22" @@ -353,7 +346,8 @@ isc_md_sha256_test(void **state) { 1); isc_md_test(md, ISC_MD_SHA256, TEST_INPUT("a"), "CDC76E5C9914FB9281A1C7E284D73E67F1809A48A49720" - "0E046D39CCC7112CD0", 1000000); + "0E046D39CCC7112CD0", + 1000000); isc_md_test(md, ISC_MD_SHA256, TEST_INPUT("01234567012345670123456701234567"), "594847328451BDFA85056225462CC1D867D877FB388DF0" @@ -552,12 +546,12 @@ main(void) { cmocka_unit_test(isc_md_new_test), /* isc_md_init() */ - cmocka_unit_test_setup_teardown(isc_md_init_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_md_init_test, _reset, + _reset), /* isc_md_reset() */ - cmocka_unit_test_setup_teardown(isc_md_reset_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_md_reset_test, _reset, + _reset), /* isc_md_init() -> isc_md_update() -> isc_md_final() */ cmocka_unit_test(isc_md_md5_test), @@ -567,10 +561,10 @@ main(void) { cmocka_unit_test(isc_md_sha384_test), cmocka_unit_test(isc_md_sha512_test), - cmocka_unit_test_setup_teardown(isc_md_update_test, - _reset, _reset), - cmocka_unit_test_setup_teardown(isc_md_final_test, - _reset, _reset), + cmocka_unit_test_setup_teardown(isc_md_update_test, _reset, + _reset), + cmocka_unit_test_setup_teardown(isc_md_final_test, _reset, + _reset), cmocka_unit_test(isc_md_free_test), }; @@ -588,4 +582,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/mem_test.c b/lib/isc/tests/mem_test.c index 85d48346..e096c54c 100644 --- a/lib/isc/tests/mem_test.c +++ b/lib/isc/tests/mem_test.c @@ -3,36 +3,37 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <fcntl.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <unistd.h> -#include <fcntl.h> #define UNIT_TESTING #include <cmocka.h> #include <isc/file.h> #include <isc/mem.h> +#include <isc/mutex.h> +#include <isc/os.h> #include <isc/print.h> #include <isc/result.h> #include <isc/stdio.h> +#include <isc/thread.h> +#include <isc/time.h> #include <isc/util.h> #include "../mem_p.h" - #include "isctest.h" static int @@ -47,21 +48,6 @@ _setup(void **state) { return (0); } -static void * -default_memalloc(void *arg, size_t size) { - UNUSED(arg); - if (size == 0U) { - size = 1; - } - return (malloc(size)); -} - -static void -default_memfree(void *arg, void *ptr) { - UNUSED(arg); - free(ptr); -} - static int _teardown(void **state) { UNUSED(state); @@ -71,35 +57,27 @@ _teardown(void **state) { return (0); } -#define MP1_FREEMAX 10 -#define MP1_FILLCNT 10 -#define MP1_MAXALLOC 30 +#define MP1_FREEMAX 10 +#define MP1_FILLCNT 10 +#define MP1_MAXALLOC 30 -#define MP2_FREEMAX 25 -#define MP2_FILLCNT 25 +#define MP2_FREEMAX 25 +#define MP2_FILLCNT 25 /* general memory system tests */ static void isc_mem_test(void **state) { - isc_result_t result; void *items1[50]; void *items2[50]; void *tmp; - isc_mem_t *localmctx = NULL; isc_mempool_t *mp1 = NULL, *mp2 = NULL; unsigned int i, j; int rval; UNUSED(state); - result = isc_mem_create(0, 0, &localmctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_mempool_create(localmctx, 24, &mp1); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_mempool_create(localmctx, 31, &mp2); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mempool_create(test_mctx, 24, &mp1); + isc_mempool_create(test_mctx, 31, &mp2); isc_mempool_setfreemax(mp1, MP1_FREEMAX); isc_mempool_setfillcount(mp1, MP1_FILLCNT); @@ -164,15 +142,7 @@ isc_mem_test(void **state) { isc_mempool_destroy(&mp1); isc_mempool_destroy(&mp2); - isc_mem_destroy(&localmctx); - - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &localmctx, - ISC_MEMFLAG_FILL | ISC_MEMFLAG_INTERNAL); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_mempool_create(localmctx, 2, &mp1); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mempool_create(test_mctx, 2, &mp1); tmp = isc_mempool_get(mp1); assert_non_null(tmp); @@ -180,15 +150,11 @@ isc_mem_test(void **state) { isc_mempool_put(mp1, tmp); isc_mempool_destroy(&mp1); - - isc_mem_destroy(&localmctx); - } /* test TotalUse calculation */ static void isc_mem_total_test(void **state) { - isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, after; ssize_t diff; @@ -198,11 +164,7 @@ isc_mem_total_test(void **state) { /* Local alloc, free */ mctx2 = NULL; - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx2, 0); - if (result != ISC_R_SUCCESS) { - goto out; - } + isc_mem_create(&mctx2); before = isc_mem_total(mctx2); @@ -221,32 +183,27 @@ isc_mem_total_test(void **state) { /* ISC_MEMFLAG_INTERNAL */ - before = isc_mem_total(mctx); + before = isc_mem_total(test_mctx); for (i = 0; i < 100000; i++) { void *ptr; - ptr = isc_mem_allocate(mctx, 2048); - isc_mem_free(mctx, ptr); + ptr = isc_mem_allocate(test_mctx, 2048); + isc_mem_free(test_mctx, ptr); } - after = isc_mem_total(mctx); + after = isc_mem_total(test_mctx); diff = after - before; /* 2048 +8 bytes extra for size_info */ assert_int_equal(diff, (2048 + 8) * 100000); - out: - if (mctx2 != NULL) { - isc_mem_destroy(&mctx2); - } - + isc_mem_destroy(&mctx2); } /* test InUse calculation */ static void isc_mem_inuse_test(void **state) { - isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, after; ssize_t diff; @@ -255,11 +212,7 @@ isc_mem_inuse_test(void **state) { UNUSED(state); mctx2 = NULL; - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx2, 0); - if (result != ISC_R_SUCCESS) { - goto out; - } + isc_mem_create(&mctx2); before = isc_mem_inuse(mctx2); ptr = isc_mem_allocate(mctx2, 1024000); @@ -270,11 +223,7 @@ isc_mem_inuse_test(void **state) { assert_int_equal(diff, 0); - out: - if (mctx2 != NULL) { - isc_mem_destroy(&mctx2); - } - + isc_mem_destroy(&mctx2); } #if ISC_MEM_TRACKLINES @@ -293,9 +242,7 @@ isc_mem_noflags_test(void **state) { UNUSED(state); - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx2, 0); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mem_create(&mctx2); isc_mem_debugging = 0; ptr = isc_mem_get(mctx2, 2048); assert_non_null(ptr); @@ -340,9 +287,7 @@ isc_mem_recordflag_test(void **state) { UNUSED(state); - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx2, 0); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mem_create(&mctx2); ptr = isc_mem_get(mctx2, 2048); assert_non_null(ptr); isc__mem_printactive(mctx2, f); @@ -367,7 +312,6 @@ isc_mem_recordflag_test(void **state) { p = strchr(p + 1, '\n'); assert_non_null(p); assert_int_equal(strlen(p), 1); - } /* test mem with trace flag */ @@ -385,10 +329,8 @@ isc_mem_traceflag_test(void **state) { UNUSED(state); - result = isc_mem_createx(0, 0, default_memalloc, default_memfree, - NULL, &mctx2, 0); + isc_mem_create(&mctx2); isc_mem_debugging = ISC_MEM_DEBUGTRACE; - assert_int_equal(result, ISC_R_SUCCESS); ptr = isc_mem_get(mctx2, 2048); assert_non_null(ptr); isc__mem_printactive(mctx2, f); @@ -422,7 +364,129 @@ isc_mem_traceflag_test(void **state) { isc_mem_debugging = ISC_MEM_DEBUGRECORD; } -#endif +#endif /* if ISC_MEM_TRACKLINES */ + +#if !defined(__SANITIZE_THREAD__) + +#define ITERS 512 +#define NUM_ITEMS 1024 /* 768 */ +#define ITEM_SIZE 65534 + +static isc_threadresult_t +mem_thread(isc_threadarg_t arg) { + void *items[NUM_ITEMS]; + size_t size = *((size_t *)arg); + + for (int i = 0; i < ITERS; i++) { + for (int j = 0; j < NUM_ITEMS; j++) { + items[j] = isc_mem_get(test_mctx, size); + } + for (int j = 0; j < NUM_ITEMS; j++) { + isc_mem_put(test_mctx, items[j], size); + } + } + + return ((isc_threadresult_t)0); +} + +static void +isc_mem_benchmark(void **state) { + int nthreads = ISC_MAX(ISC_MIN(isc_os_ncpus(), 32), 1); + isc_thread_t threads[32]; + isc_time_t ts1, ts2; + double t; + isc_result_t result; + size_t size = ITEM_SIZE; + + UNUSED(state); + + result = isc_time_now(&ts1); + assert_int_equal(result, ISC_R_SUCCESS); + + for (int i = 0; i < nthreads; i++) { + isc_thread_create(mem_thread, &size, &threads[i]); + size = size / 2; + } + for (int i = 0; i < nthreads; i++) { + isc_thread_join(threads[i], NULL); + } + + result = isc_time_now(&ts2); + assert_int_equal(result, ISC_R_SUCCESS); + + t = isc_time_microdiff(&ts2, &ts1); + + printf("[ TIME ] isc_mem_benchmark: " + "%d isc_mem_{get,put} calls, %f seconds, %f calls/second\n", + nthreads * ITERS * NUM_ITEMS, t / 1000000.0, + (nthreads * ITERS * NUM_ITEMS) / (t / 1000000.0)); +} + +static isc_threadresult_t +mempool_thread(isc_threadarg_t arg) { + isc_mempool_t *mp = (isc_mempool_t *)arg; + void *items[NUM_ITEMS]; + + for (int i = 0; i < ITERS; i++) { + for (int j = 0; j < NUM_ITEMS; j++) { + items[j] = isc_mempool_get(mp); + } + for (int j = 0; j < NUM_ITEMS; j++) { + isc_mempool_put(mp, items[j]); + } + } + + return ((isc_threadresult_t)0); +} + +static void +isc_mempool_benchmark(void **state) { + int nthreads = ISC_MAX(ISC_MIN(isc_os_ncpus(), 32), 1); + isc_thread_t threads[32]; + isc_time_t ts1, ts2; + double t; + isc_result_t result; + size_t size = ITEM_SIZE; + isc_mempool_t *mp = NULL; + isc_mutex_t mplock; + + isc_mutex_init(&mplock); + + isc_mempool_create(test_mctx, ITEM_SIZE, &mp); + + isc_mempool_associatelock(mp, &mplock); + + isc_mempool_setfreemax(mp, 32768); + isc_mempool_setfillcount(mp, ISC_MAX(NUM_ITEMS / nthreads, 1)); + + UNUSED(state); + + result = isc_time_now(&ts1); + assert_int_equal(result, ISC_R_SUCCESS); + + for (int i = 0; i < nthreads; i++) { + isc_thread_create(mempool_thread, mp, &threads[i]); + size = size / 2; + } + for (int i = 0; i < nthreads; i++) { + isc_thread_join(threads[i], NULL); + } + + result = isc_time_now(&ts2); + assert_int_equal(result, ISC_R_SUCCESS); + + t = isc_time_microdiff(&ts2, &ts1); + + printf("[ TIME ] isc_mempool_benchmark: " + "%d isc_mempool_{get,put} calls, %f seconds, %f calls/second\n", + nthreads * ITERS * NUM_ITEMS, t / 1000000.0, + (nthreads * ITERS * NUM_ITEMS) / (t / 1000000.0)); + + isc_mempool_destroy(&mp); + isc_mutex_destroy(&mplock); +} + +#endif /* __SANITIZE_THREAD */ /* * Main @@ -431,21 +495,32 @@ isc_mem_traceflag_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_mem_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_mem_total_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_mem_inuse_test, - _setup, _teardown), - + cmocka_unit_test_setup_teardown(isc_mem_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(isc_mem_total_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(isc_mem_inuse_test, _setup, + _teardown), + +#if !defined(__SANITIZE_THREAD__) + cmocka_unit_test_setup_teardown(isc_mem_benchmark, _setup, + _teardown), + cmocka_unit_test_setup_teardown(isc_mempool_benchmark, _setup, + _teardown), +#endif /* __SANITIZE_THREAD__ */ #if ISC_MEM_TRACKLINES - cmocka_unit_test_setup_teardown(isc_mem_noflags_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_mem_recordflag_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_mem_traceflag_test, - _setup, _teardown), -#endif + cmocka_unit_test_setup_teardown(isc_mem_noflags_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(isc_mem_recordflag_test, _setup, + _teardown), + /* + * traceflag_test closes stderr, which causes weird + * side effects for any next test trying to use libuv. + * This test has to be the last one to avoid problems. + */ + cmocka_unit_test_setup_teardown(isc_mem_traceflag_test, _setup, + _teardown), +#endif /* if ISC_MEM_TRACKLINES */ }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -457,9 +532,8 @@ main(void) { int main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); - + printf("1..0 # Skipped: cmocka not available\n"); + return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/netaddr_test.c b/lib/isc/tests/netaddr_test.c index 7b5920b6..6a019041 100644 --- a/lib/isc/tests/netaddr_test.c +++ b/lib/isc/tests/netaddr_test.c @@ -3,23 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> -#include <stdlib.h> #include <setjmp.h> - +#include <stdarg.h> #include <stdbool.h> +#include <stddef.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #define UNIT_TESTING @@ -37,24 +34,17 @@ netaddr_isnetzero(void **state) { struct { const char *address; bool expect; - } tests[] = { - { "0.0.0.0", true }, - { "0.0.0.1", true }, - { "0.0.1.2", true }, - { "0.1.2.3", true }, - { "10.0.0.0", false }, - { "10.9.0.0", false }, - { "10.9.8.0", false }, - { "10.9.8.7", false }, - { "127.0.0.0", false }, - { "127.0.0.1", false } - }; + } tests[] = { { "0.0.0.0", true }, { "0.0.0.1", true }, + { "0.0.1.2", true }, { "0.1.2.3", true }, + { "10.0.0.0", false }, { "10.9.0.0", false }, + { "10.9.8.0", false }, { "10.9.8.7", false }, + { "127.0.0.0", false }, { "127.0.0.1", false } }; bool result; isc_netaddr_t netaddr; UNUSED(state); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { ina.s_addr = inet_addr(tests[i].address); isc_netaddr_fromin(&netaddr, &ina); result = isc_netaddr_isnetzero(&netaddr); @@ -92,7 +82,7 @@ netaddr_masktoprefixlen(void **state) { assert_int_equal(plen, 0); assert_int_equal(isc_netaddr_masktoprefixlen(&ina_b, &plen), - ISC_R_SUCCESS); + ISC_R_SUCCESS); assert_int_equal(plen, 31); assert_int_equal(isc_netaddr_masktoprefixlen(&ina_c, &plen), @@ -113,12 +103,9 @@ netaddr_multicast(void **state) { const char *addr; bool is_multicast; } tests[] = { - { AF_INET, "1.2.3.4", false }, - { AF_INET, "4.3.2.1", false }, - { AF_INET, "224.1.1.1", true }, - { AF_INET, "1.1.1.244", false }, - { AF_INET6, "::1", false }, - { AF_INET6, "ff02::1", true } + { AF_INET, "1.2.3.4", false }, { AF_INET, "4.3.2.1", false }, + { AF_INET, "224.1.1.1", true }, { AF_INET, "1.1.1.244", false }, + { AF_INET6, "::1", false }, { AF_INET6, "ff02::1", true } }; UNUSED(state); @@ -167,4 +154,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/parse_test.c b/lib/isc/tests/parse_test.c index b0f232d4..5fe9e013 100644 --- a/lib/isc/tests/parse_test.c +++ b/lib/isc/tests/parse_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,19 +11,17 @@ /*! \file */ -#include <config.h> - #if HAVE_CMOCKA +#include <inttypes.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> -#include <inttypes.h> -#include <unistd.h> #include <time.h> +#include <unistd.h> #define UNIT_TESTING #include <cmocka.h> @@ -76,8 +74,8 @@ parse_overflow(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(parse_overflow, - _setup, _teardown), + cmocka_unit_test_setup_teardown(parse_overflow, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -93,4 +91,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/pool_test.c b/lib/isc/tests/pool_test.c index 2e6c7504..45c3b9c1 100644 --- a/lib/isc/tests/pool_test.c +++ b/lib/isc/tests/pool_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -55,19 +53,20 @@ static isc_result_t poolinit(void **target, void *arg) { isc_result_t result; - isc_taskmgr_t *mgr = (isc_taskmgr_t *) arg; + isc_taskmgr_t *mgr = (isc_taskmgr_t *)arg; isc_task_t *task = NULL; result = isc_task_create(mgr, 0, &task); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } - *target = (void *) task; + *target = (void *)task; return (ISC_R_SUCCESS); } static void poolfree(void **target) { - isc_task_t *task = *(isc_task_t **) target; + isc_task_t *task = *(isc_task_t **)target; isc_task_destroy(&task); *target = NULL; } @@ -80,7 +79,8 @@ create_pool(void **state) { UNUSED(state); - result = isc_pool_create(mctx, 8, poolfree, poolinit, taskmgr, &pool); + result = isc_pool_create(test_mctx, 8, poolfree, poolinit, taskmgr, + &pool); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_pool_count(pool), 8); @@ -96,7 +96,8 @@ expand_pool(void **state) { UNUSED(state); - result = isc_pool_create(mctx, 10, poolfree, poolinit, taskmgr, &pool1); + result = isc_pool_create(test_mctx, 10, poolfree, poolinit, taskmgr, + &pool1); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_pool_count(pool1), 10); @@ -142,21 +143,22 @@ get_objects(void **state) { UNUSED(state); - result = isc_pool_create(mctx, 2, poolfree, poolinit, taskmgr, &pool); + result = isc_pool_create(test_mctx, 2, poolfree, poolinit, taskmgr, + &pool); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_pool_count(pool), 2); item = isc_pool_get(pool); assert_non_null(item); - isc_task_attach((isc_task_t *) item, &task1); + isc_task_attach((isc_task_t *)item, &task1); item = isc_pool_get(pool); assert_non_null(item); - isc_task_attach((isc_task_t *) item, &task2); + isc_task_attach((isc_task_t *)item, &task2); item = isc_pool_get(pool); assert_non_null(item); - isc_task_attach((isc_task_t *) item, &task3); + isc_task_attach((isc_task_t *)item, &task3); isc_task_detach(&task1); isc_task_detach(&task2); @@ -169,12 +171,9 @@ get_objects(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create_pool, - _setup, _teardown), - cmocka_unit_test_setup_teardown(expand_pool, - _setup, _teardown), - cmocka_unit_test_setup_teardown(get_objects, - _setup, _teardown), + cmocka_unit_test_setup_teardown(create_pool, _setup, _teardown), + cmocka_unit_test_setup_teardown(expand_pool, _setup, _teardown), + cmocka_unit_test_setup_teardown(get_objects, _setup, _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -190,4 +189,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/queue_test.c b/lib/isc/tests/queue_test.c deleted file mode 100644 index de10a542..00000000 --- a/lib/isc/tests/queue_test.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include <config.h> - -#if HAVE_CMOCKA - -#include <stdarg.h> -#include <stddef.h> -#include <setjmp.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <time.h> - -#define UNIT_TESTING -#include <cmocka.h> - -#include <isc/queue.h> -#include <isc/util.h> - -#include "isctest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = isc_test_begin(NULL, true, 0); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - isc_test_end(); - - return (0); -} - -typedef struct item item_t; -struct item { - int value; - ISC_QLINK(item_t) qlink; -}; - -typedef ISC_QUEUE(item_t) item_queue_t; - -static void -item_init(item_t *item, int value) { - item->value = value; - ISC_QLINK_INIT(item, qlink); -} - -/* Test UDP sendto/recv (IPv4) */ -static void -queue_valid(void **state) { - item_queue_t queue; - item_t one, two, three, four, five; - item_t *p; - - UNUSED(state); - - ISC_QUEUE_INIT(queue, qlink); - - item_init(&one, 1); - item_init(&two, 2); - item_init(&three, 3); - item_init(&four, 4); - item_init(&five, 5); - - assert_true(ISC_QUEUE_EMPTY(queue)); - - ISC_QUEUE_POP(queue, qlink, p); - assert_null(p); - - assert_false(ISC_QLINK_LINKED(&one, qlink)); - ISC_QUEUE_PUSH(queue, &one, qlink); - assert_true(ISC_QLINK_LINKED(&one, qlink)); - - assert_false(ISC_QUEUE_EMPTY(queue)); - - ISC_QUEUE_POP(queue, qlink, p); - assert_non_null(p); - assert_int_equal(p->value, 1); - assert_true(ISC_QUEUE_EMPTY(queue)); - assert_false(ISC_QLINK_LINKED(p, qlink)); - - ISC_QUEUE_PUSH(queue, p, qlink); - assert_false(ISC_QUEUE_EMPTY(queue)); - assert_true(ISC_QLINK_LINKED(p, qlink)); - - assert_false(ISC_QLINK_LINKED(&two, qlink)); - ISC_QUEUE_PUSH(queue, &two, qlink); - assert_true(ISC_QLINK_LINKED(&two, qlink)); - - assert_false(ISC_QLINK_LINKED(&three, qlink)); - ISC_QUEUE_PUSH(queue, &three, qlink); - assert_true(ISC_QLINK_LINKED(&three, qlink)); - - assert_false(ISC_QLINK_LINKED(&four, qlink)); - ISC_QUEUE_PUSH(queue, &four, qlink); - assert_true(ISC_QLINK_LINKED(&four, qlink)); - - assert_false(ISC_QLINK_LINKED(&five, qlink)); - ISC_QUEUE_PUSH(queue, &five, qlink); - assert_true(ISC_QLINK_LINKED(&five, qlink)); - - /* Test unlink by removing one item from the middle */ - ISC_QUEUE_UNLINK(queue, &three, qlink); - - ISC_QUEUE_POP(queue, qlink, p); - assert_non_null(p); - assert_int_equal(p->value, 1); - - ISC_QUEUE_POP(queue, qlink, p); - assert_non_null(p); - assert_int_equal(p->value, 2); - - ISC_QUEUE_POP(queue, qlink, p); - assert_non_null(p); - assert_int_equal(p->value, 4); - - ISC_QUEUE_POP(queue, qlink, p); - assert_non_null(p); - assert_int_equal(p->value, 5); - - assert_true(ISC_QUEUE_EMPTY(queue)); - - ISC_QUEUE_DESTROY(queue); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(queue_valid, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, NULL, NULL)); -} - -#else /* HAVE_CMOCKA */ - -#include <stdio.h> - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/isc/tests/quota_test.c b/lib/isc/tests/quota_test.c new file mode 100644 index 00000000..36b661c3 --- /dev/null +++ b/lib/isc/tests/quota_test.c @@ -0,0 +1,344 @@ +/* + * 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. + */ + +#if HAVE_CMOCKA + +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define UNIT_TESTING +#include <cmocka.h> + +#include <isc/quota.h> +#include <isc/result.h> +#include <isc/thread.h> +#include <isc/util.h> + +static void +isc_quota_get_set_test(void **state) { + UNUSED(state); + isc_quota_t quota; + isc_quota_t *quota2 = NULL; + isc_quota_init("a, 100); + + assert_int_equal(isc_quota_getmax("a), 100); + assert_int_equal(isc_quota_getsoft("a), 0); + + isc_quota_max("a, 50); + isc_quota_soft("a, 30); + + assert_int_equal(isc_quota_getmax("a), 50); + assert_int_equal(isc_quota_getsoft("a), 30); + + assert_int_equal(isc_quota_getused("a), 0); + isc_quota_attach("a, "a2); + assert_int_equal(isc_quota_getused("a), 1); + isc_quota_detach("a2); + assert_int_equal(isc_quota_getused("a), 0); + isc_quota_destroy("a); +} + +#define add_quota(quota, quotasp, exp, attached, exp_used) \ + { \ + *quotasp = NULL; \ + isc_result_t result = isc_quota_attach(quota, quotasp); \ + assert_int_equal(result, exp); \ + if (attached) { \ + assert_ptr_equal(*quotasp, quota); \ + } else { \ + assert_null(*quotasp); \ + } \ + assert_int_equal(isc_quota_getused(quota), exp_used); \ + } + +static void +isc_quota_hard_test(void **state) { + isc_quota_t quota; + isc_quota_t *quotas[110]; + int i; + UNUSED(state); + + isc_quota_init("a, 100); + + for (i = 0; i < 100; i++) { + add_quota("a, "as[i], ISC_R_SUCCESS, true, i + 1); + } + + add_quota("a, "as[100], ISC_R_QUOTA, false, 100); + + assert_int_equal(isc_quota_getused("a), 100); + + isc_quota_detach("as[0]); + assert_null(quotas[0]); + + add_quota("a, "as[100], ISC_R_SUCCESS, true, 100); + add_quota("a, "as[101], ISC_R_QUOTA, false, 100); + + for (i = 100; i > 0; i--) { + isc_quota_detach("as[i]); + assert_null(quotas[i]); + assert_int_equal(isc_quota_getused("a), i - 1); + } + assert_int_equal(isc_quota_getused("a), 0); + isc_quota_destroy("a); +} + +static void +isc_quota_soft_test(void **state) { + isc_quota_t quota; + isc_quota_t *quotas[110]; + int i; + UNUSED(state); + + isc_quota_init("a, 100); + isc_quota_soft("a, 50); + + for (i = 0; i < 50; i++) { + add_quota("a, "as[i], ISC_R_SUCCESS, true, i + 1); + } + for (i = 50; i < 100; i++) { + add_quota("a, "as[i], ISC_R_SOFTQUOTA, true, i + 1); + } + + add_quota("a, "as[i], ISC_R_QUOTA, false, 100); + + for (i = 99; i >= 0; i--) { + isc_quota_detach("as[i]); + assert_null(quotas[i]); + assert_int_equal(isc_quota_getused("a), i); + } + assert_int_equal(isc_quota_getused("a), 0); + isc_quota_destroy("a); +} + +static atomic_uint_fast32_t cb_calls = ATOMIC_VAR_INIT(0); +static isc_quota_cb_t cbs[30]; +static isc_quota_t *qp; + +static void +callback(isc_quota_t *quota, void *data) { + int val = *(int *)data; + /* Callback is not called if we get the quota directly */ + assert_int_not_equal(val, -1); + + /* We get the proper quota pointer */ + assert_ptr_equal(quota, qp); + + /* Verify that the callbacks are called in order */ + int v = atomic_fetch_add_relaxed(&cb_calls, 1); + assert_int_equal(v, val); + + /* + * First 5 will be detached by the test function, + * for the last 5 - do a 'chain detach'. + */ + if (v >= 5) { + isc_quota_detach("a); + } +} + +static void +isc_quota_callback_test(void **state) { + isc_result_t result; + isc_quota_t quota; + isc_quota_t *quotas[30]; + qp = "a; + /* + * - 10 calls that end with SUCCESS + * - 10 calls that end with SOFTQUOTA + * - 10 callbacks + */ + int ints[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int i; + UNUSED(state); + + isc_quota_init("a, 20); + isc_quota_soft("a, 10); + + for (i = 0; i < 10; i++) { + quotas[i] = NULL; + isc_quota_cb_init(&cbs[i], callback, &ints[i]); + result = isc_quota_attach_cb("a, "as[i], &cbs[i]); + assert_int_equal(result, ISC_R_SUCCESS); + assert_ptr_equal(quotas[i], "a); + assert_int_equal(isc_quota_getused("a), i + 1); + } + for (i = 10; i < 20; i++) { + quotas[i] = NULL; + isc_quota_cb_init(&cbs[i], callback, &ints[i]); + result = isc_quota_attach_cb("a, "as[i], &cbs[i]); + assert_int_equal(result, ISC_R_SOFTQUOTA); + assert_ptr_equal(quotas[i], "a); + assert_int_equal(isc_quota_getused("a), i + 1); + } + + for (i = 20; i < 30; i++) { + quotas[i] = NULL; + isc_quota_cb_init(&cbs[i], callback, &ints[i]); + result = isc_quota_attach_cb("a, "as[i], &cbs[i]); + assert_int_equal(result, ISC_R_QUOTA); + assert_ptr_equal(quotas[i], NULL); + assert_int_equal(isc_quota_getused("a), 20); + } + assert_int_equal(atomic_load(&cb_calls), 0); + + for (i = 0; i < 5; i++) { + isc_quota_detach("as[i]); + assert_null(quotas[i]); + assert_int_equal(isc_quota_getused("a), 20); + assert_int_equal(atomic_load(&cb_calls), i + 1); + } + /* That should cause a chain reaction */ + isc_quota_detach("as[5]); + assert_int_equal(atomic_load(&cb_calls), 10); + + /* Release the quotas that we did not released in the callback */ + for (i = 0; i < 5; i++) { + qp = "a; + isc_quota_detach(&qp); + } + + for (i = 6; i < 20; i++) { + isc_quota_detach("as[i]); + assert_null(quotas[i]); + assert_int_equal(isc_quota_getused("a), 19 - i); + } + assert_int_equal(atomic_load(&cb_calls), 10); + + assert_int_equal(isc_quota_getused("a), 0); + isc_quota_destroy("a); +} + +/* + * Multithreaded quota callback test: + * - quota set to 100 + * - 10 threads, each trying to get 100 quotas. + * - creates a separate thread to release it after 10ms + */ + +typedef struct qthreadinfo { + atomic_uint_fast32_t direct; + atomic_uint_fast32_t callback; + isc_quota_t *quota; + isc_quota_cb_t callbacks[100]; +} qthreadinfo_t; + +static atomic_uint_fast32_t g_tnum = ATOMIC_VAR_INIT(0); +/* at most 10 * 100 quota_detach threads */ +isc_thread_t g_threads[10 * 100]; + +static void * +quota_detach(void *quotap) { + isc_quota_t *quota = (isc_quota_t *)quotap; + usleep(10000); + isc_quota_detach("a); + return ((isc_threadresult_t)0); +} + +static void +quota_callback(isc_quota_t *quota, void *data) { + qthreadinfo_t *qti = (qthreadinfo_t *)data; + atomic_fetch_add_relaxed(&qti->callback, 1); + int tnum = atomic_fetch_add_relaxed(&g_tnum, 1); + isc_thread_create(quota_detach, quota, &g_threads[tnum]); +} + +static isc_threadresult_t +quota_thread(void *qtip) { + qthreadinfo_t *qti = (qthreadinfo_t *)qtip; + for (int i = 0; i < 100; i++) { + isc_quota_cb_init(&qti->callbacks[i], quota_callback, qti); + isc_quota_t *quota = NULL; + isc_result_t result = isc_quota_attach_cb(qti->quota, "a, + &qti->callbacks[i]); + if (result == ISC_R_SUCCESS) { + atomic_fetch_add_relaxed(&qti->direct, 1); + int tnum = atomic_fetch_add_relaxed(&g_tnum, 1); + isc_thread_create(quota_detach, quota, + &g_threads[tnum]); + } + } + return ((isc_threadresult_t)0); +} + +static void +isc_quota_callback_mt_test(void **state) { + UNUSED(state); + isc_quota_t quota; + int i; + + isc_quota_init("a, 100); + static qthreadinfo_t qtis[10]; + isc_thread_t threads[10]; + for (i = 0; i < 10; i++) { + atomic_init(&qtis[i].direct, 0); + atomic_init(&qtis[i].callback, 0); + qtis[i].quota = "a; + isc_thread_create(quota_thread, &qtis[i], &threads[i]); + } + for (i = 0; i < 10; i++) { + isc_thread_join(threads[i], NULL); + } + + for (i = 0; i < (int)atomic_load(&g_tnum); i++) { + isc_thread_join(g_threads[i], NULL); + } + int direct = 0, callback = 0; + + for (i = 0; i < 10; i++) { + direct += atomic_load(&qtis[i].direct); + callback += atomic_load(&qtis[i].callback); + } + /* Total quota gained must be 10 threads * 100 tries */ + assert_int_equal(direct + callback, 10 * 100); + /* + * At least 100 must be direct, the rest is virtually random: + * - in a regular run I'm constantly getting 100:900 ratio + * - under rr - usually around ~120:880 + * - under rr -h - 1000:0 + */ + assert_true(direct >= 100); + + isc_quota_destroy("a); +} + +int +main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(isc_quota_get_set_test), + cmocka_unit_test(isc_quota_hard_test), + cmocka_unit_test(isc_quota_soft_test), + cmocka_unit_test(isc_quota_callback_test), + cmocka_unit_test(isc_quota_callback_mt_test), + }; + + return (cmocka_run_group_tests(tests, NULL, NULL)); +} + +#else /* HAVE_CMOCKA */ + +#include <stdio.h> + +int +main(void) { + printf("1..0 # Skipped: cmocka not available\n"); + return (0); +} + +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/radix_test.c b/lib/isc/tests/radix_test.c index b17391ef..8f273410 100644 --- a/lib/isc/tests/radix_test.c +++ b/lib/isc/tests/radix_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> @@ -64,7 +62,7 @@ isc_radix_search_test(void **state) { UNUSED(state); - result = isc_radix_create(mctx, &radix, 32); + result = isc_radix_create(test_mctx, &radix, 32); assert_int_equal(result, ISC_R_SUCCESS); in_addr.s_addr = inet_addr("3.3.3.0"); @@ -104,8 +102,8 @@ isc_radix_search_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_radix_search_test, - _setup, _teardown), + cmocka_unit_test_setup_teardown(isc_radix_search_test, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -121,4 +119,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/random_test.c b/lib/isc/tests/random_test.c index f60422fb..4b6b6439 100644 --- a/lib/isc/tests/random_test.c +++ b/lib/isc/tests/random_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -16,16 +16,14 @@ * random. The test is expected to fail on occasion by random happenstance. */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> -#include <setjmp.h> - #include <inttypes.h> #include <math.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> @@ -40,10 +38,11 @@ #include <isc/result.h> #include <isc/util.h> +#include "isctest.h" + #define REPS 25000 -typedef double (pvalue_func_t)(isc_mem_t *mctx, - uint16_t *values, size_t length); +typedef double(pvalue_func_t)(isc_mem_t *mctx, uint16_t *values, size_t length); /* igamc(), igam(), etc. were adapted (and cleaned up) from the Cephes * math library: @@ -53,15 +52,17 @@ typedef double (pvalue_func_t)(isc_mem_t *mctx, * * The Cephes math library was released into the public domain as part * of netlib. -*/ + */ static double MACHEP = 1.11022302462515654042E-16; static double MAXLOG = 7.09782712893383996843E2; static double big = 4.503599627370496e15; -static double biginv = 2.22044604925031308085e-16; +static double biginv = 2.22044604925031308085e-16; -static double igamc(double a, double x); -static double igam(double a, double x); +static double +igamc(double a, double x); +static double +igam(double a, double x); /* Set to true (or use -v option) for verbose output */ static bool verbose = false; @@ -75,16 +76,39 @@ typedef enum { ISC_NONCE_BYTES } isc_random_func; +static int +_setup(void **state) { + isc_result_t result; + + UNUSED(state); + + result = isc_test_begin(NULL, true, 0); + assert_int_equal(result, ISC_R_SUCCESS); + + return (0); +} + +static int +_teardown(void **state) { + UNUSED(state); + + isc_test_end(); + + return (0); +} + static double igamc(double a, double x) { double ans, ax, c, yc, r, t, y, z; double pk, pkm1, pkm2, qk, qkm1, qkm2; - if ((x <= 0) || (a <= 0)) + if ((x <= 0) || (a <= 0)) { return (1.0); + } - if ((x < 1.0) || (x < a)) + if ((x < 1.0) || (x < a)) { return (1.0 - igam(a, x)); + } ax = a * log(x) - x - lgamma(a); if (ax < -MAXLOG) { @@ -108,14 +132,15 @@ igamc(double a, double x) { y += 1.0; z += 2.0; yc = y * c; - pk = pkm1 * z - pkm2 * yc; - qk = qkm1 * z - qkm2 * yc; + pk = pkm1 * z - pkm2 * yc; + qk = qkm1 * z - qkm2 * yc; if (qk != 0) { r = pk / qk; t = fabs((ans - r) / r); ans = r; - } else + } else { t = 1.0; + } pkm2 = pkm1; pkm1 = pk; @@ -137,15 +162,17 @@ static double igam(double a, double x) { double ans, ax, c, r; - if ((x <= 0) || (a <= 0)) + if ((x <= 0) || (a <= 0)) { return (0.0); + } - if ((x > 1.0) && (x > a)) + if ((x > 1.0) && (x > a)) { return (1.0 - igamc(a, x)); + } /* Compute x**a * exp(-x) / md_gamma(a) */ ax = a * log(x) - x - lgamma(a); - if (ax < -MAXLOG ) { + if (ax < -MAXLOG) { print_error("# igam: UNDERFLOW, ax=%f\n", ax); return (0.0); } @@ -178,10 +205,11 @@ scount_calculate(uint16_t n) { uint16_t lsb; lsb = n & 1; - if (lsb != 0) + if (lsb != 0) { sc += 1; - else + } else { sc -= 1; + } n >>= 1; } @@ -199,8 +227,9 @@ bitcount_calculate(uint16_t n) { uint16_t lsb; lsb = n & 1; - if (lsb != 0) + if (lsb != 0) { bc += 1; + } n >>= 1; } @@ -238,9 +267,9 @@ matrix_binaryrank(uint32_t *bits, size_t rows, size_t cols) { while (rt >= cols || ((bits[i] >> rt) & 1) == 0) { i++; - if (i < rows) + if (i < rows) { continue; - else { + } else { rt++; if (rt < cols) { i = k; @@ -259,10 +288,11 @@ matrix_binaryrank(uint32_t *bits, size_t rows, size_t cols) { } for (j = i + 1; j < rows; j++) { - if (((bits[j] >> rt) & 1) == 0) + if (((bits[j] >> rt) & 1) == 0) { continue; - else + } else { bits[j] ^= bits[k]; + } } rt++; @@ -273,8 +303,6 @@ matrix_binaryrank(uint32_t *bits, size_t rows, size_t cols) { static void random_test(pvalue_func_t *func, isc_random_func test_func) { - isc_mem_t *mctx = NULL; - isc_result_t result; uint32_t m; uint32_t j; uint32_t histogram[11] = { 0 }; @@ -288,9 +316,6 @@ random_test(pvalue_func_t *func, isc_random_func test_func) { tables_init(); - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); - m = 1000; passed = 0; @@ -325,9 +350,8 @@ random_test(pvalue_func_t *func, isc_random_func test_func) { case ISC_RANDOM_UNIFORM: uniform_values = (uint16_t *)values; for (i = 0; - i < (sizeof(values) / sizeof(*uniform_values)); - i++) - { + i < (sizeof(values) / (sizeof(*uniform_values))); + i++) { uniform_values[i] = isc_random_uniform(UINT16_MAX); } @@ -337,14 +361,14 @@ random_test(pvalue_func_t *func, isc_random_func test_func) { break; } - p_value = (*func)(mctx, (uint16_t *)values, REPS * 2); + p_value = (*func)(test_mctx, (uint16_t *)values, REPS * 2); if (p_value >= 0.01) { passed++; } assert_in_range(p_value, 0.0, 1.0); - i = (int) floor(p_value * 10); + i = (int)floor(p_value * 10); histogram[i]++; } @@ -353,7 +377,7 @@ random_test(pvalue_func_t *func, isc_random_func test_func) { * 4.2.1 in NIST SP 800-22). */ alpha = 0.01; /* the significance level */ - proportion = (double) passed / (double) m; + proportion = (double)passed / (double)m; p_hat = 1.0 - alpha; lower_confidence = p_hat - (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m)); higher_confidence = p_hat + (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m)); @@ -426,8 +450,9 @@ monobit(isc_mem_t *mctx, uint16_t *values, size_t length) { numbits = length * sizeof(*values) * 8; scount = 0; - for (i = 0; i < length; i++) + for (i = 0; i < length; i++) { scount += scounts_table[values[i]]; + } /* Preconditions (section 2.1.7 in NIST SP 800-22) */ assert_true(numbits >= 100); @@ -466,14 +491,15 @@ runs(isc_mem_t *mctx, uint16_t *values, size_t length) { numbits = length * sizeof(*values) * 8; bcount = 0; - for (i = 0; i < length; i++) + for (i = 0; i < length; i++) { bcount += bitcounts_table[values[i]]; + } if (verbose) { print_message("# numbits=%u, bcount=%u\n", numbits, bcount); } - pi = (double) bcount / (double) numbits; + pi = (double)bcount / (double)numbits; tau = 2.0 / sqrt(numbits); /* Preconditions (section 2.3.7 in NIST SP 800-22) */ @@ -484,8 +510,9 @@ runs(isc_mem_t *mctx, uint16_t *values, size_t length) { * for some sequences, and the p-value is taken as 0 in these * cases. */ - if (fabs(pi - 0.5) >= tau) + if (fabs(pi - 0.5) >= tau) { return (0.0); + } /* Compute v_obs */ j = 0; @@ -545,7 +572,7 @@ blockfrequency(isc_mem_t *mctx, uint16_t *values, size_t length) { /* Preconditions (section 2.2.7 in NIST SP 800-22) */ assert_true(numbits >= 100); assert_true(mbits >= 20); - assert_true((double) mbits > (0.01 * numbits)); + assert_true((double)mbits > (0.01 * numbits)); assert_true(numblocks < 100); assert_true(numbits >= (mbits * numblocks)); @@ -566,8 +593,9 @@ blockfrequency(isc_mem_t *mctx, uint16_t *values, size_t length) { /* Compute chi_square */ chi_square = 0.0; - for (i = 0; i < numblocks; i++) + for (i = 0; i < numblocks; i++) { chi_square += (pi[i] - 0.5) * (pi[i] - 0.5); + } chi_square *= 4 * mbits; @@ -641,21 +669,25 @@ binarymatrixrank(isc_mem_t *mctx, uint16_t *values, size_t length) { rank = matrix_binaryrank(bits, matrix_m, matrix_q); - if (rank == matrix_m) + if (rank == matrix_m) { fm_0++; - else if (rank == (matrix_m - 1)) + } else if (rank == (matrix_m - 1)) { fm_1++; - else + } else { fm_rest++; + } } /* Compute chi_square */ term1 = ((fm_0 - (0.2888 * num_matrices)) * - (fm_0 - (0.2888 * num_matrices))) / (0.2888 * num_matrices); + (fm_0 - (0.2888 * num_matrices))) / + (0.2888 * num_matrices); term2 = ((fm_1 - (0.5776 * num_matrices)) * - (fm_1 - (0.5776 * num_matrices))) / (0.5776 * num_matrices); + (fm_1 - (0.5776 * num_matrices))) / + (0.5776 * num_matrices); term3 = ((fm_rest - (0.1336 * num_matrices)) * - (fm_rest - (0.1336 * num_matrices))) / (0.1336 * num_matrices); + (fm_rest - (0.1336 * num_matrices))) / + (0.1336 * num_matrices); chi_square = term1 + term2 + term3; @@ -741,7 +773,6 @@ isc_random_bytes_binarymatrixrank(void **state) { random_test(binarymatrixrank, ISC_RANDOM_BYTES); } - /*** *** Tests for isc_random_uniform() function: ***/ @@ -844,7 +875,7 @@ main(int argc, char **argv) { } } - return (cmocka_run_group_tests(tests, NULL, NULL)); + return (cmocka_run_group_tests(tests, _setup, _teardown)); } #else /* HAVE_CMOCKA */ @@ -857,4 +888,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/regex_test.c b/lib/isc/tests/regex_test.c index 86e9439c..7fe4bcb2 100644 --- a/lib/isc/tests/regex_test.c +++ b/lib/isc/tests/regex_test.c @@ -3,35 +3,32 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#define UNIT_TESTING -#include <cmocka.h> - #ifdef HAVE_REGEX_H #include <regex.h> -#endif +#endif /* ifdef HAVE_REGEX_H */ + +#define UNIT_TESTING +#include <cmocka.h> #include <isc/commandline.h> -#include <isc/regex.h> #include <isc/print.h> +#include <isc/regex.h> #include <isc/util.h> /* Set to true (or use -v option) for verbose output */ @@ -47,7 +44,8 @@ regex_validate(void **state) { struct { const char *expression; int expect; - int exception; /* regcomp accepts but is disallowed. */ + int exception; /* regcomp accepts but is + * disallowed. */ } tests[] = { { "", -1, 0 }, { "*", -1, 0 }, @@ -138,832 +136,2009 @@ regex_validate(void **state) { { "(a)\\1", 1, 0 }, { "(a)\\2", -1, 1 }, { "\\0", 0, 0 }, - { "[[][:g(\?(raph:][:alnu)(\?{m:][:space:]h]<Z3})AAA)S[:space:]{176,}", 0, 0 }, - { "(()IIIIIIII(III[[[[[[[[[[[[[[[[[[^[[[[[[[[ [^ fX][:ascii:].)N[:a(\?<!lpha:])][:punct:]e*y+)a{-124,223}", 3, 0 }, - { "(pP\\\\\\(\?<!\\\\\\\\\\\\\\\\\\\\\\lRRRRRRRRRRRRRRRRBBBBBBBBBBBBBBBB))kkkkkkkkkkkkkkkkkkkkk|^", 1, 0 }, - { "[^[^[{111}(\?=(\?:(\?>/r(\?<(\?=!(\?(\?!<!Q(\?:=0_{Meqipm`(\?((\?{x|N)))))|))+]+]Z)O{,-215}])}))___________________{}", 0, 0 }, - { "[C{,-218(\?=}E^< ]PP-Ga)t``````````````````````````{138}", 0, 0 }, + { "[[][:g(\?(raph:][:alnu)(\?{m:][:space:]h]<Z3})AAA)S[:space:]" + "{176,}", + 0, 0 }, + { "(()IIIIIIII(III[[[[[[[[[[[[[[[[[[^[[[[[[[[ [^ " + " " + "fX][:ascii:].)N[:a(\?<!lpha:])][:punct:]e*y+)a{-124,223}", + 3, 0 }, + { "(pP\\\\\\(\?<!" + "\\\\\\\\\\\\\\\\\\\\\\lRRRRRRRRRRRRRRRRBBBBBBBBBBBBBBBB))" + "kkkkkkkkkkkkkkkkkkkkk|^", + 1, 0 }, + { "[^[^[{111}(\?=(\?:(\?>/" + "r(\?<(\?=!(\?(\?!<!Q(\?:=0_{Meqipm`(\?((\?{x|N)))))|))+]+]Z)" + "O{,-215}])}))___________________{}", + 0, 0 }, + { "[C{,-218(\?=}E^< ]PP-Ga)t``````````````````````````{138}", 0, + 0 }, { "[^h(\?<!(\?>Nn(\?#])))", 0, 0 }, { "[(\?!(\?<=[^{,37}AAAA(AAAAAAAAAAAAA])", 0, 0 }, - { "[^((\?(\?:ms(\?<!xims:A{}(\?{*</H(\?=xL $(\?<!,[})))*)qqqqqqqqqqqqqqqqqq)]33333333333333333333333333333{[:graph:]p)-+( oqD]){-10,}-{247}_______________________X-e[:alpha:][:upperword:]_(______wwwwwwwww /c[:upperword:][:alnum:][:alnum:][:pun(\?{ct:])[:blankcntrl:]})*_*", 2, 0 }, - { "[(\?<!:lowerprin(\?{t:]{}}){113,})[:punct:]IIIIIIIIIIIIIIIIIIIIIIII", 0, 0 }, + { "[^((\?(\?:ms(\?<!xims:A{}(\?{*</H(\?=xL " + "$(\?<!,[})))*)qqqqqqqqqqqqqqqqqq)]" + "33333333333333333333333333333{[:graph:]p)-+( " + "oqD]){-10,}-{247}_______________________X-e[:alpha:][:" + "upperword:]_(______wwwwwwwww " + "/c[:upperword:][:alnum:][:alnum:][:pun(\?{ct:])[:blankcntrl:" + "]})*_*", + 2, 0 }, + { "[(\?<!:lowerprin(\?{t:]{}}){113,})[:punct:]" + "IIIIIIIIIIIIIIIIIIIIIIII", + 0, 0 }, { "PP)", 0, 0 }, - { "(([^(\?<!((\?>\?=[])p.]}8X[:blankcntrl:],{-119,94})XmF1.{)-)[:upperword:])[:digit:]{zg-q", 2, 0 }, - { "[^[({(\?#254}))Z[l][x50]=444444444444(4444444444u[:punct:]\?[:punct:(\?!])])", 1, 0 }, + { "(([^(\?<!((\?>\?=[])p.]}8X[:blankcntrl:],{-119,94})XmF1.{)-)" + "[:upperword:])[:digit:]{zg-q", + 2, 0 }, + { "[^[({(\?#254}))Z[l][x50]=444444444444(4444444444u[:punct:]" + "\?[:punct:(\?!])])", + 1, 0 }, { "[^[^[^([^((*4[(^((\?<=])Ec)", 0, 0 }, { "(0)Y:8biiiiiiiiiiiiiiiiiii", 1, 0 }, - { "[^w(\?!)P::::::::::::::(\?#::(\?<=:::::::::]\"\"{}[3333333333333333(\?<=33333(\?!)9Xja][:alph(\?<=a:])xB1)(PX8Cf\?4444)qq[:digit:])", 1, 0 }, + { "[^w(\?!)P::::::::::::::(\?#::(\?<=:::::::::]\"\"{}[" + "3333333333333333(\?<=33333(\?!)9Xja][:alph(\?<=a:])xB1)(" + "PX8Cf\?4444)qq[:digit:])", + 1, 0 }, { "([U[^[^].]^m]/306KS7JJJJJJJJ{})", 1, 0 }, - { "[^[^([^[(\?!(\?>8j`Wg2(\?{,(\?>!#N++++(\?<![++++++)+44444444bA:K(\?<!O3([:digit:]3]}}}}}}}}}}}}}}}}}}}}}}}}LP})S", 0, 0 }, + { "[^[^([^[(\?!(\?>8j`Wg2(\?{,(\?>!#N++++(\?<![++++++)+" + "44444444bA:K(\?<!O3([:digit:]3]}}}}}}}}}}}}}}}}}}}}}}}}LP})" + "S", + 0, 0 }, { "[({(\?{,(\?(=213}*))})]WWWWWWWWWWWWWWW[:alnum:])", 0, 0 }, { "[:(\?<=ascii:])", 0, 0 }, { "[U(\?#)(\?<=+HzE])[:punct:]{-207,170}\?s.!", 0, 0 }, - { "{}z=jU75~n#soD\"&\?UL`X{xxxxxxxxxxxxxxxxxxxx(xxxxxx${-246,27}[:graph:]g\"{_bX)[:alnum:][:punct:]{-79,}-", 1, 0 }, - { "[^{,-186}@@@@[^(\?{@@(\?>@+(\?>l.]}))*\\BCYX]^W{52,123}(lXislccccccccccccccccc)-*)", 1, 0 }, + { "{}z=jU75~n#soD\"&\?UL`X{xxxxxxxxxxxxxxxxxxxx(xxxxxx${-246," + "27}[:graph:]g\"{_bX)[:alnum:][:punct:]{-79,}-", + 1, 0 }, + { "[^{,-186}@@@@[^(\?{@@(\?>@+(\?>l.]}))*\\BCYX]^W{52,123}(" + "lXislccccccccccccccccc)-*)", + 1, 0 }, { "(x42+,)7=]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", 1, 0 }, { "[^(*[:graph:]q/TH\?B(\?{P)]})uZn[:digit:]+2", 0, 0 }, - { "([XXXXXXXXXXXXXXXXXXXXX[(:alnum:][:space:]i%[:upperw(\?=o(\?#rd:])) ", 1, 0 }, + { "([XXXXXXXXXXXXXXXXXXXXX[(:alnum:][:space:]i%[:upperw(\?=o(" + "\?#rd:])) ", + 1, 0 }, { "(@@@@)", 1, 0 }, - { "{-18,}[:as[(\?>^[cii:]]{}>+{-46,}{,95}[:punct:]{}99999999999999])-{-134}'sK$wCKjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj", 0, 0 }, + { "{-18,}[:as[(\?>^[cii:]]{}>+{-46,}{,95}[:punct:]{}" + "99999999999999])-{-134}'sK$" + "wCKjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj", + 0, 0 }, { "(l[:alpha:(\?!]))", 1, 0 }, - { "[[^(\?{]|JJ[:alph(a:]X{})B^][:lowerprint:]n-219{-32}{19,105}k4P}){,-144}", 0, 0 }, - { "[[^]P[:punct:][:alpha:][:xdigit:]syh]|W#JS*(m<2,P-RK)cA@", 1, 0 }, + { "[[^(\?{]|JJ[:alph(a:]X{})B^][:lowerprint:]n-219{-32}{19,105}" + "k4P}){,-144}", + 0, 0 }, + { "[[^]P[:punct:][:alpha:][:xdigit:]syh]|W#JS*(m<2,P-RK)cA@", 1, + 0 }, { "([^((\?({\?<=)}){[^}^]{}])^P4[:punct:[]$)]", 1, 0 }, - { "([(\?#:(\?{space:]}):{}{-242,}n)F[:alpha:]3$)d4H3up6qS[:blankcntrl:]B:C{}[:upperword:]r", 1, 0 }, + { "([(\?#:(\?{space:]}):{}{-242,}n)F[:alpha:]3$)d4H3up6qS[:" + "blankcntrl:]B:C{}[:upperword:]r", + 1, 0 }, { "([(\?:]))[:digit:]mLV.{}", 1, 0 }, { "[^PPP-[]{[,50}{128,}]111111111111111]p", 0, 0 }, - { "[^([^([^([[^[([^[^[[2[[[[[[[[[[[[[^[[[[(\?(\?{:[[[[[[(\?([-[:ascii:]--*)", -1, 0 }, + { "[^([^([^([[^[([^[^[[2[[[[[[[[[[[[[^[[[[(\?(\?{:[[[[[[(\?([-[" + ":ascii:]--*)", + -1, 0 }, { ")!F^DA/ZZZZZZZZZZZZZZZZZZ", 0, 0 }, - { "[[[[[[[((\?=\?(\?>([[[[[[[^[[[[(\?()[[[K(\?#))])))]7Y[:space:]{,-96}pP)[:ascii:]u{-88}:N{-251}uo", 0, 0 }, + { "[[[[[[[((\?=\?(\?>([[[[[[[^[[[[(\?()[[[K(\?#))])))]7Y[:" + "space:]{,-96}pP)[:ascii:]u{-88}:N{-251}uo", + 0, 0 }, { "t[:x(\?<=digit:])eYYYYYYYYYYYYYYYYYY{,-220}A", 0, 0 }, - { "[[({10,}[:graph:]Pdddddd(\?#X)])[:alnum:(]]L-C){,50}[:blankcntrl:]p[:gra(ph:]){66,}", 0, 0 }, - { "[^[^]*4br]w[:digit(\?::]n99999999999999999)P[:punct:]pP", 0, 0 }, + { "[[({10,}[:graph:]Pdddddd(\?#X)])[:alnum:(]]L-C){,50}[:" + "blankcntrl:]p[:gra(ph:]){66,}", + 0, 0 }, + { "[^[^]*4br]w[:digit(\?::]n99999999999999999)P[:punct:]pP", 0, + 0 }, { "[:digit:]{67,247}!N{122})VrXe", 0, 0 }, - { "[:xdigit:]^[:xdigit:]Z[:alnum:]^^^^1[:upperword:(\?=])[:lowerprint:]*JJ-", 0, 0 }, - { "[[(\?imsximsx:^*e(){,3[6}](V~\?^[:asc(\?!ii:]I.dZ))]$^AAAAAAAAAAAAAAAAAAAAAAAA[:space:]k)]", 1, 0 }, - { "W{,112}[:lowerp(\?<!rint:]$#GT>R7~t'\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"9,O).", 0, 0 }, - { "[^{6((\?>\?:4}(\?<=G))f)KKKKKKKKKKKKKKKKKKKKKKKKKKKKKpppppppp(\?=ppppp]{,-101}|[:blankcntrl:]Z{-182})", 0, 0 }, - { "([:punct:]@^,,,,,,,,,,,,,,,,,,,,,,,,,,0\?:-o8NPIIIIIIIII)pPKKKKKKKKKKKKKKKKKKKK", 1, 0 }, + { "[:xdigit:]^[:xdigit:]Z[:alnum:]^^^^1[:upperword:(\?=])[:" + "lowerprint:]*JJ-", + 0, 0 }, + { "[[(\?imsximsx:^*e(){,3[6}](V~\?^[:asc(\?!ii:]I.dZ))]$^" + "AAAAAAAAAAAAAAAAAAAAAAAA[:space:]k)]", + 1, 0 }, + { "W{,112}[:lowerp(\?<!rint:]$#GT>R7~t'" + "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"9,O).", + 0, 0 }, + { "[^{6((\?>\?:4}(\?<=G))f)" + "KKKKKKKKKKKKKKKKKKKKKKKKKKKKKpppppppp(\?=ppppp]{,-101}|[:" + "blankcntrl:]Z{-182})", + 0, 0 }, + { "([:punct:]@^,,,,,,,,,,,,,,,,,,,,,,,,,,0\?:-o8NPIIIIIIIII)" + "pPKKKKKKKKKKKKKKKKKKKK", + 1, 0 }, { "([^[[^[^]]]])", 1, 0 }, { "[([^[(333\"(\?#\\\\[)(\?isx-x:\"Tx]')", 0, 0 }, - { "[[n>^>T%.zzzzzzzzzzzzzzzzz$&|Fk.1o7^o, ^8{202,-12}$[:alnum:]]G[:upperword:]V[:xdigit:]L|[:upperword:]KKKKKKKKKKKKYX\"\")xJ ~B@[{,-68}/][:upperword:]QI.", 0, 0 }, - { "[^[]tN^hy3\"d@v T[GE\?^~{124,10(\?{2}]})\?[:upperword:]O", 0, 0 }, - { "d.``````````````````````````[:up(\?=perword:]RRRRRRRRRRRRRRR)", 0, 0 }, - { "[Z{{{{{{{{{{{{{(\?={(\?<!{{{{{{{{{(\?>{{J6N:H[tA+mN3Zmf:p\?]\?){-181,82}S4n.b[:lowerpri(\?{nt:]|ggggggggggggggggggggggggggggggg}))4)", 0, 0 }, - { "[^((/////[^////[^/////////[(^/////]fI{240}{-120}+]R]GA)", 0, 0 }, + { "[[n>^>T%.zzzzzzzzzzzzzzzzz$&|Fk.1o7^o, " + "^8{202,-12}$[:alnum:]]G[:upperword:]V[:xdigit:]L|[:" + "upperword:]KKKKKKKKKKKKYX\"\")xJ " + "~B@[{,-68}/][:upperword:]QI.", + 0, 0 }, + { "[^[]tN^hy3\"d@v T[GE\?^~{124,10(\?{2}]})\?[:upperword:]O", 0, + 0 }, + { "d.``````````````````````````[:up(\?=perword:]" + "RRRRRRRRRRRRRRR)", + 0, 0 }, + { "[Z{{{{{{{{{{{{{(\?={(\?<!{{{{{{{{{(\?>{{J6N:H[tA+mN3Zmf:p\?]" + "\?){-181,82}S4n.b[:lowerpri(\?{nt:]|" + "ggggggggggggggggggggggggggggggg}))4)", + 0, 0 }, + { "[^((/////[^////[^/////////[(^/////]fI{240}{-120}+]R]GA)", 0, + 0 }, { "[-(\?#.)(\?())[:alpha:](\?={(\?#}r)[:space:]PPW]o)", 0, 0 }, - { "[:lowerp(\?{rint:]})201{46,}[:a[^scii:]0Q{37,}][:blankcntrl:]1331", 0, 0 }, + { "[:lowerp(\?{rint:]})201{46,}[:a[^scii:]0Q{37,}][:blankcntrl:" + "]1331", + 0, 0 }, { "[^(\?!(\?#)\\GIwxKKKKKKKKKK'$KKKKKKKK]l)bbb^&\?", 0, 0 }, { "[:ascii:]*[:sp(\?<=ace:])", 0, 0 }, { "({-66,}Z{})0I{-111,}[:punct(\?():])", 1, 0 }, - { "[[^(\?!()%%%%%%%%%%%%%(\?:%%%%%%%%%%%%%%%%)t(\?{VX>B#6sUU(\?<!UUUUUU(\?=UUU[^UUUUUUUUUUUU(\?((\?:UPPPPPPPPPPP)PPPPPPPPPPPPPPP]ffffffffffffffffffffffff)^[:space:]wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww{243}9[:lowerprint:]Dv[:graph:])][:blankcntrl:]V%E[:graph:]})[:space:]{-83,}cQZ{}4{-23,135}", 0, 0 }, - { "({,-76[}]O[:xdi(\?<!git:])\?5))))))))\?d[:lowerprint:]b666666[:graph:]c", 1, 0 }, + { "[[^(\?!()%%%%%%%%%%%%%(\?:%%%%%%%%%%%%%%%%)t(\?{VX>B#6sUU(" + "\?<!UUUUUU(\?=UUU[^UUUUUUUUUUUU(\?((\?:UPPPPPPPPPPP)" + "PPPPPPPPPPPPPPP]ffffffffffffffffffffffff)^[:space:]" + "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww{243}9[:lowerprint:]Dv[:" + "graph:])][:blankcntrl:]V%E[:graph:]})[:space:]{-83,}cQZ{}4{-" + "23,135}", + 0, 0 }, + { "({,-76[}]O[:xdi(\?<!git:])\?5))))))))\?d[:lowerprint:]" + "b666666[:graph:]c", + 1, 0 }, { "{}{-145,}[:(\?(spa)ce:])f", 0, 0 }, - { "[([^].{116,243}]T*[[^:punct(\?[{[^:(\?<!]]8()])[:alnum:])})]N{}{,243}*[n]][:graph:]", 1, 0 }, - { "[^w]8888888888888888_________(__________[:ascii:]BdqTE$^0|MNto*i#############[^#################])", 1, 0 }, - { "[^[[[<[()\?]GGG{,26[}[:alnum:]SSSSS.gggggggg[:graph:]CCCCCCCCCCC{79,}{138,191}][:di(git:]u]@]JJJJJJJJJJJJJJJJJJJJJJJ[:graph:(\?:][:alnum:]])[:alnum:])]", 0, 0 }, - { "[^(((BBBBBBBBBB(\?>BBBZvvvvvvvvvv(\?m(sximsx:vvv)iiiiiiii)))j>Rs:Sm]0MMMMMMMMMMM|@F)Y]*^#EEEEEEE)*", 0, 0 }, - { "([^([(U(\?!)<<<<<<<<<<(\?#<<<<(\?<!<<<)(\?=L.{73,})+]n9U}fk%Jn}'b Na<%yyyyyyyyyyyy)){-198,}]))[:space:].pP361U]3s@u_9AU Te/{s`6=IMZdL1|.ySRo", 1, 0 }, + { "[([^].{116,243}]T*[[^:punct(\?[{[^:(\?<!]]8()])[:alnum:])})]" + "N{}{,243}*[n]][:graph:]", + 1, 0 }, + { "[^w]8888888888888888_________(__________[:ascii:]BdqTE$^0|" + "MNto*i#############[^#################])", + 1, 0 }, + { "[^[[[<[()\?]GGG{,26[}[:alnum:]SSSSS.gggggggg[:graph:]" + "CCCCCCCCCCC{79,}{138,191}][:di(git:]u]@]" + "JJJJJJJJJJJJJJJJJJJJJJJ[:graph:(\?:][:alnum:]])[:alnum:])]", + 0, 0 }, + { "[^(((BBBBBBBBBB(\?>BBBZvvvvvvvvvv(\?m(sximsx:vvv)iiiiiiii)))" + "j>Rs:Sm]0MMMMMMMMMMM|@F)Y]*^#EEEEEEE)*", + 0, 0 }, + { "([^([(U(\?!)<<<<<<<<<<(\?#<<<<(\?<!<<<)(\?=L.{73,})+]n9U}fk%" + "Jn}'b Na<%yyyyyyyyyyyy)){-198,}]))[:space:].pP361U]3s@u_9AU " + "Te/{s`6=IMZdL1|.ySRo", + 1, 0 }, { "[[((\?<=\?>(\?#){}]{}`){1,82}){-143[,}]^G", 0, 0 }, - { "[:digit:]W|[:up(\?<!perword:]{,-101}llllllllllllllllll[:upperword:])mmYYYYYYYYYYYYYYYYYYYYYYY*", 0, 0 }, + { "[:digit:]W|[:up(\?<!perword:]{,-101}llllllllllllllllll[:" + "upperword:])mmYYYYYYYYYYYYYYYYYYYYYYY*", + 0, 0 }, { "@NHy)", 0, 0 }, - { "([^[^]][:alnum:]222[^22222222(\?{2222222222222222][:lo(\?:werprint:][:xdigit:]^[:blankcntrl:]s+N)[:alpha:]-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWxxxxxxxxxxxxxxxxxxxxxxxxxxD[:space:]U)TTTTTTTTTTfffffffffffzzzzzzzzzzzzzzzzzzzzzzzzz})", 1, 0 }, - { "[^[^[[^[][^[]pP([^\?[^<=(\?=]){158,})]]]][:digit:]]K22222222222p^dUKJ`\">@]", 1, 0 }, - { "[^[^[(\?imsximsx::p(\?{unct:][(\?>:ascii:]5w)]{159}\\Q\?@C]4(44444444}[^)|)[:graph:]]C:b)", 1, 0 }, - { "[^[[(tYri[W<8%1(\?='yt][:lowerprint:[]))1r]][:alnum:][:digit:]{48}{-52,-183}+][:alpha:]r][:upperword:]\?{-105,155}{-55,-87}pPN#############################{63,232}]", 0, 0 }, - { "[*(\?>L(\?<(\?>=))]&&&&&&&(&&&&&&&&&&&&&&&&&&))[|WIX]{-62,-114}S K=HW60XE<2+W", 1, 0 }, + { "([^[^]][:alnum:]222[^22222222(\?{2222222222222222][:lo(\?:" + "werprint:][:xdigit:]^[:blankcntrl:]s+N)[:alpha:]-" + "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWxxxxxxxxxxxxxxxxxxxxxxxxxxD[" + ":space:]U)TTTTTTTTTTfffffffffffzzzzzzzzzzzzzzzzzzzzzzzzz})", + 1, 0 }, + { "[^[^[[^[][^[]pP([^\?[^<=(\?=]){158,})]]]][:digit:]]" + "K22222222222p^dUKJ`\">@]", + 1, 0 }, + { "[^[^[(\?imsximsx::p(\?{unct:][(\?>:ascii:]5w)]{159}\\Q\?@C]" + "4(44444444}[^)|)[:graph:]]C:b)", + 1, 0 }, + { "[^[[(tYri[W<8%1(\?='yt][:lowerprint:[]))1r]][:alnum:][:" + "digit:]{48}{-52,-183}+][:alpha:]r][:upperword:]\?{-105,155}{" + "-55,-87}pPN#############################{63,232}]", + 0, 0 }, + { "[*(\?>L(\?<(\?>=))]&&&&&&&(&&&&&&&&&&&&&&&&&&))[|WIX]{-62,-" + "114}S K=HW60XE<2+W", + 1, 0 }, { "(00000000000)z\\\\*t{}R{88}[:alnum:]*", 1, 0 }, - { "(([^(\?=\?gggggg[gLw)]{-250,}[:xdigit:]yZ[:g(raph:]8QNr[:space:][:blankcntrl:]A)][:digit:]D)[:xdigit:])", 2, 0 }, + { "(([^(\?=\?gggggg[gLw)]{-250,}[:xdigit:]yZ[:g(raph:]8QNr[:" + "space:][:blankcntrl:]A)][:digit:]D)[:xdigit:])", + 2, 0 }, { "[^([^,(\?<!]*))]", 0, 0 }, { "[^(\?{[:alnum:]]}}}}}}}}}}}}}}}}}}}}}}}){-83}", 0, 0 }, { "WWWWWWWW[:alnum(\?<=(\?#:]{,-1})@OSSS)[:digit:]", 0, 0 }, { "[^(\?!*]+G)", 0, 0 }, - { "[LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL>s8.>[^{}$(\?(]]XXXXXXX)XXXXXXXXXXXXXX[:alpha:]Whii\?p[:xdigit:])+", 0, 0 }, + { "[LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL>s8.>[^{}$(\?(]]XXXXXXX)" + "XXXXXXXXXXXXXX[:alpha:]Whii\?p[:xdigit:])+", + 0, 0 }, { "(7777[:blankcntrl:])", 1, 0 }, { "[^C[:digit:]]{}YYYY(YYYYYYYYYYYYYYYY)", 1, 0 }, { "on|,#tve%F(w-::::::::::::::::::::::::::::*=->)", 1, 0 }, - { "([((\?=(\?!((\?=')))27(<{})S-vvvvvvvvvv(\?=vvvvvvvvvvvvvvvvv[:punct:][:alnum:]}}}}}}}}}}}}}}}}}}}}}}}PPPPPPPPPPPPPPPPPPPPPPPPPPPPPgggggggggggggggggggggggggg(\?#(\?#gggggg<X){}]{-164,61})>+))uQ)W>[:punct:][:xdigit:][:digit:][:punct:]{}[:digit:][:space:]){,-105}=xiAyf}o[:alpha:]akZSYK+sl{", 1, 0 }, + { "([((\?=(\?!((\?=')))27(<{})S-vvvvvvvvvv(\?=" + "vvvvvvvvvvvvvvvvv[:punct:][:alnum:]}}}}}}}}}}}}}}}}}}}}}}}" + "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPgggggggggggggggggggggggggg(\?#(" + "\?#gggggg<X){}]{-164,61})>+))uQ)W>[:punct:][:xdigit:][:" + "digit:][:punct:]{}[:digit:][:space:]){,-105}=xiAyf}o[:alpha:" + "]akZSYK+sl{", + 1, 0 }, { "[^[^]/S:Hq<[:upperword:(\?<=]W[:alnum:]X])1973", 0, 0 }, - { "[[^[[^([^VVVV(\?!(VVVVVVVVVVVVVVVVVVVVV[VVVVX][^]2))98ppppppppppppppppppppppppppppppp/////////////////////b.]G{-101,}[:[ascii:]P].=~])AAAAAAAAAAAAA2{-153,}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]][:alnum:][:lowerprint:]WN/D!rD]|4444{180}]V_@3lW#lat]", 0, 0 }, - { "[^[^([^TTTTT(\?:T(\?:T7777{,59}])[:graph:][:ascii(\?<=:]))f]AD{,-43}%%%%%%%%%%%%%%%%)S|[:digit:]FZm<[:blankcntrl:]QT&xj*{-114,}$[:xdigit:]042][:xdig[it:]{-180}027[:alpha:][:ascii:][:lowerprint:][:xdigit:]^|[:alnum:][^Mi]z!suQ{-44,-32}[:digit:]]", 0, 0 }, + { "[[^[[^([^VVVV(\?!(VVVVVVVVVVVVVVVVVVVVV[VVVVX][^]2))" + "98ppppppppppppppppppppppppppppppp/////////////////////" + "b.]G{-101,}[:[ascii:]P].=~])AAAAAAAAAAAAA2{-153,}]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]][:alnum:][:lowerprint:]WN/" + "D!rD]|4444{180}]V_@3lW#lat]", + 0, 0 }, + { "[^[^([^TTTTT(\?:T(\?:T7777{,59}])[:graph:][:ascii(\?<=:]))f]" + "AD{,-43}%%%%%%%%%%%%%%%%)S|[:digit:]FZm<[:blankcntrl:]QT&xj*" + "{-114,}$[:xdigit:]042][:xdig[it:]{-180}027[:alpha:][:ascii:]" + "[:lowerprint:][:xdigit:]^|[:alnum:][^Mi]z!suQ{-44,-32}[:" + "digit:]]", + 0, 0 }, { ")", 0, 0 }, { "''''''''''[:a(\?imsxisx:lnum:])P", 0, 0 }, - { "(([{20(\?<=8}[:alnum:]pP$`(\?#N)wRH[:graph:]aaaaaaaaaaaaaa(\?=aaaaaaaaaaaaaaaaP]a)))[:punct:]-\?)A^", 2, 0 }, - { "[^(.//[:punct:]&-333333333333333333333333333(\?<!33)LLLLLLLLLLLLLLLLL[:alnum:]$1]~8]|^\"A[:xdigit:]\?[:ascii:]{128,}{,-74}[:graph:]{157}3N){-196,184}D", 0, 0 }, + { "(([{20(\?<=8}[:alnum:]pP$`(\?#N)wRH[:graph:]aaaaaaaaaaaaaa(" + "\?=aaaaaaaaaaaaaaaaP]a)))[:punct:]-\?)A^", + 2, 0 }, + { "[^(.//" + "[:punct:]&-333333333333333333333333333(\?<!33)" + "LLLLLLLLLLLLLLLLL[:alnum:]$1]~8]|^\"A[:xdigit:]\?[:ascii:]{" + "128,}{,-74}[:graph:]{157}3N){-196,184}D", + 0, 0 }, { "[^($(\?{(\?<=)[#)]})[:space:]]nWML0D{}", 0, 0 }, - { ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,[^]x{213,-93}(\?{A7]V{}})", 0, 0 }, + { ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,[^]x{213,-93}(\?{A7]V{}})", 0, + 0 }, { "[k(\?=*)+^[f(])r_H6", 0, 0 }, { "[(\?#(\?{)]q})", 0, 0 }, - { "([GLLLLLLLLLL(\?!((\?:LLLLLLLL]))C#T$Y))^|>W90DDDDDDDDDDD[^DDDDDDDDDDDDDDDDDDDD]B[:punct:]c/", 1, 0 }, - { "[^(\?<!)(\?{b}){,199}A[:space:]+++++++(\?!++++++++{36}Tn])", 0, 0 }, + { "([GLLLLLLLLLL(\?!((\?:LLLLLLLL]))C#T$Y))^|>W90DDDDDDDDDDD[^" + "DDDDDDDDDDDDDDDDDDDD]B[:punct:]c/", + 1, 0 }, + { "[^(\?<!)(\?{b}){,199}A[:space:]+++++++(\?!++++++++{36}Tn])", + 0, 0 }, { "()[:alpha:]a", 1, 0 }, { "[(\?(:blan)kcntrl:])lUUUUUUUUUUUUUUUUUUUUUUU", 0, 0 }, - { "[^[^(s[[[[[[[[[[[[[[(\?#[[[[[[[)\?`````][:blankcntrl:(\?>]|)p1EmmmmmmmmmmmmmmmmmmmmmmmmmmmmL{-241}666666666666666666666)]^bLDDDDDDDDDDDDD]", 0, 0 }, - { "[nn(\?<!nnnnn(\?#n8)=````````````````````{41,}]U,cb*%Y[:graph:]).[:alnum:]\\\\\\\\\\gt", 0, 0 }, + { "[^[^(s[[[[[[[[[[[[[[(\?#[[[[[[[)\?`````][:blankcntrl:(\?>]|)" + "p1EmmmmmmmmmmmmmmmmmmmmmmmmmmmmL{-241}666666666666666666666)" + "]^bLDDDDDDDDDDDDD]", + 0, 0 }, + { "[nn(\?<!nnnnn(\?#n8)=````````````````````{41,}]U,cb*%Y[:" + "graph:]).[:alnum:]\\\\\\\\\\gt", + 0, 0 }, { "()\?5{,-195}lm*Ga[:space:]Y", 1, 0 }, { "[(\?:].di)c", 0, 0 }, - { "([([^([\?{})Za,$S(\?!p(\?{++(\?##V(\?<!Evuil.2(\?<![^[h|[^']C)*\"]5]", 1, 0 }, - { "[((^24(\?#4[^Kkj{}))]]{232}47)077[:alpha:]zzzzzzzz{}", 0, 0 }, + { "([([^([\?{})Za,$S(\?!p(\?{++(\?##V(\?<!Evuil.2(\?<![^[h|[^']" + "C)*\"]5]", + 1, 0 }, + { "[((^24(\?#4[^Kkj{}))]]{232}47)077[:alpha:]zzzzzzzz{}", 0, + 0 }, { "[^(\?:[^F]o$h)-iV%]", 0, 0 }, - { "[[^[([((([^(\?{[^((\?=)kaSx(\?imsximsx:w3A[`%+A$I{,62}ns&Y!#ay o9YAo{Y>1((\?>\?#45)Z{,108}{}11111111111111111111111111qqqq)\?][:lowerprint:]mbo#)@", 0, 0 }, + { "[[^[([((([^(\?{[^((\?=)kaSx(\?imsximsx:w3A[`%+A$I{,62}ns&Y!#" + "ay " + "o9YAo{Y>1((\?>\?#45)Z{,108}{}11111111111111111111111111qqqq)" + "\?][:lowerprint:]mbo#)@", + 0, 0 }, { "[^iii8(888888(\?<!8^]))s", 0, 0 }, { "([[(\?(\?:({^]}[)[(r)])G]{,-87}", 1, 0 }, - { "([[^{249,}(\?>(\?=)]]T()[:bl(\?!ankcntrl:]=jjjjjjjjjjjjjjjj-)))t{}[:alpha:]-\":i! Gn[A4Ym7<<<<<<<<<<<<<<<<]", 2, 0 }, + { "([[^{249,}(\?>(\?=)]]T()[:bl(\?!ankcntrl:]=jjjjjjjjjjjjjjjj-" + ")))t{}[:alpha:]-\":i! Gn[A4Ym7<<<<<<<<<<<<<<<<]", + 2, 0 }, { "^{}{[^,241(\?#}(\?m(\?ixim:sximsx:]t))+oD)", 0, 0 }, { "5[(\?#:xdigit:])", 0, 0 }, - { "[^f{(\?>,22(9}[^[^])6KKKKKKKKKKKKK)]RRRRRRRRfuK99999999C}osnNR]BgCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC[:blankcntrl:]", 0, 0 }, - { "[^(\?=U){24,}W-{,17(\?:3[^}]q.nQ#PU_|i$$$$$$$$$$$$$$+)[:dig(\?<!it:]){-98}\?[:upperword:]]", -1, 0 }, - { "[(\?<=[0(\?!72])euE.]{,-159}[:alnum:]t-:l\?)$yyyyyyyyyyyyyyyyyyyyyyyyyyfffffffffffffffffffffffffff", 0, 0 }, - { "[^[^]q[:asc(\?imsxmsx:ii:]JJJJJJJJJJJJJJJJJJJJ[:graph:]]$)`#DdY^qqqqqqqqqqqqqqqqqqqqqqqqqqqu>4^4ta[:alpha:]", 0, 0 }, + { "[^f{(\?>,22(9}[^[^])6KKKKKKKKKKKKK)]RRRRRRRRfuK99999999C}" + "osnNR]BgCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC[:blankcntrl:]", + 0, 0 }, + { "[^(\?=U){24,}W-{,17(\?:3[^}]q.nQ#PU_|i$$$$$$$$$$$$$$+)[:dig(" + "\?<!it:]){-98}\?[:upperword:]]", + -1, 0 }, + { "[(\?<=[0(\?!72])euE.]{,-159}[:alnum:]t-:l\?)$" + "yyyyyyyyyyyyyyyyyyyyyyyyyyfffffffffffffffffffffffffff", + 0, 0 }, + { "[^[^]q[:asc(\?imsxmsx:ii:]JJJJJJJJJJJJJJJJJJJJ[:graph:]]$)`#" + "DdY^qqqqqqqqqqqqqqqqqqqqqqqqqqqu>4^4ta[:alpha:]", + 0, 0 }, { "(((b0HN)q))p5<T())`7JJv{'cv'#L8BNz", 4, 0 }, - { "[pFp2VttBg(\?<=7777777777777|TTTTTTTTTTTTTTT[:space:]Z]^p\"[:blankcntrl:])", 0, 0 }, + { "[pFp2VttBg(\?<=7777777777777|TTTTTTTTTTTTTTT[:space:]Z]^p\"[" + ":blankcntrl:])", + 0, 0 }, { ")aM@@@@@@@@@@@@@", 0, 0 }, { "([^[(\?<![^])", 1, 0 }, { "()Z[:ascii:]", 1, 0 }, - { "(fuPPo)..........................[:xdigit:]{}{,4}*kkkkkkkCx#,_=&~)|.2x", 1, 0 }, - { "[+(\?<=){}++++++[:alnum:](\?=+]s)[:alnum:]~~~~~~XXXXXXXXXXXXXXX.[:digit:]", 0, 0 }, + { "(fuPPo)..........................[:xdigit:]{}{,4}*kkkkkkkCx#" + ",_=&~)|.2x", + 1, 0 }, + { "[+(\?<=){}++++++[:alnum:](\?=+]s)[:alnum:]~~~~~~" + "XXXXXXXXXXXXXXX.[:digit:]", + 0, 0 }, { "[{}[^^(\?(]))CCCCCCCCCCCCCCCCCCCCEg2cF]{}3", 0, 0 }, - { "([[[^[^[^([[^[^([(\?<=G[[)=(\?!===(\?isximsx:==(\?#==[^=====(\?{==================$T[[^^u_TiC.Fo.02>X)uH]$})354b[:alnum:]]]EVVVVVVVVVVVVVVVVVVVVVVVVVVVVVz[:digi(\?(t:][:upperword:])", 1, 0 }, - { "([:blankcntrl:]t-){121,}[:ascii:]444444{}[:graph:]E040", 1, 0 }, - { "[^{134,}]DzQ\?{-30,191})z,\?1Vfq!z}cgv)ERK)1T/=f\?>'", 0, 0 }, - { "@v)<yN]'l-/KKKKKKKBBBBBBBBBBBBBMa2eLA[:digit(\?<!:])\"\"e|l$&m`_yn[:blankcntrl:]uuuuuuuuuuuuuuuuuuu[:punct:]", 0, 0 }, - { "[[999999999999999(\?<=(\?:(\?ixmx:(\?>))])Y]|){,10}\?{}", 0, 0 }, + { "([[[^[^[^([[^[^([(\?<=G[[)=(\?!===(\?isximsx:==(\?#==[^=====" + "(\?{==================$T[[^^u_TiC.Fo.02>X)uH]$})354b[:alnum:" + "]]]EVVVVVVVVVVVVVVVVVVVVVVVVVVVVVz[:digi(\?(t:][:upperword:]" + ")", + 1, 0 }, + { "([:blankcntrl:]t-){121,}[:ascii:]444444{}[:graph:]E040", 1, + 0 }, + { "[^{134,}]DzQ\?{-30,191})z,\?1Vfq!z}cgv)ERK)1T/=f\?>'", 0, + 0 }, + { "@v)<yN]'l-/" + "KKKKKKKBBBBBBBBBBBBBMa2eLA[:digit(\?<!:])\"\"e|l$&m`_yn[:" + "blankcntrl:]uuuuuuuuuuuuuuuuuuu[:punct:]", + 0, 0 }, + { "[[999999999999999(\?<=(\?:(\?ixmx:(\?>))])Y]|){,10}\?{}", 0, + 0 }, { "([[[(\?!^]P-AA[AAAAAA[A[^A)r]+B]])", 1, 0 }, { "3}|[:ascii:][:punct:]()", 1, 0 }, { "()dw", 1, 0 }, { "[N]{})))))))))))))))))))))))", 0, 0 }, - { "[[[^([[(\?()(\?#)++([^\?{+++[^+++++++++++(\?!+(\?=+++++++r9/n]N7{-219}{-91}pP[:punct:]T]mROm+~[:digit:][:digit:])Y:", 0, 0 }, - { "[^'Pu[(\?<!D&]_a[:alnum:]E<,F%4&[:xdigit:])][:lowerprint:]", 0, 0 }, + { "[[[^([[(\?()(\?#)++([^\?{+++[^+++++++++++(\?!+(\?=+++++++r9/" + "n]N7{-219}{-91}pP[:punct:]T]mROm+~[:digit:][:digit:])Y:", + 0, 0 }, + { "[^'Pu[(\?<!D&]_a[:alnum:]E<,F%4&[:xdigit:])][:lowerprint:]", + 0, 0 }, { "tttt(tttttttttt*uKKUUUUU)", 1, 0 }, - { "([:ascii:]GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG)+kX______________{}GGGGG\?TUH3,{67,77}|[:graph:]C{,-136}{}[:upperword:[]{,-6}&]T84]n={C", 1, 0 }, - { "[:upperword:]DC[:u(\?<=pperword:]*d`H0\?m>~\?N|z#Ar--SO{,-141}076)G\?{,-110}M+-[:alpha:]", 0, 0 }, + { "([:ascii:]GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG)+kX______________{" + "}GGGGG\?TUH3,{67,77}|[:graph:]C{,-136}{}[:upperword:[]{,-6}&" + "]T84]n={C", + 1, 0 }, + { "[:upperword:]DC[:u(\?<=pperword:]*d`H0\?m>~\?N|z#Ar--SO{,-" + "141}076)G\?{,-110}M+-[:alpha:]", + 0, 0 }, { "{,-214}{,10(9})", 1, 0 }, - { "([^xxxxxxxxxxxxxxxxxMMMMMMMMMMMMMMXW])].[:punct:]Q`{-63,63}Uua[:alnum:]\?OQssb#L@@@@@@@@(@@@)[:graph:]", 2, 0 }, - { "[[^(\?!```[^``````````````(\?<=``(\?>````````M/////(\?!////////////////////[^GD!|#li]~)*.$]))Tq!]C[:lowerprint:]Qk[{}]]JJJJJJJJJJJJJJJJJJJJJJJ{e])c", 0, 0 }, - { "$[5(7ES])[:xdigit:]%{MRMtYD&aS&g6jp&ghJ@:!I~4%{P\?0vvvvvvvvvvvvvvvvvvvv\\\\\\\\\\\\\\\\\\\\\\\\x54[:lowerprint:][:upperword:]", 0, 0 }, - { "[((([(\?((\?>[:alnum:][):as(\?<!cii:(\?:]Re))K|)|^){-28,89}l<H.<H:N)QKuuuuuuuuw8E136P)^)[:ascii:]][:xdigit:]-", 0, 0 }, + { "([^xxxxxxxxxxxxxxxxxMMMMMMMMMMMMMMXW])].[:punct:]Q`{-63,63}" + "Uua[:alnum:]\?OQssb#L@@@@@@@@(@@@)[:graph:]", + 2, 0 }, + { "[[^(\?!```[^``````````````(\?<=``(\?>````````M/////(\?!/////" + "///////////////" + "[^GD!|#li]~)*.$]))Tq!]C[:lowerprint:]Qk[{}]]" + "JJJJJJJJJJJJJJJJJJJJJJJ{e])c", + 0, 0 }, + { "$[5(7ES])[:xdigit:]%{MRMtYD&aS&g6jp&ghJ@:!I~4%{" + "P\?0vvvvvvvvvvvvvvvvvvvv\\\\\\\\\\\\\\\\\\\\\\\\x54[:" + "lowerprint:][:upperword:]", + 0, 0 }, + { "[((([(\?((\?>[:alnum:][):as(\?<!cii:(\?:]Re))K|)|^){-28,89}" + "l<H.<H:N)QKuuuuuuuuw8E136P)^)[:ascii:]][:xdigit:]-", + 0, 0 }, { "(pjvA'x]=D\"qUby\\+'R)r\?C22[:ascii:]", 1, 0 }, { "[]*b~y C=#P\"6(gD%#-[^FBt{}]${-244}", 0, 0 }, - { "[:up(\?!pe(\?=rword:])lA-'yb\"Xk|K_V\"/@}:&zUA-)W#{-178,-142}(){-202,}", 1, 0 }, + { "[:up(\?!pe(\?=rword:])lA-'yb\"Xk|K_V\"/" + "@}:&zUA-)W#{-178,-142}(){-202,}", + 1, 0 }, { "()1.WldRA-!!!!!!!!!!!!!!!!!", 1, 0 }, - { "lZZZZZZZZZZZZZZZ(Z[:al(\?:num:])ttttttttttttttttttttttttttttttg.)6$yyy", 1, 0 }, - { "[([^([^[^(([([^[^(([[$(\?{P(\?=(\?<(\?!=(\?#P[^Y])<GA[:ascii:][(\?#(\?<!:alpha:](B{100,})]}))\?)XU=", 1, 0 }, - { "[[dVw{6(\?{9,}2222kkkkkkkkkkkkkkkkkkkkkkkkkk|{}*E]]{}SB{35}-w%{eh})<{-178,}", 0, 0 }, + { "lZZZZZZZZZZZZZZZ(Z[:al(\?:num:])" + "ttttttttttttttttttttttttttttttg.)6$yyy", + 1, 0 }, + { "[([^([^[^(([([^[^(([[$(\?{P(\?=(\?<(\?!=(\?#P[^Y])<GA[:" + "ascii:][(\?#(\?<!:alpha:](B{100,})]}))\?)XU=", + 1, 0 }, + { "[[dVw{6(\?{9,}2222kkkkkkkkkkkkkkkkkkkkkkkkkk|{}*E]]{}SB{35}-" + "w%{eh})<{-178,}", + 0, 0 }, { "(D(~))", 2, 0 }, - { "[(:alpha:]{,90}Z|)[:ascii:]Du\?[:grap[^h:]^w+|{}][:ascii:]", 0, 0 }, + { "[(:alpha:]{,90}Z|)[:ascii:]Du\?[:grap[^h:]^w+|{}][:ascii:]", + 0, 0 }, { "[:p(\?<=unct:]kkkkkkkkkkkkkkkkkkkk)", 0, 0 }, - { "{}[:((\?<!dig((\?#it(\?#:]())p))ZZZZZZZZZZ[:blankcntrl:]){}{-124,})[:ascii:]", 1, 0 }, - { "[[:graph:]{168}lRRRRRRRRRRRRR(\?#RRRRRRRRRRRRRRRRR)rrrr(\?(rrrrrr)rrrrrrrS[(\?<!@f)6>{,-49})q${98,}J\?]){", 0, 0 }, + { "{}[:((\?<!dig((\?#it(\?#:]())p))ZZZZZZZZZZ[:blankcntrl:]){}{" + "-124,})[:ascii:]", + 1, 0 }, + { "[[:graph:]{168}lRRRRRRRRRRRRR(\?#RRRRRRRRRRRRRRRRR)rrrr(\?(" + "rrrrrr)rrrrrrrS[(\?<!@f)6>{,-49})q${98,}J\?]){", + 0, 0 }, { "([:pu(\?(nc)t:]F{-32,-102}+)\?cpP[:lowerprint:].^)", 1, 0 }, { "([{}{210,-238}]1:h)", 1, 0 }, - { "([]QQQQ[QQQQQQQQQQQQQQQQQQ][:digit:]Z{-20,}Slllllll[:space:]C^(@{-174,-156}fx{cf2c}{-242,}rBBBBBBBBBBBBBBBBBBc[:alpha:]N\?))$[:graph:][:ascii:]P+nnnnnnnnnnnnnnnnnnnnnnn1N$r>>>>>>>>>>>>>>>>>>>>>>>>(>>{,88}{,-234}__________)[:upperword:]R.[:alnum:][:lowerprint:]^}\"", 3, 0 }, + { "([]QQQQ[QQQQQQQQQQQQQQQQQQ][:digit:]Z{-20,}Slllllll[:space:]" + "C^(@{-174,-156}fx{cf2c}{-242,}rBBBBBBBBBBBBBBBBBBc[:alpha:]" + "N\?))$[:graph:][:ascii:]P+nnnnnnnnnnnnnnnnnnnnnnn1N$r>>>>>>>" + ">>>>>>>>>>>>>>>>>(>>{,88}{,-234}__________)[:upperword:]R.[:" + "alnum:][:lowerprint:]^}\"", + 3, 0 }, { "([^(\?=]-))$", 1, 0 }, - { "([:ascii:]\?,D[:upperword:][:xdigit:]tttttttttttt[^tt(\?<!ttttttttt21f|.(pP[:punct:])])rrrrrrrr)", 1, 0 }, - { "([{1(\?=16}iiiiiiiiii((\?<=iiiiiiiiiiiiiiiiii|ZZZZZZZZZZZ(\?(\?#{ZZZZZZZ))c}))<<<<<(\?#<<<<<<<<<<<d7CVq8]w{-148,-168}\\Gp){-230,}D3", 1, 0 }, + { "([:ascii:]\?,D[:upperword:][:xdigit:]tttttttttttt[^tt(\?<!" + "ttttttttt21f|.(pP[:punct:])])rrrrrrrr)", + 1, 0 }, + { "([{1(\?=16}iiiiiiiiii((\?<=iiiiiiiiiiiiiiiiii|ZZZZZZZZZZZ(" + "\?(\?#{ZZZZZZZ))c}))<<<<<(\?#<<<<<<<<<<<d7CVq8]w{-148,-168}" + "\\Gp){-230,}D3", + 1, 0 }, { "[^8888(88888888888EX].[:alnum:]){}", 0, 0 }, { "([^][^)2]-[:lower(\?=print:]{,79}[:graph:]n)", 1, 0 }, - { "[bSi\?x_mp(C)0{64}[:space:]hhh(\?(hhh)hhL){5,130}'w\"$l&[:xdigit:][:alpha:]IIIIIIIIIIIIIIIIIIIIIII+-SOOOOOOOOOOOO (\?( ) ]f)ed", 0, 0 }, + { "[bSi\?x_mp(C)0{64}[:space:]hhh(\?(hhh)hhL){5,130}'w\"$l&[:" + "xdigit:][:alpha:]IIIIIIIIIIIIIIIIIIIIIII+-SOOOOOOOOOOOO " + " (\?( ) ]f)ed", + 0, 0 }, { "[[^[(^(C.Jl[^X&Rb64a+Sd])'m[:alpha:])]]]{134,}", 0, 0 }, { "()L", 1, 0 }, - { "[[(({224,(\?#88})@======(\?!=========(\?{=)PPP)i^@p(\?([:punct:]})^^[^^^^^^^^^^^^^^^^^^^^^@)m]|{CS{,-3}168)-[:xdigit:][:upperword:]hnD=Bns)z)AAAAAAAAAAAAAAAAAAAAAAA[^A{}ccccccccccc)SZ]Q-p.sD]]+P", 0, 0 }, - { "[[^[^]{135,}66666666666666666666[6(666i2M9.!uhmT\?JMm.*(\?!+)[:alpha:]eeeeeeeeeeeeeeeeeeeeeeeeeee]]])ZZ[:blankcntrl:][:ascii:]", 0, 0 }, - { "(13[3Ux>{,10}[(\?<=:xdigit:]))PL9{-89,-181}F'''''''''", 1, 0 }, + { "[[(({224,(\?#88})@======(\?!=========(\?{=)PPP)i^@p(\?([:" + "punct:]})^^[^^^^^^^^^^^^^^^^^^^^^@)m]|{CS{,-3}168)-[:xdigit:" + "][:upperword:]hnD=Bns)z)AAAAAAAAAAAAAAAAAAAAAAA[^A{}" + "ccccccccccc)SZ]Q-p.sD]]+P", + 0, 0 }, + { "[[^[^]{135,}66666666666666666666[6(666i2M9.!uhmT\?JMm.*(\?!+" + ")[:alpha:]eeeeeeeeeeeeeeeeeeeeeeeeeee]]])ZZ[:blankcntrl:][:" + "ascii:]", + 0, 0 }, + { "(13[3Ux>{,10}[(\?<=:xdigit:]))PL9{-89,-181}F'''''''''", 1, + 0 }, { "[^.|(\?{af]})^$XE!$", 0, 0 }, { "(WWWWWWWWWWWWWWWWWWWWWWWWWWWW#J)", 1, 0 }, { "({}}M7we-216)L[:digit:][:upperword:]", 1, 0 }, { "([:aln[^u(\?=m:]))].z", 1, 0 }, - { "([:alpha:]{(92})%6{41,136})Vij@[:alnum:][:lowerprint:]", 2, 0 }, - { "[[[++(\?{+++{}})n{{137,}{51,-177}Z[]M*[:ascii:]{(-29,-47}2)$e^{,-195}{-156,}^]{}{-225,69}A]{-222,}{,20}m[:blankcntrl:]", 1, 0 }, - { ")l)[:alnum:][:graph:]g8TTTTTTTTTTTTTTTTLLLLLLLLLLLLLLLLL", 0, 0 }, + { "([:alpha:]{(92})%6{41,136})Vij@[:alnum:][:lowerprint:]", 2, + 0 }, + { "[[[++(\?{+++{}})n{{137,}{51,-177}Z[]M*[:ascii:]{(-29,-47}2)$" + "e^{,-195}{-156,}^]{}{-225,69}A]{-222,}{,20}m[:blankcntrl:]", + 1, 0 }, + { ")l)[:alnum:][:graph:]g8TTTTTTTTTTTTTTTTLLLLLLLLLLLLLLLLL", 0, + 0 }, { "[([(\?<=.(\?{)/})mmmmmmmm(\?(mmmmm]{-154,-176}*S)I]", 0, 0 }, - { "[(([{(\?(\?<!im(\?imsix:sim(sx:,141}])D)l{,42}ttttt[(\?::punct:])){-162,-141}{-26,})dU@@@@@@@@@@@@@@@ S)\\A\?w|VVVVVVVVV)X.kN{,21}{-208,-52}>[:lowerprint:][:ascii:]e-]]]]]]]]]]]]]]]]]]]]]", 0, 0 }, - { "[^({}(){(66(\?=,}[^]'''''QQQQQQQQQ).P#>^){86,168}Z[(\?<!:lowerprint:]{-166,-70}<k", 0, 0 }, - { "APP[:alpha:][:alnum:]nd[:upperword:(\?(]^xxxxxxxxxxxxxxxxxxx)xxxxxxxxx{-70}[:punct:]l)U-", 0, 0 }, - { "[^(.\"od~(6({[^(\?<!228}\?)\?)######(\?:#########z )c(\?<!aQ`(\?{UKSwu[})][^-17]{11,}}][:ascii:]))^RiH+WyspP[qi&)=p6])[:space:]{-221,}]6p", 0, 0 }, + { "[(([{(\?(\?<!im(\?imsix:sim(sx:,141}])D)l{,42}ttttt[(\?::" + "punct:])){-162,-141}{-26,})dU@@@@@@@@@@@@@@@ " + "S)\\A\?w|VVVVVVVVV)X.kN{,21}{-208,-52}>[:lowerprint:][:" + "ascii:]e-]]]]]]]]]]]]]]]]]]]]]", + 0, 0 }, + { "[^({}(){(66(\?=,}[^]'''''QQQQQQQQQ).P#>^){86,168}Z[(\?<!:" + "lowerprint:]{-166,-70}<k", + 0, 0 }, + { "APP[:alpha:][:alnum:]nd[:upperword:(\?(]^" + "xxxxxxxxxxxxxxxxxxx)xxxxxxxxx{-70}[:punct:]l)U-", + 0, 0 }, + { "[^(.\"od~(6({[^(\?<!228}\?)\?)######(\?:#########z " + ")c(\?<!aQ`(\?{UKSwu[})][^-17]{11,}}][:ascii:]))^RiH+WyspP[" + "qi&)=p6])[:space:]{-221,}]6p", + 0, 0 }, { "{-78}()[:xdigit:]{155}{,-92}", 1, 0 }, - { "[(\?>Q{,147}_____________(\?!______uuuuuuuuuuuuuTr]){74,179}{}){,103}{-209,16}*RRRRRRRRRRRRRRRRw{,87}9{144}[:ascii:]'<Ab", 0, 0 }, + { "[(\?>Q{,147}_____________(\?!______uuuuuuuuuuuuuTr]){74,179}" + "{}){,103}{-209,16}*RRRRRRRRRRRRRRRRw{,87}9{144}[:ascii:]'<" + "Ab", + 0, 0 }, { "([666c] {-171}yc,8-k_)EEEEEEEEEEEEEEEEEEEEE<", 1, 0 }, { "[^(\?>(\?<!)2(\?imim:)6HwN)^|fc!(\?(d]75))065)G", 0, 0 }, { "[[^xDB[:alnum:][:xdigit:]][:digit:]jW]([:alpha:])", 1, 0 }, - { "[ds~T+[x55[:digit:]X[JJJJJJJ.[(\?::upperword:]){,-14}][:xdigit:]bbbbbbbbbbb", 0, 0 }, + { "[ds~T+[x55[:digit:]X[JJJJJJJ.[(\?::upperword:]){,-14}][:" + "xdigit:]bbbbbbbbbbb", + 0, 0 }, { "[qqqqq(\?<=qqqq(\?(qqq)^G[):ascii:]])W", 0, 0 }, - { "[:space:]JJJJJJ[:alph(\?<!a:]|[:ascii:(\?(])[:x)digit:]- XSstG[:g(\?>raph:])^)Ny6RF_ndoU9@*rxW{4,41}4{}", 0, 0 }, - { "[:punct:]{162,}j[:aln(um:].....................[^...]\?>z[:l[owerprint:]){55,222}]", 0, 0 }, - { "(>vWa)OXcccccccccccccccccccccccc[:alpha:]C{,-10}81|m1D^T)[:lowerprint:]''''[:alpha:]l", 1, 0 }, - { "(XZcgM/UI-/mZq-222){-85,-196}[:alpha:]{114}rrrrrrrrrrrrrrrrrrrrrrrr{,157}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZLkD-&&&&&&&&&&&&&&&-][:alnum:]{}{,111}[:digit:]", 1, 0 }, - { "[^(\?:]MMMMMMMMMMMMMMMMMMMMMMMMMMM)cK[KKKKKKKKKKKKKKKKKKKKKKKK]P{146}", 0, 0 }, + { "[:space:]JJJJJJ[:alph(\?<!a:]|[:ascii:(\?(])[:x)digit:]- " + "XSstG[:g(\?>raph:])^)Ny6RF_ndoU9@*rxW{4,41}4{}", + 0, 0 }, + { "[:punct:]{162,}j[:aln(um:].....................[^...]\?>z[:" + "l[owerprint:]){55,222}]", + 0, 0 }, + { "(>vWa)OXcccccccccccccccccccccccc[:alpha:]C{,-10}81|m1D^T)[:" + "lowerprint:]''''[:alpha:]l", + 1, 0 }, + { "(XZcgM/UI-/" + "mZq-222){-85,-196}[:alpha:]{114}rrrrrrrrrrrrrrrrrrrrrrrr{," + "157}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZLkD-&&&&&&&&&&&&&&&-][:" + "alnum:]{}{,111}[:digit:]", + 1, 0 }, + { "[^(\?:]MMMMMMMMMMMMMMMMMMMMMMMMMMM)cK[" + "KKKKKKKKKKKKKKKKKKKKKKKK]P{146}", + 0, 0 }, { "([^[^wqesa)n\?L(\?<=FH+G[^rCGmfD]w)m1D\"%}]])", 1, 0 }, - { "[((\?:[^.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH|S)xd)*[:space:](])[:xdigit:]ngr'G#/B]-----------------------------", 0, 0 }, + { "[((\?:[^.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH|S)xd)*[:space:](])[" + ":xdigit:]ngr'G#/B]-----------------------------", + 0, 0 }, { ")[:lowerprint(\?<=(:]l))G p", 0, 0 }, - { "[^[^(\?<(\?<(=(\?imsximx:![(((\?<!\?(^))\?]^)[:xdigit:][:graph:]{-104,})Gf+GD*qc)c]f))])", 0, 0 }, - { "[^([\?())P[:alnum:]w]{-186,-139}-[:space:]RN3w[Fmvpl[:space:][:digit:]&&&&&&&&&&&&}(\?#}}}}}}}}}}}}}}}}}}}])z", 0, 0 }, - { "([[^^*C[()f][(\?=:punct([\?#:]o)]V)]%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[^x{1f948})]]", 1, 0 }, + { "[^[^(\?<(\?<(=(\?imsximx:![(((\?<!\?(^))\?]^)[:xdigit:][:" + "graph:]{-104,})Gf+GD*qc)c]f))])", + 0, 0 }, + { "[^([\?())P[:alnum:]w]{-186,-139}-[:space:]RN3w[Fmvpl[:space:" + "][:digit:]&&&&&&&&&&&&}(\?#}}}}}}}}}}}}}}}}}}}])z", + 0, 0 }, + { "([[^^*C[()f][(\?=:punct([\?#:]o)]V)]%%%%%%%%%%%%%%%%%%%%%%%%" + "%%%%%%[^x{1f948})]]", + 1, 0 }, { "[(:xdigit:])zE", 0, 0 }, { "[:pu(\?(nc)t:])(a*){-51}", 1, 0 }, - { "[^(.NKKKKKKKKKKKKKKKKKKKKKKKK-[:upperword:][:space:]`MPi>", -1, 0 }, - { "Nvvv[vv.][:alnu[^m:]+|Crrrrrrrrrrrrrrrrrrrrr[:xdigit:]j1n)v#]", 0, 0 }, - { "[^#}[(\?>:alnum:]).QQQQ[^QQQQQQ!!![!!!!!!!-s.n]se]{-238,}Tf]p4721", 0, 0 }, - { "([((\?#\?<=)+)Hr:-H]z[:graph:].{}oooooo(ooooooooo][:punct:]k<gXG@@@@@@@@@@@@@@@@@@@{,-176}){}L`)$", 2, 0 }, - { "({,249}{-73,}Z&&&&&&&&Ds35MB<v)qqqqqqqqqqqqqqqqqqqqqqqqq", 1, 0 }, + { "[^(.NKKKKKKKKKKKKKKKKKKKKKKKK-[:upperword:][:space:]`MPi>", + -1, 0 }, + { "Nvvv[vv.][:alnu[^m:]+|Crrrrrrrrrrrrrrrrrrrrr[:xdigit:]j1n)v#" + "]", + 0, 0 }, + { "[^#}[(\?>:alnum:]).QQQQ[^QQQQQQ!!![!!!!!!!-s.n]se]{-238,}Tf]" + "p4721", + 0, 0 }, + { "([((\?#\?<=)+)Hr:-H]z[:graph:].{}oooooo(ooooooooo][:punct:]" + "k<gXG@@@@@@@@@@@@@@@@@@@{,-176}){}L`)$", + 2, 0 }, + { "({,249}{-73,}Z&&&&&&&&Ds35MB<v)qqqqqqqqqqqqqqqqqqqqqqqqq", 1, + 0 }, { "[^.N][:blankcntrl:]))))))))))))))))))))))))))))))", 0, 0 }, { "(()*){198,}", 2, 0 }, - { "{-237,}220{}[:ascii:]```````(`````````````\?{-115,185}){,-18}[:punct:]'|Kk", 1, 0 }, + { "{-237,}220{}[:ascii:]```````(`````````````\?{-115,185}){,-" + "18}[:punct:]'|Kk", + 1, 0 }, { "[(\?()])", 0, 0 }, - { "([(\?#[:alnum:]CQ)}}}}}}}}(\?>}}}}}}}(}}}}}\?310[|))xA5r][[^:ascii:]^{,-156}{])CCCCCCCCCCC-145]FzwOD_u\?", 1, 0 }, - { "[^[^[]{-163}{(-203}[(\?!:upperword:]PPGjZ[:xdi(\?=git(\?#:]{-73}s)qqqq(qqqqqqqqqqqqqqqqqq{173,210}[:xdigit:(\?<(\?>=]WW[^WWWWWWW\?*O)))Q){}08)[(\?(\?<=#:blankcntrl:]{90,}]U)])L)ooooooooooooooooooooooooooox--^c[:ascii:]])s)", 2, 0 }, + { "([(\?#[:alnum:]CQ)}}}}}}}}(\?>}}}}}}}(}}}}}\?310[|))xA5r][[^" + ":ascii:]^{,-156}{])CCCCCCCCCCC-145]FzwOD_u\?", + 1, 0 }, + { "[^[^[]{-163}{(-203}[(\?!:upperword:]PPGjZ[:xdi(\?=git(\?#:]{" + "-73}s)qqqq(qqqqqqqqqqqqqqqqqq{173,210}[:xdigit:(\?<(\?>=]WW[" + "^WWWWWWW\?*O)))Q){}08)[(\?(\?<=#:blankcntrl:]{90,}]U)])L)" + "ooooooooooooooooooooooooooox--^c[:ascii:]])s)", + 2, 0 }, { "[(\?!:punc(\?imximx:t[^:]4F<}!)]'M-)tKKKa4904", 0, 0 }, - { "[^^{}\\(\?<!\\\\\\\\\\\\\\\\\\(\?#\\\\\\\\[:punct:](\?>)T000000000(\?(000)00000))+])", 0, 0 }, + { "[^^{}\\(\?<!\\\\\\\\\\\\\\\\\\(\?#\\\\\\\\[:punct:](\?>)" + "T000000000(\?(000)00000))+])", + 0, 0 }, { "L[:p(\?#unct:])", 0, 0 }, { "[:upperw(\?<!ord:])", 0, 0 }, - { "@$\"\"\"\"\"\"\"[\"\"\"\"\"\"\"\"\"\"[^(\"\"\"\"\"(\"\"][]))*U{223,138}*o```````````````(\?=[```````````````]{238}mmmPPPPPPPPPPPPPPP&&&&&&&&&&&&&&&&&&)sF$[:digit:[]]", 0, 0 }, + { "@$\"\"\"\"\"\"\"[\"\"\"\"\"\"\"\"\"\"[^(\"\"\"\"\"(\"\"][]))" + "*U{223,138}*o```````````````(\?=[```````````````]{238}" + "mmmPPPPPPPPPPPPPPP&&&&&&&&&&&&&&&&&&)sF$[:digit:[]]", + 0, 0 }, { "[^#Txx[xxxlPB(\?><[^U/)]]{}X3333333333(3333333f*])", 1, 0 }, - { "<<<<<<<<<<<<<<<[^<<<<<<<<<.][(\?#:ascii:])[:xdigit:]|^", 0, 0 }, + { "<<<<<<<<<<<<<<<[^<<<<<<<<<.][(\?#:ascii:])[:xdigit:]|^", 0, + 0 }, { "([:punct:]{}){-167,}{-59,}Pd\"", 1, 0 }, - { "[((\?#{,214})t$)VVV[:xdigit:]{104(\?<=}D][:graph:])|H){1,}{-176,}", 0, 0 }, - { "[[([[^N,,,,,(\?=,,(\?#(\?:,,,,,,,,,,,[^,,,,,,,,,,]<,~4::_.A]){-52,}-[:alnum:]Pnnnnnnnnnnnnnnnnnn)d", 0, 0 }, + { "[((\?#{,214})t$)VVV[:xdigit:]{104(\?<=}D][:graph:])|H){1,}{-" + "176,}", + 0, 0 }, + { "[[([[^N,,,,,(\?=,,(\?#(\?:,,,,,,,,,,,[^,,,,,,,,,,]<,~4::_.A]" + "){-52,}-[:alnum:]Pnnnnnnnnnnnnnnnnnn)d", + 0, 0 }, { "{-18(3,})uT{4,}", 1, 0 }, - { "[^[^[(p+c(\?<!b$))(\?:EU(\?(.][^{}]3[:xdigi[^t):][:punct(\?>:])[])][:s[^pace:]][:alnum:][:alpha:]]kw06E", 0, 0 }, - { "[^^^^^^JJJJJJJJ(JJ(\?=JJ(.6[:space:]H]{231,}A^eqqq)[:ascii:(\?>(])[(\?>:spa(\?:ce:]xxxxxxxxx)@_t-))138GNNNNNNNNNNNNNNNNNNNNNNNNNN[:digit:]no!`#E\?&[:lowerprint:].)[:graph:]{86,}[:digit:][:alnum:]", 0, 0 }, + { "[^[^[(p+c(\?<!b$))(\?:EU(\?(.][^{}]3[:xdigi[^t):][:punct(\?>" + ":])[])][:s[^pace:]][:alnum:][:alpha:]]kw06E", + 0, 0 }, + { "[^^^^^^JJJJJJJJ(JJ(\?=JJ(.6[:space:]H]{231,}A^eqqq)[:ascii:(" + "\?>(])[(\?>:spa(\?:ce:]xxxxxxxxx)@_t-))" + "138GNNNNNNNNNNNNNNNNNNNNNNNNNN[:digit:]no!`#E\?&[:" + "lowerprint:].)[:graph:]{86,}[:digit:][:alnum:]", + 0, 0 }, { "[:g(\?<=raph:]a{114,146}(){}0Y[:bl(ankcntrl:])D)\?", 1, 0 }, { "[^[^]*H{-192,96}S|]G)6B-kLB", 0, 0 }, - { "[[^[^][/NS8`um(\?{82&{((\?{\?<!-[110,-88}]m)})kkkkkkkk$$$$$$$$$$$$[^$$$$$@n%BuK@X!P)y0v!^]YY[YYY[YYYYYYYYYYYYYYYYYY///////{}{{{{{{{{{{{{{oiiii})]8{-2[53}w{82,}]{,245}]{-134}]fffffffffffffffffff]\"I>DW>9tN%{113}{unE", 0, 0 }, + { "[[^[^][/" + "NS8`um(\?{82&{((\?{\?<!-[110,-88}]m)})kkkkkkkk$$$$$$$$$$$$[^" + "$$$$$@n%BuK@X!P)y0v!^]YY[YYY[YYYYYYYYYYYYYYYYYY///////" + "{}{{{{{{{{{{{{{oiiii})]8{-2[53}w{82,}]{,245}]{-134}]" + "fffffffffffffffffff]\"I>DW>9tN%{113}{unE", + 0, 0 }, { "[:(\?(alpha:]`))Y2sCqWQ104", 0, 0 }, - { "(([^()Wcccccccc(\?{cccccccccccccccccc(\?<!c(ccccc[:space:]$)(\?>)FZ{}{}`|||||||||||||*````````````````````````````'=dLQmx/Y.A7j'o}jn{}:})][:punct:]$|,-)!&Y:Ys#ykL7JJJJJJJJJJJJJJJJJJJJJJJJJ8yex>#mv[:punct:](x@)$[:uppe(\?<!rword:])_)", 3, 0 }, - { "[[(^HHHHHHHHHHHH(\?imsximx:HH(HHHHHH(\?{HH[HH])qjR>9))i})]a!lBW3p{A=or)ShE%[:punct:]{}]5r", 0, 0 }, - { "[:pu[nc[^t:]]]}}}}}}}[}}}}}}}(\?#}])@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDD\?]xA2\?", 0, 0 }, - { "(.[:alpha:]xB7[:alnu(\?{m:]})RRRRRRRRRRRRRRRRRRRRRRRRRRRL)[:space:]G\?", 1, 0 }, + { "(([^()Wcccccccc(\?{cccccccccccccccccc(\?<!c(ccccc[:space:]$)" + "(\?>)FZ{}{}`|||||||||||||*````````````````````````````'=" + "dLQmx/" + "Y.A7j'o}jn{}:})][:punct:]$|,-)!&Y:Ys#" + "ykL7JJJJJJJJJJJJJJJJJJJJJJJJJ8yex>#mv[:punct:](x@)$[:uppe(" + "\?<!rword:])_)", + 3, 0 }, + { "[[(^HHHHHHHHHHHH(\?imsximx:HH(HHHHHH(\?{HH[HH])qjR>9))i})]a!" + "lBW3p{A=or)ShE%[:punct:]{}]5r", + 0, 0 }, + { "[:pu[nc[^t:]]]}}}}}}}[}}}}}}}(\?#}])@@@@@@@@@@@@@@@@@@" + "DDDDDDDDDDDDDDDDDDD\?]xA2\?", + 0, 0 }, + { "(.[:alpha:]xB7[:alnu(\?{m:]})RRRRRRRRRRRRRRRRRRRRRRRRRRRL)[:" + "space:]G\?", + 1, 0 }, { "[:blan(\?<!(\?=kcntrl:]){71,})!ooooooooooooN", 0, 0 }, { "()e$$$$$$$$$$$$$$$$$$$$iiiiiiii", 1, 0 }, - { "(b[:ascii:]67777777777777777777777777)({-106}kkk^F-------------------------------{13}A)f00000000sBAddddd{-66}kd!D'", 2, 0 }, - { "(Q ^])[^lf][:space:][:lowerprint:]\?", 1, 0 }, - { "[[^]\\S{152}W![:digit:][[^:space:(\?(]=pEhwY][:alnum:][:digit):][:graph:]])QQIC9h-oowf[:xdigit:]{-52}{,190}1111111111111111111fX{-189,226}W", 0, 0 }, - { "[^(\?!(\?<=)]).h[:as(\?>cii:])[:alnum:]$$$$$[:space:]3$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1", 0, 0 }, - { "[[$zQ================(\?<!=(\?>=========(\?====D[^))|i{}\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)][:s(pace:]]))]", 0, 0 }, - { "[^{,-[15(\?#6}]Vwjjjjjjjj[jjjjjjjjjjjjjjjjjjS9999)]q]rWWWWWWWWWWWWWWWW[:punct:]@@@@@@@@@@@@@@@@@@@@@@@@gO[:blankcntrl:]>L[:ascii:]:::::::::::::::::::x11uuuuuuuuuuuuuuuuuuuuuuuuuuuuu{-124,114}[:graph:]C#{tcg[:xdigit:]gZZZZ[:lowerprint:]nA(_{{{{{{{{{{{{{{{{{{{{SS)\\D[:alpha:]", 1, 0 }, - { "[^(\?())]!T\?[:asc[^ii:]E:4},,]I[^b(\?:n4(njj~+{\?'k{7}{189,-194}{ig.[[[[[[(\?#[[[_bs6,JD`1(\?<!WBo]F+{d*VO22z2K1][:xdigit:]))Suuuuuuuuuuu[^u{,117}\?YYYYYYYYYYYYYYYYYYYYYYYYB^]|q]:eY1GGGGGGGGGGGGGGGGGGGGGGGGGGGGe\?)bU[:punct:]", 0, 0 }, - { "[\?UA(\?:]\?)[:xdigit:]A^mmmmmmmmmmmmmm>>>>>>>>>>>>>>>>>>>>>>>>>>>>[^>>>(\?(>)){,-165}]", 0, 0 }, - { "([^[][^n(\?{[[p]#})|][^]L|66666666666[:graph:]][:graph:]2[:xdigit:][:space:]9b})[:digit(\?imsximsx::]+PZ):{}|E)[:xdigit[^:]|>]^[:alpha:]::::::::[:ascii:]````[:ascii:]:", 1, 0 }, + { "(b[:ascii:]67777777777777777777777777)({-106}kkk^F----------" + "---------------------{13}A)f00000000sBAddddd{-66}kd!D'", + 2, 0 }, + { "(Q ^])[^lf][:space:][:lowerprint:]\?", + 1, 0 }, + { "[[^]\\S{152}W![:digit:][[^:space:(\?(]=pEhwY][:alnum:][:" + "digit):][:graph:]])QQIC9h-oowf[:xdigit:]{-52}{,190}" + "1111111111111111111fX{-189,226}W", + 0, 0 }, + { "[^(\?!(\?<=)]).h[:as(\?>cii:])[:alnum:]$$$$$[:space:]3$$$$$$" + "$$$$$$$$$$$$$$$$$$$$$$$$$1", + 0, 0 }, + { "[[$zQ================(\?<!=(\?>=========(\?====D[^))|i{}" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)][:s(pace:]])" + ")]", + 0, 0 }, + { "[^{,-[15(\?#6}]Vwjjjjjjjj[jjjjjjjjjjjjjjjjjjS9999)]q]" + "rWWWWWWWWWWWWWWWW[:punct:]@@@@@@@@@@@@@@@@@@@@@@@@gO[:" + "blankcntrl:]>L[:ascii:]:::::::::::::::::::" + "x11uuuuuuuuuuuuuuuuuuuuuuuuuuuuu{-124,114}[:graph:]C#{tcg[:" + "xdigit:]gZZZZ[:lowerprint:]nA(_{{{{{{{{{{{{{{{{{{{{SS)\\D[:" + "alpha:]", + 1, 0 }, + { "[^(\?())]!T\?[:asc[^ii:]E:4},,]I[^b(\?:n4(njj~+{\?'k{7}{189," + "-194}{ig.[[[[[[(\?#[[[_bs6,JD`1(\?<!WBo]F+{d*VO22z2K1][:" + "xdigit:]))Suuuuuuuuuuu[^u{,117}\?YYYYYYYYYYYYYYYYYYYYYYYYB^]" + "|q]:eY1GGGGGGGGGGGGGGGGGGGGGGGGGGGGe\?)bU[:punct:]", + 0, 0 }, + { "[\?UA(\?:]\?)[:xdigit:]A^mmmmmmmmmmmmmm>>>>>>>>>>>>>>>>>>>>>" + ">>>>>>>[^>>>(\?(>)){,-165}]", + 0, 0 }, + { "([^[][^n(\?{[[p]#})|][^]L|66666666666[:graph:]][:graph:]2[:" + "xdigit:][:space:]9b})[:digit(\?imsximsx::]+PZ):{}|E)[:" + "xdigit[^:]|>]^[:alpha:]::::::::[:ascii:]````[:ascii:]:", + 1, 0 }, { "[:lowerprint(\?<!:])", 0, 0 }, - { "[[^[]{-47}[:lowerprint:][:punct:]L[(\?::g(raph:]lY[:alnum:])qWYU)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}[c%$dp5[:alnum:]DDDDDDDD^^%&{,-94}E]{-8,175}[:alpha:]-.^[:digi(t:]CCCC(CCCCCCCCC]).ax72)", 1, 0 }, - { "[[^($$$$$$$$$$$$$$$$$$[^$I((\?{\?(u)\"YuK ZpOHq[!(\?>t|LQT(|)L[(:ascii:])", 0, 0 }, - { "[^[^([:graph:](QpPdyDQ`[:alpha:](.X[:digit:]wwwwwwwwwwwwww(\?imxims:wwwwwwwe(\?<!z)ONNN(\?#)[^])[:space:](KKKKKKKKK{113,}327[:xdigit:]k)]CeeeeeeeeeeeeeeeeeMMMMMMMMMMMMMMMMM)[:lowerprint:]]HHHHHHHHHHHHHHHHHHH]]]]]]]]]]]]]", 1, 0 }, - { "[Q(r(\?=)v]dm[:alnum:][:b(\?{lankcntrl:][:xdigit(\?=:])})P[:graph:]bd/Rx){50}{-150,-172}", 0, 0 }, + { "[[^[]{-47}[:lowerprint:][:punct:]L[(\?::g(raph:]lY[:alnum:])" + "qWYU)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}[c%$dp5[:alnum:]DDDDDDDD^" + "^%&{,-94}E]{-8,175}[:alpha:]-.^[:digi(t:]CCCC(CCCCCCCCC])." + "ax72)", + 1, 0 }, + { "[[^($$$$$$$$$$$$$$$$$$[^$I((\?{\?(u)\"YuK " + "ZpOHq[!(\?>t|LQT(|)L[(:ascii:])", + 0, 0 }, + { "[^[^([:graph:](QpPdyDQ`[:alpha:](.X[:digit:]wwwwwwwwwwwwww(" + "\?imxims:wwwwwwwe(\?<!z)ONNN(\?#)[^])[:space:](KKKKKKKKK{" + "113,}327[:xdigit:]k)]CeeeeeeeeeeeeeeeeeMMMMMMMMMMMMMMMMM)[:" + "lowerprint:]]HHHHHHHHHHHHHHHHHHH]]]]]]]]]]]]]", + 1, 0 }, + { "[Q(r(\?=)v]dm[:alnum:][:b(\?{lankcntrl:][:xdigit(\?=:])})P[:" + "graph:]bd/Rx){50}{-150,-172}", + 0, 0 }, { "[(\?(im(\?:sxims:))9]))L", 0, 0 }, { "[[^[(\?{^Z][^0[:alpha:]]\\XB*{-151}t})][:alnum:]]", 0, 0 }, - { "[([(D\?/////////////////////.'yvYysU&5AU-]kV)*){,123}z]", 0, 0 }, - { "[:alnu(\?{m:][:a(\?=lpha:][:alpha:])n}))7[:ascii:][:xdigit:][:punct:]-", 0, 0 }, + { "[([(D\?/////////////////////.'yvYysU&5AU-]kV)*){,123}z]", 0, + 0 }, + { "[:alnu(\?{m:][:a(\?=lpha:][:alpha:])n}))7[:ascii:][:xdigit:]" + "[:punct:]-", + 0, 0 }, { "[^[:graph:]IIIIIIIIIIIIIIIIIIIIIII][:sp(\?<!ace:])", 0, 0 }, - { "[[[(\?=[[[cDD(\?<!D(\?:DDDDDDDDDDDD(\?<=DDD(DDDDDD(\?:DDDDDDD(\?<=D(\?()])rvp{243,}D$<[:space:]([:lowerpr)int:])])Ea{}U[:upperword:][:xdigit(\?#:]or}Z+34gD{/P NJ", 1, 0 }, + { "[[[(\?=[[[cDD(\?<!D(\?:DDDDDDDDDDDD(\?<=DDD(DDDDDD(\?:" + "DDDDDDD(\?<=D(\?()])rvp{243,}D$<[:space:]([:lowerpr)int:])])" + "Ea{}U[:upperword:][:xdigit(\?#:]or}Z+34gD{/P NJ", + 1, 0 }, { "[^(,H>)*d2K0DNX5)T(].)[:digit:].", 0, 0 }, - { "([:punct:(\?#])})JJJJJJJJ[:xdigit:]PPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU.......................0hSk{,89}[:xdigit:].[:xdigit:]Z", 1, 0 }, - { "(LGTTTTTTTTTTTTTTTTTTTTTTTTTT[:alpha:]){-106,113}[:punct:]d|[:digit:]kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\?wP", 1, 0 }, - { "([^[^<N_-k\?{(\?#18}]i]::::::::::::::::::::::::::)1+LLLLn{}/){-198}", 1, 0 }, - { "([[^(AAAAAAAAAA(\?(AAAAA)AAAAf).LzHHHHHHHHHHHHHHHHHHHHH(\?#HHHHH|)[ZEEEEE(\?#EEEEEEEEE(\?<!EEEEEEEEsG)q[:punct:]{}][:upperword:]D)[:space:][:digit:]+e[:ascii:]].i|JJJJJJJJ+n][:xdigit:]Se)P[:lowerprint:]_______________________________.[:punct:]pP{-172,86}iiiiiiiiiiiiiiiiiiiiiiiii){,-178}", 1, 0 }, - { "([\?=[[^,BDRRPZ{129}*D-[:punct:]]])([:upperword:]ud)\?][:punct:]A", -1, 0 }, - { "(([(\?#((\?{\?=^])c-)C[:lowerprint:]xvkR}k\")ccccccccccccccccccccNNNNNNN[:alp[ha:]{,93}vhlX:|A]2})nSw)]N.", 2, 0 }, + { "([:punct:(\?#])})JJJJJJJJ[:xdigit:]" + "PPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU.......................0hSk{" + ",89}[:xdigit:].[:xdigit:]Z", + 1, 0 }, + { "(LGTTTTTTTTTTTTTTTTTTTTTTTTTT[:alpha:]){-106,113}[:punct:]d|" + "[:digit:]kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\?wP", + 1, 0 }, + { "([^[^<N_-k\?{(\?#18}]i]::::::::::::::::::::::::::)1+LLLLn{}/" + "){-198}", + 1, 0 }, + { "([[^(AAAAAAAAAA(\?(AAAAA)AAAAf).LzHHHHHHHHHHHHHHHHHHHHH(\?#" + "HHHHH|)[ZEEEEE(\?#EEEEEEEEE(\?<!EEEEEEEEsG)q[:punct:]{}][:" + "upperword:]D)[:space:][:digit:]+e[:ascii:]].i|JJJJJJJJ+n][:" + "xdigit:]Se)P[:lowerprint:]_______________________________.[:" + "punct:]pP{-172,86}iiiiiiiiiiiiiiiiiiiiiiiii){,-178}", + 1, 0 }, + { "([\?=[[^,BDRRPZ{129}*D-[:punct:]]])([:upperword:]ud)\?][:" + "punct:]A", + -1, 0 }, + { "(([(\?#((\?{\?=^])c-)C[:lowerprint:]xvkR}k\")" + "ccccccccccccccccccccNNNNNNN[:alp[ha:]{,93}vhlX:|A]2})nSw)]" + "N.", + 2, 0 }, { "()g/qzyiV(x3d|A0wllllll){162}[:space:]", 2, 0 }, - { "qqqqqqqqqqqqqqqqqqqqvvvvvvvvvvvv8[:x(\?imsxmsx:digit:][:alpha:]''''''''''''''''''''''''''')", 0, 0 }, + { "qqqqqqqqqqqqqqqqqqqqvvvvvvvvvvvv8[:x(\?imsxmsx:digit:][:" + "alpha:]''''''''''''''''''''''''''')", + 0, 0 }, { "({,226}nf^W=vs$xK^=A=M#b,)V", 1, 0 }, - { "(_T 2BC9N'cccccccccc-87EF#&^eQfDDDn._,m&c`tjAwR #~A)[:(\?imsimx:alpha:])/yHYL6|{-40,47}", 1, 0 }, + { "(_T 2BC9N'cccccccccc-87EF#&^eQfDDDn._,m&c`tjAwR " + "#~A)[:(\?imsimx:alpha:])/yHYL6|{-40,47}", + 1, 0 }, { "[[^]{-8(4,138})z[:xdigit:]{180,}]", 1, 0 }, - { "[([^T____________________(\?:__C(\?<=]-)])+[:ascii:])r[:graph:].----------", 0, 0 }, - { "[f{}LLLL(LLp((((\?<!((((((((((((((({,56}]BR`{,52}){-22,}\?[:space:]h>Sow", 0, 0 }, + { "[([^T____________________(\?:__C(\?<=]-)])+[:ascii:])r[:" + "graph:].----------", + 0, 0 }, + { "[f{}LLLL(LLp((((\?<!((((((((((((((({,56}]BR`{,52}){-22,}\?[:" + "space:]h>Sow", + 0, 0 }, { "{-179}^[:alpha:(\?!].a'5wacA3\\\\\\\\AAAAAAAA)~^]wC", 0, 0 }, - { ">[:digit:]{,-212}+(`)LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL[:ascii:][:digit:][:space:]", 1, 0 }, + { ">[:digit:]{,-212}+(`)LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL[:ascii:" + "][:digit:][:space:]", + 1, 0 }, { "[[^[[^RBW{,255(}(\?(\?>=(W)_]uu][:blankcntrl:])O)]]", 0, 0 }, { "(C_______________________________)2", 1, 0 }, { "([/ntf_a3].)", 1, 0 }, - { "[:space:]+[(:upperword:],c7[:asci(\?<=i:]ggggggggggg)[:ascii:]/1$$$$$$$$$$$$$$$$$$$$$$$$$$)", 0, 0 }, - { "Xq{109}~EEEEEEEE[:upper[^word:]lgB:X(h[:alpha:]B[:space:]].)IkaH@3}}H'yK~\?[:upperw(\?#ord:(\?:]){=================[:blankcntrl:])", 1, 0 }, - { "(([[^]]$3Xr^$%%%%%%%%%%%%%%%%%%%%%================U[:ascii:])X).FFFFFFFFFFgO[:punct:]oooooooooooooooooooBC[:blankcntrl:]mmmmmmmmmmmmmmmmmmmm[:lowerprint:]rBM~<HAc#Sb&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Cy", 2, 0 }, - { "([([([^(\?:)D]-{M#H >rERRRRRRR[^RRRRR(\?>RRRRR])[(\?=^)X]{207,}U])))Z[:blankcntrl:]]yyyyyyyyyyyyyyyy\?", 1, 0 }, - { "[Q(\?{*[^(\?(\?!!])[:graph:]]})[:alnum:]iE)dGGGGGGG[^GGGGGGGGGG[:xdigit:]w]", 0, 0 }, + { "[:space:]+[(:upperword:],c7[:asci(\?<=i:]ggggggggggg)[:" + "ascii:]/1$$$$$$$$$$$$$$$$$$$$$$$$$$)", + 0, 0 }, + { "Xq{109}~EEEEEEEE[:upper[^word:]lgB:X(h[:alpha:]B[:space:]].)" + "IkaH@3}}H'yK~\?[:upperw(\?#ord:(\?:]){=================[:" + "blankcntrl:])", + 1, 0 }, + { "(([[^]]$3Xr^$%%%%%%%%%%%%%%%%%%%%%================U[:ascii:]" + ")X).FFFFFFFFFFgO[:punct:]oooooooooooooooooooBC[:blankcntrl:]" + "mmmmmmmmmmmmmmmmmmmm[:lowerprint:]rBM~<HAc#Sb&&&&&&&&&&&&&&&" + "&&&&&&&&&&&&&&Cy", + 2, 0 }, + { "([([([^(\?:)D]-{M#H " + ">rERRRRRRR[^RRRRR(\?>RRRRR])[(\?=^)X]{207,}U])))Z[:" + "blankcntrl:]]yyyyyyyyyyyyyyyy\?", + 1, 0 }, + { "[Q(\?{*[^(\?(\?!!])[:graph:]]})[:alnum:]iE)dGGGGGGG[^" + "GGGGGGGGGG[:xdigit:]w]", + 0, 0 }, { "[^Z(\?!6(\?(\?><=)[:graph:])]BBBBBBBBBBBBBBBB^)", 0, 0 }, - { "[[^([^[^][[[[[[[(\?({[[(\?(\?imsxmsx(\?imsi[ms:::[[[[[[[[[}))]$)){12,})|:::::::::::::::::::[:lowerprint:]{}{-96,-147}){13,}`[:digit:]]\"^Ca%%%%%%%%%%%%%%%%%%%%%%%%%%UUUUUUUUUUUUUUUUUU]]9", 0, 0 }, - { "[^(\?(\?(\?#!<=))JLBS\"zi)'''''''''''['''''''''''''piiiiiiiiiiiii(\?<=iiii]])ZZZZZZZZZZZZZZZZZZ[:space:]", 0, 0 }, + { "[[^([^[^][[[[[[[(\?({[[(\?(\?imsxmsx(\?imsi[ms:::[[[[[[[[[})" + ")]$)){12,})|:::::::::::::::::::[:lowerprint:]{}{-96,-147}){" + "13,}`[:digit:]]\"^Ca%%%%%%%%%%%%%%%%%%%%%%%%%%" + "UUUUUUUUUUUUUUUUUU]]9", + 0, 0 }, + { "[^(\?(\?(\?#!<=))JLBS\"zi)'''''''''''['''''''''''''" + "piiiiiiiiiiiii(\?<=iiii]])ZZZZZZZZZZZZZZZZZZ[:space:]", + 0, 0 }, { "({})[:punct:]", 1, 0 }, { "E9[:blankc(\?{ntrl:]})N", 0, 0 }, { "[:alph(\?#a:]){198,}sq\?X0B7", 0, 0 }, - { "[^\\\\\\\\(\\\\\\[\\\\\\\\\\\\[(\?<(\?isximsx:={11(\?(9,}\?0])]]))\?FN3M\?{-128,}Z444444)444fbLiVN8)", 0, 0 }, - { "[[^[^([[[[[[[[[(\?>[[[[[[[[[[[[[[[[[[[[[{53(\?<=,-175(\?>}ggggggggggggggggg%))[:alnum:])[:punct:]kkkkkkkkkkkkkkkkkkkkkkkkk)+Soooooooooooooooooooooooooooooooo](WR+--)x36+llllllllllll{,35}]Fqb^=F]KKKKKKaaaaa{,131}", 1, 0 }, - { "(g\"Ssqw<&{Cl{82,}Mdf|9cIlmCW{}[:digit:]4C{}[:alnum:]PP)", 1, 0 }, - { "OOOOOOOU[*evVIIIIIIIIIIIIIIIII(\?#(\?#IIII)]PP[:xdigit:]2222222222222222[:xdigit:]Kx)p[:digit:]", 0, 0 }, + { "[^\\\\\\\\(\\\\\\[\\\\\\\\\\\\[(\?<(\?isximsx:={11(\?(9,}" + "\?0])]]))\?FN3M\?{-128,}Z444444)444fbLiVN8)", + 0, 0 }, + { "[[^[^([[[[[[[[[(\?>[[[[[[[[[[[[[[[[[[[[[{53(\?<=,-175(\?>}" + "ggggggggggggggggg%))[:alnum:])[:punct:]" + "kkkkkkkkkkkkkkkkkkkkkkkkk)+" + "Soooooooooooooooooooooooooooooooo](WR+--)x36+llllllllllll{," + "35}]Fqb^=F]KKKKKKaaaaa{,131}", + 1, 0 }, + { "(g\"Ssqw<&{Cl{82,}Mdf|9cIlmCW{}[:digit:]4C{}[:alnum:]PP)", 1, + 0 }, + { "OOOOOOOU[*evVIIIIIIIIIIIIIIIII(\?#(\?#IIII)]PP[:xdigit:]" + "2222222222222222[:xdigit:]Kx)p[:digit:]", + 0, 0 }, { "([[{248,16(\?=5(\?#}][:alpha:])|[:p(\?!unct:(\?(]", 1, 0 }, - { "[pP((\?=S)(\?#)]$[:aln(\?(um:)]2\?)$GGGGGGGGGGGGGGGGG({-U:c){-61,}[:ascii:]{-202}G", 1, 0 }, + { "[pP((\?=S)(\?#)]$[:aln(\?(um:)]2\?)$GGGGGGGGGGGGGGGGG({-U:c)" + "{-61,}[:ascii:]{-202}G", + 1, 0 }, { "()$D[:alnum:]", 1, 0 }, { "[(\?#^]){}[:ascii:]", 0, 0 }, - { "[uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu]FFFFFFFFFFFFFFFFFFFFFF&2e\?)%oP'mc@z2b}n{<b4_Laz^0LLLLLLLLLLLLLLLLLLLLLLL,,,d", 0, 0 }, + { "[uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu]FFFFFFFFFFFFFFFFFFFFFF&2e\?)" + "%oP'mc@z2b}n{<b4_Laz^0LLLLLLLLLLLLLLLLLLLLLLL,,,d", + 0, 0 }, { "{}(^________________''|$)RRRRRRRRRRRRRRRRRRR", 1, 0 }, - { "(H)####################bbbbbbbbbbbbbbbbVSSSSSSSSSSS|tdU\"goeAbPP{-248,81}", 1, 0 }, - { "[^[(\?ims(\?>xisx:)UHpP*n{}]{}fx14<7OEpE>n2150)8888888888888888]^GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGS", 0, 0 }, + { "(H)####################bbbbbbbbbbbbbbbbVSSSSSSSSSSS|" + "tdU\"goeAbPP{-248,81}", + 1, 0 }, + { "[^[(\?ims(\?>xisx:)UHpP*n{}]{}fx14<7OEpE>n2150)" + "8888888888888888]^GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGS", + 0, 0 }, { "(d)+", 1, 0 }, { "[^.(\?(>)(\?=e)])al[:space:]x", 0, 0 }, { "[^256c(\?!]){-19,}", 0, 0 }, { "Q)", 0, 0 }, - { "[^s\?\?(\?{\?\?\?(\?#\?(\?<!\?\?\?\?\?\?\?\?\?\?\?(\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{}]F\?j(jjjjjjjjjjjjjjjjjjn)kTI1f[{1|(\?<=^[^+[:digit:]{}^s^))})))T]{-17}{CCCCCCCCCCa{-21,}{,-146}^uZQB]YuLu-|tUGRMz^^", 1, 0 }, + { "[^s\?\?(\?{\?\?\?(\?#\?(\?<!\?\?\?\?\?\?\?\?\?\?\?(" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{}]F\?j(jjjjjjjjjjjjjjjjjjn)" + "kTI1f[{1|(\?<=^[^+[:digit:]{}^s^))})))T]{-17}{CCCCCCCCCCa{-" + "21,}{,-146}^uZQB]YuLu-|tUGRMz^^", + 1, 0 }, { "([^.{}.EE[EEEEEEEE(\?<=EEEEEEEEEEEEEEEU]]-@s))$", 1, 0 }, - { "[^([((\?#[#])|a)])[cccccccccccccccc][:digit:]LLLLLLL[:alnum:]}[P%vzl{}^]&", 0, 0 }, + { "[^([((\?#[#])|a)])[cccccccccccccccc][:digit:]LLLLLLL[:alnum:" + "]}[P%vzl{}^]&", + 0, 0 }, { "({}[:space:]E)101+A{-35,11}", 1, 0 }, { "(va:7)u[:alpha:]", 1, 0 }, - { "([^[[rrrrrrrrrr(\?:rrrrrrrrrr(\?<!rrrrrrrrry|D'*AH@a{}\?[:space:][:alpha:]^]$ {-225}[(\?(:as)(\?(>cii:])){-107,-139}6/{^[:upperw(\?imsxmsx:ord:]{,-47} ]wuH#nAn)GGGGGGGGGGGGGGGGGr[)]T{91}lJ))[:lowerprint:][:xdigit:][:lowerprint:])]*", 1, 0 }, + { "([^[[rrrrrrrrrr(\?:rrrrrrrrrr(\?<!rrrrrrrrry|D'*AH@a{}\?[:" + "space:][:alpha:]^]$ " + "{-225}[(\?(:as)(\?(>cii:])){-107,-139}6/" + "{^[:upperw(\?imsxmsx:ord:]{,-47} " + "]wuH#nAn)GGGGGGGGGGGGGGGGGr[)]T{91}lJ))[:lowerprint:][:" + "xdigit:][:lowerprint:])]*", + 1, 0 }, { "()[:space:]~!$[:alnum:]JJJJ[:ascii:]", 1, 0 }, { "[^(\?<=)-]()k", 1, 0 }, { "(()W){,8}ea", 2, 0 }, - { "({,-56}5G&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrk.8) hWJ,TM)0Yd-", 1, 0 }, + { "({,-56}5G&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrk.8) hWJ,TM)0Yd-", 1, + 0 }, { "(Z-fddddddddddddddddddddddd)-{9}", 1, 0 }, { "[^<[(\?!:asc(\?:i(\?<!i:])F])[:alp(ha:]b))-}Wwx8B", 0, 0 }, - { "[^[^[^([(\?{}(\?=)(\?())-CCCCCCCCCCC(\?=CCCCCCCC(CCCCC(\?:CCCCCCCC(\?{l[(\?!:space:]})[:upperwor(\?:d:]{-27}[:al[^pha:][:xdigit:]^f", 0, 0 }, - { "[[^]G@>2!+[:punct:(\?<!]{,189}6ZF[:blankcntrl:][:digit:]{,214}){-115,-14}l[:upperword:]{101,}Z[:ascii:]Ld&02|c]<0~<bc", 0, 0 }, + { "[^[^[^([(\?{}(\?=)(\?())-CCCCCCCCCCC(\?=CCCCCCCC(CCCCC(\?:" + "CCCCCCCC(\?{l[(\?!:space:]})[:upperwor(\?:d:]{-27}[:al[^pha:" + "][:xdigit:]^f", + 0, 0 }, + { "[[^]G@>2!+[:punct:(\?<!]{,189}6ZF[:blankcntrl:][:digit:]{," + "214}){-115,-14}l[:upperword:]{101,}Z[:ascii:]Ld&02|c]<0~<bc", + 0, 0 }, { "(Q)[:digit:]x", 1, 0 }, - { "hT[[:alnum:]\?]O[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxFF%^(\?(_LN 8uXQT\"*/L)+l)>qQ[^]e[:ascii:]PP()[:digit:]NQ8%6d=&2I{-62,-142}w]].e{}*", 1, 0 }, - { "{,-219}xxxtEEEEEEEEEEEEEEEE[:pun(\?(ct:])qqq)nnnnnnnnnnnnnnnnnnnnnnnnnnn", 0, 0 }, + { "hT[[:alnum:]\?]O[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxFF%^(\?(_" + "LN " + "8uXQT\"*/" + "L)+l)>qQ[^]e[:ascii:]PP()[:digit:]NQ8%6d=&2I{-62,-142}w]].e{" + "}*", + 1, 0 }, + { "{,-219}xxxtEEEEEEEEEEEEEEEE[:pun(\?(ct:])qqq)" + "nnnnnnnnnnnnnnnnnnnnnnnnnnn", + 0, 0 }, { "[:di(\?>git:])W4", 0, 0 }, { "([^y])Fkvto$", 1, 0 }, - { "[^($$$$$$(\?!$$$$$(\?{$$$$$$(\?<=$$$$$$$$$$$+===)[:alnum:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM)Z]{}^[:blankcntrl:]--xxxxxxxxxxxxxxx[^xxxxxxx)\?tVG\?{232,81}{121,}xn{,-226}})tttttttttttttttttttttttmu(\?<!&&&&&&&&&&&&&&&&&&&&&&0b]z)$87{,-192}{}{-242,}", 0, 0 }, + { "[^($$$$$$(\?!$$$$$(\?{$$$$$$(\?<=$$$$$$$$$$$+===)[:alnum:]" + "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM)Z]{}^[:blankcntrl:]--" + "xxxxxxxxxxxxxxx[^xxxxxxx)\?tVG\?{232,81}{121,}xn{,-226}})" + "tttttttttttttttttttttttmu(\?<!&&&&&&&&&&&&&&&&&&&&&&0b]z)$" + "87{,-192}{}{-242,}", + 0, 0 }, { "l[:dig(\?(it:]|s*)aA[:digit(\?<=:].^.))x[:digit:]", 0, 0 }, { "[:grap[^(\?#h:]').]Z", 0, 0 }, - { "[:gra[^ph:]t[:digit:]222222222222(22222222222222222H qM]pWZr[:ascii:]-hRb_.)Q{-228,-204}{}", 1, 0 }, + { "[:gra[^ph:]t[:digit:]222222222222(22222222222222222H " + "qM]pWZr[:ascii:]-hRb_.)Q{-228,-204}{}", + 1, 0 }, { "AAAAAAAAAAAAAAA(AA)YeX", 1, 0 }, { "(!dqqqF*^){(,-79}s!!!!!!!!!!!!)", 2, 0 }, - { "[^(\?msxm(\?#sx:]|)ZHYup)j{95}0L:vXB#')d'DX\?m.T034\\\\\\\\\\\\\\\\\\\\\\y5rV{}S", 0, 0 }, - { "(W*O+yl([\?!P(\?:)I]${}{-195,-14}[:upperword:]{}[:xdi[^git:][:space:]X[:grap[^h:]~]zzzzzzzzzzzzzzzzzzzzzzzL)+)Y b.-=jf{-216,}${/!}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|]", 2, 0 }, - { "[^\\\\\\\\\\(\?<=\\\\\\\\\\\\\\\\m]{-48,234}[:alpha:]s)", 0, 0 }, - { "[(\?{U}(\?<!)])LLLLLLLLLLLLLLsssssssssssssssssssssssssss[:ascii:][:blankcntrl:]---------b", 0, 0 }, - { "[^[^[(\?#)(\?imsxims[x:)<<<<[<<<<<<<<<<(\?<!<<<<<<<([^\?(<<<<<<<<<<z(\?(zu(\?<=~83}aZpIE)[:alnum:](\?imsximsx:(\?!jrE6(\?<!\?V(SzDU)000[000000000((\?=\?)=0])L|lOYuWXk", 0, 0 }, - { "$o[:dig(it:]nnnnnnnnnnnnnnn{-94}|G)[:alpha(\?!:] {,-108}D=\?>[:digit:]S[:space:]t", 0, 0 }, + { "[^(\?msxm(\?#sx:]|)ZHYup)j{95}0L:vXB#')d'DX\?m." + "T034\\\\\\\\\\\\\\\\\\\\\\y5rV{}S", + 0, 0 }, + { "(W*O+yl([\?!P(\?:)I]${}{-195,-14}[:upperword:]{}[:xdi[^git:]" + "[:space:]X[:grap[^h:]~]zzzzzzzzzzzzzzzzzzzzzzzL)+)Y " + "b.-=jf{-216,}${/!}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|]", + 2, 0 }, + { "[^\\\\\\\\\\(\?<=\\\\\\\\\\\\\\\\m]{-48,234}[:alpha:]s)", 0, + 0 }, + { "[(\?{U}(\?<!)])LLLLLLLLLLLLLLsssssssssssssssssssssssssss[:" + "ascii:][:blankcntrl:]---------b", + 0, 0 }, + { "[^[^[(\?#)(\?imsxims[x:)<<<<[<<<<<<<<<<(\?<!<<<<<<<([^\?(<<<" + "<<<<<<<z(\?(zu(\?<=~83}aZpIE)[:alnum:](\?imsximsx:(\?!jrE6(" + "\?<!\?V(SzDU)000[000000000((\?=\?)=0])L|lOYuWXk", + 0, 0 }, + { "$o[:dig(it:]nnnnnnnnnnnnnnn{-94}|G)[:alpha(\?!:] " + "{,-108}D=\?>[:digit:]S[:space:]t", + 0, 0 }, { "()n", 1, 0 }, { "[:upp(erword:]$)<}.vZM<lEY5Y*", 0, 0 }, - { "[^([^\?>)rCD&{5(\?msxisx:7,}qqqqqqqqqqqqqqqqqq{31,}@w#W:(@(\?:zp$YYYYA[:alpha:]{1}A)*dZJ\"5OG|\?(\?#a])]|){-150}[:xdigit:]", 0, 0 }, - { "[($)gwo{`\"]{-160,}\\\\\\\\\\\\\\\\\\\\\\\\\\66666666666666888888888888", -1, 1 }, - { "((}DA+Rc000000000000000000)%vvvvvvvvvvvvvvvvvvvvv%C&emZ*[:alnum:]#m/D[:graph:][:blank[^cntrl:]E{,168})kkkkkkkkkk000000000000000]", 2, 0 }, - { "[^[u*(\?#x01234)oxGGGGG(\?([GGGG)GGGGGGGGG]^U)!!CCCCBM`4QB^XEN]{,-60}[:upperword:]G]", 0, 0 }, + { "[^([^\?>)rCD&{5(\?msxisx:7,}qqqqqqqqqqqqqqqqqq{31,}@w#W:(@(" + "\?:zp$YYYYA[:alpha:]{1}A)*dZJ\"5OG|\?(\?#a])]|){-150}[:" + "xdigit:]", + 0, 0 }, + { "[($)gwo{`\"]{-160,}" + "\\\\\\\\\\\\\\\\\\\\\\\\\\66666666666666888888888888", + -1, 1 }, + { "((}DA+Rc000000000000000000)%vvvvvvvvvvvvvvvvvvvvv%C&emZ*[:" + "alnum:]#m/" + "D[:graph:][:blank[^cntrl:]E{,168})" + "kkkkkkkkkk000000000000000]", + 2, 0 }, + { "[^[u*(\?#x01234)oxGGGGG(\?([GGGG)GGGGGGGGG]^U)!!CCCCBM`4QB^" + "XEN]{,-60}[:upperword:]G]", + 0, 0 }, { "(%)~t{S,K^MI3PMo)=b", 1, 0 }, - { "[[[^]{}eU([:xdigit:]&&&&&&&&&&&&&&&&&)\"W|43[:alpha:][:graph:]J8b[:blankcntrl:]gggggQ{,183}{,-254}\?[:ascii(:]{,134}", 1, 0 }, - { "[[([^[^([^(\?=)1RRRRRRRRRRRRRRRRRRRRRR(\?:(\?(\?(\?!=#RRRRR(\?=RRRR(\?<[^!Ru)])]o[:[graph:[^]{,7})[:digit(\?::]{-215,}e[:space:]]", 0, 0 }, - { "({{{{{{{{{{{{{{{{{{KKKKKKKKKKKKKKKKKKKKKKKKKKKKBBBBBBBBBBBB)[:space:]0[:alnum:]HcctQA", 1, 0 }, - { "[^(pP7(HsN[^g{186,-87}\?\?]EQ%u:-Y)+>>>>>>>>>>>>>>>>>>>>>pP][:alpha:]", 0, 0 }, - { "[(.{141}h|)((\?:\?=@Q} ghcC{+*(R)D+][:lo(\?#werprint:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz))", 0, 0 }, + { "[[[^]{}eU([:xdigit:]&&&&&&&&&&&&&&&&&)\"W|43[:alpha:][:" + "graph:]J8b[:blankcntrl:]gggggQ{,183}{,-254}\?[:ascii(:]{," + "134}", + 1, 0 }, + { "[[([^[^([^(\?=)1RRRRRRRRRRRRRRRRRRRRRR(\?:(\?(\?(\?!=#RRRRR(" + "\?=RRRR(\?<[^!Ru)])]o[:[graph:[^]{,7})[:digit(\?::]{-215,}e[" + ":space:]]", + 0, 0 }, + { "({{{{{{{{{{{{{{{{{{KKKKKKKKKKKKKKKKKKKKKKKKKKKKBBBBBBBBBBBB)" + "[:space:]0[:alnum:]HcctQA", + 1, 0 }, + { "[^(pP7(HsN[^g{186,-87}\?\?]EQ%u:-Y)+>>>>>>>>>>>>>>>>>>>>>pP]" + "[:alpha:]", + 0, 0 }, + { "[(.{141}h|)((\?:\?=@Q} " + "ghcC{+*(R)D+][:lo(\?#werprint:]" + "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz))", + 0, 0 }, { "[^({}S)PPFl(])-216", 0, 0 }, { "[([[^(((([(\?#^[^[^\?4[(:[dig[^it(\?(:]{122,})y\?", 0, 0 }, - { "[[2${188}u{1(4(\?(1,1(\?{98}e{&tbaoI]q)[:punct:])d}))Nqffffffffffffffffffffffffffff[:ascii:]+]", 0, 0 }, + { "[[2${188}u{1(4(\?(1,1(\?{98}e{&tbaoI]q)[:punct:])d}))" + "Nqffffffffffffffffffffffffffff[:ascii:]+]", + 0, 0 }, { "()K-", 1, 0 }, - { "[[{2(2((\?(\?!()2})])[:alpha:]fVVVVVVVVV{-47}):::::::::::)\?vwyyyyyyyyyyyyyyyyyyyyyyyyy-]{}", 0, 0 }, + { "[[{2(2((\?(\?!()2})])[:alpha:]fVVVVVVVVV{-47}):::::::::::)" + "\?vwyyyyyyyyyyyyyyyyyyyyyyyyy-]{}", + 0, 0 }, { "ivcs)g", 0, 0 }, - { "(hhhh[^hhhh(\?{h\?]})%%%%%%%%%%%%%%%)\"+38mbY:s9{/d# zaNnbQb)b:*zpKI{-26,-189}", 1, 0 }, + { "(hhhh[^hhhh(\?{h\?]})%%%%%%%%%%%%%%%)\"+38mbY:s9{/d# " + "zaNnbQb)b:*zpKI{-26,-189}", + 1, 0 }, { "S*(#)[:graph:]lllllllll&G)t", 1, 0 }, { "([^[(([\?=\?<!)]]___{-63,})]nt", 1, 0 }, - { "[:b(lankcntrl:][:alpha:]*[:pu[^[nct:][:alpha:]A]$aaaaaaaaaaaa*)A[:digit:]U][:alnum:]", 0, 0 }, - { "[^f[^p000{68(\?isxmx:,}(\?!vvvvvv)$)]PP#*{(})[:punct:]&&&&&&&&&&&&&[:punct:]\?][:blankcntrl:]", 1, 0 }, - { "[^(((\?(\?(()))GGGGGGGGG{(\?!($)))((\?!)V^{228,145}))]{-229}Qjjjjj[:punct:]R)", 0, 0 }, - { "[(Q[^((\?{(\?:]~z)})gE(.<){}|)Kuuuuu$*222222222222222222222D]", -1, 0 }, + { "[:b(lankcntrl:][:alpha:]*[:pu[^[nct:][:alpha:]A]$" + "aaaaaaaaaaaa*)A[:digit:]U][:alnum:]", + 0, 0 }, + { "[^f[^p000{68(\?isxmx:,}(\?!vvvvvv)$)]PP#*{(})[:punct:]&&&&&&" + "&&&&&&&[:punct:]\?][:blankcntrl:]", + 1, 0 }, + { "[^(((\?(\?(()))GGGGGGGGG{(\?!($)))((\?!)V^{228,145}))]{-229}" + "Qjjjjj[:punct:]R)", + 0, 0 }, + { "[(Q[^((\?{(\?:]~z)})gE(.<){}|)Kuuuuu$*" + "222222222222222222222D]", + -1, 0 }, { "([^`(\?<=`````[^`````````M]\?)=L74A[:upperword:]]P", 1, 0 }, { "(({}[:space:]qv-T){,-192}{-45}{65}9\?X).d", 2, 0 }, - { "_[(:upperword:]mU(P}qX>\?%)$Lwq[:alpha:]{-115,}================================{127,}", 1, 0 }, + { "_[(:upperword:]mU(P}qX>\?%)$Lwq[:alpha:]{-115,}=============" + "==================={127,}", + 1, 0 }, { "e)", 0, 0 }, { "[{,2[5}Klen+D0'YX(\?<=|_H]I,Y\"*/<3sM[:digit:]])#.", 0, 0 }, - { "[:(xdigit:]){[:digit(\?mxmsx::][:as(\?<=cii:]d!{135})#)pP[:space:]Syyyyyyyyyyyyyyyyyyyy\"Gg8", 0, 0 }, + { "[:(xdigit:]){[:digit(\?mxmsx::][:as(\?<=cii:]d!{135})#)pP[:" + "space:]Syyyyyyyyyyyyyyyyyyyy\"Gg8", + 0, 0 }, { "[(\?()])", 0, 0 }, - { "[^([^[^[[^[:alpha:]SIus[^f<f]}}}}}}}}}}][:xdigit(\?=:]Z{-13}*]_[]LLLL)]E[:alnum:]b$)]]]]]]]]]]]]]]]]]]]]]]]]][:lowerprint:][:ascii:]{,40}{86,}333333333999999999999999999999999999*fffffffffffffffffffffffff99999999U9|[:digit:][:upperword:]oowwwwwwww[wwwwwwwwww{195}[:xdigit:]]H{-73,153}R+zAz{}r/////////////{232,}kAoffffffffff[:blankcntrl:]xxxxxxxxxxxxxxx]KKKKKl0,[:alpha:]|{,-165}Qc{96}CCCCCCCCCCCCCCCCCCCC/", 0, 0 }, - { "{}:V(7O-)[:ascii:][:graph:]PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#", 1, 0 }, - { "[^(\?<[^=CC(CC$)]* c)BBBBBBBBBBBBBBBBBBBBBBB]z{-18,}", 0, 0 }, - { "[[qqqqqqqqqqq(\?(qq235|ttttttttttttttttttttttttttttt[[ttt<<<<(\?{<<<<<<<<<<<<)<<<<<<<<p)/S9(\?{OOOOOOO(\?<!OOOk)})]nIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIb]Z})", 0, 0 }, - { "[^[^(\?>][^((\?<!C(\?!+(\?=)]^8)6nx).)){,-13}[:blankcntrl:]\"(L{}){,29}nnnnn{-83}]l[:upperword:])", 1, 0 }, + { "[^([^[^[[^[:alpha:]SIus[^f<f]}}}}}}}}}}][:xdigit(\?=:]Z{-13}" + "*]_[]LLLL)]E[:alnum:]b$)]]]]]]]]]]]]]]]]]]]]]]]]][:" + "lowerprint:][:ascii:]{,40}{86,}" + "333333333999999999999999999999999999*" + "fffffffffffffffffffffffff99999999U9|[:digit:][:upperword:]" + "oowwwwwwww[wwwwwwwwww{195}[:xdigit:]]H{-73,153}R+zAz{}r/////" + "////////" + "{232,}kAoffffffffff[:blankcntrl:]xxxxxxxxxxxxxxx]KKKKKl0,[:" + "alpha:]|{,-165}Qc{96}CCCCCCCCCCCCCCCCCCCC/", + 0, 0 }, + { "{}:V(7O-)[:ascii:][:graph:]PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#", + 1, 0 }, + { "[^(\?<[^=CC(CC$)]* c)BBBBBBBBBBBBBBBBBBBBBBB]z{-18,}", + 0, 0 }, + { "[[qqqqqqqqqqq(\?(qq235|ttttttttttttttttttttttttttttt[[ttt<<<" + "<(\?{<<<<<<<<<<<<)<<<<<<<<p)/" + "S9(\?{OOOOOOO(\?<!OOOk)})]nIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIb]" + "Z})", + 0, 0 }, + { "[^[^(\?>][^((\?<!C(\?!+(\?=)]^8)6nx).)){,-13}[:blankcntrl:]" + "\"(L{}){,29}nnnnn{-83}]l[:upperword:])", + 1, 0 }, { "[(ZZ\"#(\?#Nb(\?<!:U)oRRRR])Zei${Ec/)s", 0, 0 }, - { "[^[^[(\?(t(\?:3```````)`````)|#CB)/////////////////////////////*!liB#|CCCCCCCCCCCCCC(\?=CCCCCCa7N]weTTTTTTTTTTTTTTTT1{}o\?{}BBBBBBBBBBBBBBBBBBBBBBBB.])u{-218,126}.,[:space:]]", 0, 0 }, - { "[[([:alnum:])yyy(\?!yyyyyyyyyy(\?!yyyyyyyyyyyyyyyyyyy[:graph:]I])Uw*X.^[:ascii:]{,-63}[:digit:]{-88})&&&&&&&&&&&&&&]*", 0, 0 }, - { "[[[^K(\?=KKKKKKKKKKKK(\?:KKKKKKKKK[KKKKKK]]U[:digit:])]dd)({,16})xy+Pu)JJJJJJJJJJJJJJJ[:space:][:ascii:][:upperword:]ql_jywmt4B+]{-30,}^555555555Xza[:punct:]", 1, 0 }, - { "[[^^XXX(\?:XXX((XXXXXXXXXXXXXXXXXXXX)v)$N9$r\"\"\"\"\"\"\"\"\"\"\"\"\"].{,239}$[:punct:]\"9999][:alpha:]{}c){,55}s[:upperword:][:xdigit:]310", 0, 0 }, - { "[@([^I8oNl)]-{-203,-224}{-78,}KKKKKKKKc{-66}[:xdi(\?=git:]==========){}f{-124,}[:upperword:][:lowerprint:]]{}--------l+", 0, 0 }, - { "[^]ozp+0(\?#\"[(\?()X]))[:blankcntrl:][^e{99,222}JJJJJJJJJJJJJJJ3F]\?[:blankcntrl:]l$ot", 0, 0 }, - { "[[^[[((\?isximx:)2222222222(\?=22222[:graph:])+U)((\?{\?<=(\?()iYv8qc@#y)G])+}))FvnP\"7OZ-b273[:ascii:]Ak6*`S[:digit:][:graph:]]{2}^G{79,}DDDDDbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbb)|tP48y{wNJ_S hJbY]]dc", 1, 0 }, + { "[^[^[(\?(t(\?:3```````)`````)|#CB)//////////////////////////" + "///" + "*!liB#|CCCCCCCCCCCCCC(\?=CCCCCCa7N]weTTTTTTTTTTTTTTTT1{}o\?{" + "}BBBBBBBBBBBBBBBBBBBBBBBB.])u{-218,126}.,[:space:]]", + 0, 0 }, + { "[[([:alnum:])yyy(\?!yyyyyyyyyy(\?!yyyyyyyyyyyyyyyyyyy[:" + "graph:]I])Uw*X.^[:ascii:]{,-63}[:digit:]{-88})&&&&&&&&&&&&&&" + "]*", + 0, 0 }, + { "[[[^K(\?=KKKKKKKKKKKK(\?:KKKKKKKKK[KKKKKK]]U[:digit:])]dd)({" + ",16})xy+Pu)JJJJJJJJJJJJJJJ[:space:][:ascii:][:upperword:]ql_" + "jywmt4B+]{-30,}^555555555Xza[:punct:]", + 1, 0 }, + { "[[^^XXX(\?:XXX((XXXXXXXXXXXXXXXXXXXX)v)$N9$" + "r\"\"\"\"\"\"\"\"\"\"\"\"\"].{,239}$[:punct:]\"9999][:alpha:" + "]{}c){,55}s[:upperword:][:xdigit:]310", + 0, 0 }, + { "[@([^I8oNl)]-{-203,-224}{-78,}KKKKKKKKc{-66}[:xdi(\?=git:]==" + "========){}f{-124,}[:upperword:][:lowerprint:]]{}--------l+", + 0, 0 }, + { "[^]ozp+0(\?#\"[(\?()X]))[:blankcntrl:][^e{99,222}" + "JJJJJJJJJJJJJJJ3F]\?[:blankcntrl:]l$ot", + 0, 0 }, + { "[[^[[((\?isximx:)2222222222(\?=22222[:graph:])+U)((\?{\?<=(" + "\?()iYv8qc@#y)G])+}))FvnP\"7OZ-b273[:ascii:]Ak6*`S[:digit:][" + ":graph:]]{2}^G{79,}DDDDDbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbb)|" + "tP48y{wNJ_S hJbY]]dc", + 1, 0 }, { "[:alph(\?{a:]p1[:lowerprint:]}){163,}", 0, 0 }, { "W()", 1, 0 }, - { "()``````````````````````````[:ascii:][:alnum:]{,26}[:graph:]", 1, 0 }, - { "[:al(\?<!num:]|byyy,*)U5%u${190}-{-221,-33}k7777777777777777777777777777777+eXXXXXXXXXXXXXXXXX[X(\?(XX)XX)S'vEAa]*e", -1, 0 }, - { "[^(([R_AC[lE'{2(\?{28(]8LTt[]b[:punct:]]O)|2[:graph:][:space:]}) x3C[:alpha:])uI+dddddddddddddddddddddddd{-165,}FFFFFFFFFFFFFFFFFFFFFFF)cccc*[:upperword:]]G{,-38}{24,}555555555555555555555555555VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVZ[:blankcntrl:][:ascii:]", 0, 0 }, - { "[^QQQQQQQ(\?#QQ(QQQQQQ[:punct:][:space:]){(\?(\?:!}[:graph:]t}}[^}}(}}}}}444444[^444444444444444444444]\?]G)E)L{,-103}{84,}r$ii]-[:alp(\?<=ha:]S5G~9>n*)P<3tttttttttttttttttttttttttt)n{}[:graph:]eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{,83}[:digit:])0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[:alpha:]{-155,}{151,}", 0, 0 }, + { "()``````````````````````````[:ascii:][:alnum:]{,26}[:graph:" + "]", + 1, 0 }, + { "[:al(\?<!num:]|byyy,*)U5%u${190}-{-221,-33}" + "k7777777777777777777777777777777+eXXXXXXXXXXXXXXXXX[X(\?(XX)" + "XX)S'vEAa]*e", + -1, 0 }, + { "[^(([R_AC[lE'{2(\?{28(]8LTt[]b[:punct:]]O)|2[:graph:][:" + "space:]}) " + "x3C[:alpha:])uI+dddddddddddddddddddddddd{-165,}" + "FFFFFFFFFFFFFFFFFFFFFFF)cccc*[:upperword:]]G{,-38}{24,}" + "555555555555555555555555555VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVZ[" + ":blankcntrl:][:ascii:]", + 0, 0 }, + { "[^QQQQQQQ(\?#QQ(QQQQQQ[:punct:][:space:]){(\?(\?:!}[:graph:]" + "t}}[^}}(}}}}}444444[^444444444444444444444]\?]G)E)L{,-103}{" + "84,}r$ii]-[:alp(\?<=ha:]S5G~9>n*)P<" + "3tttttttttttttttttttttttttt)n{}[:graph:]" + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{,83}[:digit:])" + "0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[:alpha:]{-155,}{151,}", + 0, 0 }, { "Ue{,254}+f[:lowerp(\?<=rint:]U.fff)", 0, 0 }, - { "QQQQQQQQQQQQQQQQQQQQQQQQAY<J)'MPi_u%#2doopqU7/{103}[:graph:]e!7{GOr", 0, 0 }, - { "[^({,[^233}[^d)BBBBBBBBBBBBBBB=======(\?>===========[^=S|[^[:alpha:]G/]qqqqqqqqq{}[:xdigit:])..k", 0, 0 }, - { "[([^[[:space:]ffffff(\?=ff]M]))[:xdigit:]UbCI,CzalLU*y5I[:digit:]r{-30,180}{-209,-45}Paf]", 0, 0 }, - { "[^[h(\?{hhhhhhhhhhhhhhhhhhhhh})]{,143}[:lowerprint:][:ascii:((\?(\?=])[:asc)ii:])zp]", 0, 0 }, + { "QQQQQQQQQQQQQQQQQQQQQQQQAY<J)'MPi_u%#2doopqU7/" + "{103}[:graph:]e!7{GOr", + 0, 0 }, + { "[^({,[^233}[^d)BBBBBBBBBBBBBBB=======(\?>===========[^=S|[^[" + ":alpha:]G/]qqqqqqqqq{}[:xdigit:])..k", + 0, 0 }, + { "[([^[[:space:]ffffff(\?=ff]M]))[:xdigit:]UbCI,CzalLU*y5I[:" + "digit:]r{-30,180}{-209,-45}Paf]", + 0, 0 }, + { "[^[h(\?{hhhhhhhhhhhhhhhhhhhhh})]{,143}[:lowerprint:][:ascii:" + "((\?(\?=])[:asc)ii:])zp]", + 0, 0 }, { "[[(\?{]})]", 0, 0 }, - { "[[1\"3m^,(\?<!2((\?!\?#t```````````````````````````)\?)|c^)A^~]{61}W\\\\\\vvvvrrrrrrrrrrr[:digit(\?#:])]F[:upperword:]dX\\\\", 0, 0 }, + { "[[1\"3m^,(\?<!2((\?!\?#t```````````````````````````)\?)|c^)" + "A^~]{61}W\\\\\\vvvvrrrrrrrrrrr[:digit(\?#:])]F[:upperword:]" + "dX\\\\", + 0, 0 }, { "([${144,}(\?<!)-RAk_F(\?imsxisx:=9]z/))", 1, 0 }, - { "[[^[[[^([[^[^[^([[^([[Uiiiii#####(\?(\?{(\?<!#########(\?=#####).^)(.|>2m[M/2222222222222222222222222222(\?:22222222222(\?#22(\?:(\?=22222{,243}]x68+I/K)11111111111]\\pP[:graph:]$[:space:]^{}A)[:xdigit:]-={>", 0, 0 }, - { "[(\?>[(^()Vty2vvvvvvvvvvvvvvvvz^])ZZZZZZZZZZZZZZZZZZZ----------------5\\dVLSp8UE2m+z3X/Sd", 0, 0 }, - { "[}}}}}}}}}}}}}}}}}}}(\?#}}(\?<=)|*C ]*29JW7O9mEB]pE_OoxN)[:alpha:]", 0, 0 }, - { "([^((\?<=\?)D{,200}.[(\?#:ascii:])[:space:].)[:alpha:]D|[:graph:]{,-41}*LLUUUUUUUUUUUUU{-189,-131}]qHR<k2@P{27}<^e,ub%\?/4){-243}+[:digit:]%*x9lA^", 1, 0 }, + { "[[^[[[^([[^[^[^([[^([[Uiiiii#####(\?(\?{(\?<!#########(\?=##" + "###).^)(.|>2m[M/" + "2222222222222222222222222222(\?:22222222222(\?#22(\?:(\?=" + "22222{,243}]x68+I/" + "K)11111111111]\\pP[:graph:]$[:space:]^{}A)[:xdigit:]-={>", + 0, 0 }, + { "[(\?>[(^()Vty2vvvvvvvvvvvvvvvvz^])ZZZZZZZZZZZZZZZZZZZ-------" + "---------5\\dVLSp8UE2m+z3X/Sd", + 0, 0 }, + { "[}}}}}}}}}}}}}}}}}}}(\?#}}(\?<=)|*C " + "]*29JW7O9mEB]pE_OoxN)[:alpha:]", + 0, 0 }, + { "([^((\?<=\?)D{,200}.[(\?#:ascii:])[:space:].)[:alpha:]D|[:" + "graph:]{,-41}*LLUUUUUUUUUUUUU{-189,-131}]qHR<k2@P{27}<^e,ub%" + "\?/4){-243}+[:digit:]%*x9lA^", + 1, 0 }, { "([:alpha:]bT&+_)$Z{,212}x26`", 1, 0 }, - { "[^([^(A{[^}g(\?()A9p#54b]-------------------------------).wzD#=f\\)A)8a]]DNNNNNNNNNNNNNNNNNNNNNNNNNN", 0, 0 }, + { "[^([^(A{[^}g(\?()A9p#54b]-------------------------------)." + "wzD#=f\\)A)8a]]DNNNNNNNNNNNNNNNNNNNNNNNNNN", + 0, 0 }, { "(W000000000000000000000000000000)", 1, 0 }, { "www(wwwwwwwwwwwww)", 1, 0 }, { "()555555555555{18}i+[:alnum:]E {}U", 1, 0 }, - { "SqbHoooooooooooo[^oooooo([^ooooooo])\\N[:xdigit:]]oooo`", 0, 0 }, - { "[999999999999999999uE{193,0}lx{7917}[:punct:]4&d]{221,}[:digit:]{49,156}[:lowe(\?<=rprint:])[:space:]{-33}w+", 0, 0 }, - { "[^(\?{})<{220,-193}[(\?=:xdigit:]UUUUUUUUUUUUUUUUUUU'{-18}])", 0, 0 }, - { "b[(\?<=:upperw(\?{ord:][:digit:]})EEEEEEEEEEEEEEEEEEEEE//////////////////){177}C", 0, 0 }, - { "(^).[:alnum:][^[(\?=[(\?{[})DA5{)[[I~y&O\?9>])]][:blankcntrl:]M[:alpha:]x9[:upperword:]|[:xdigit:]b", 1, 0 }, + { "SqbHoooooooooooo[^oooooo([^ooooooo])\\N[:xdigit:]]oooo`", 0, + 0 }, + { "[999999999999999999uE{193,0}lx{7917}[:punct:]4&d]{221,}[:" + "digit:]{49,156}[:lowe(\?<=rprint:])[:space:]{-33}w+", + 0, 0 }, + { "[^(\?{})<{220,-193}[(\?=:xdigit:]UUUUUUUUUUUUUUUUUUU'{-18}]" + ")", + 0, 0 }, + { "b[(\?<=:upperw(\?{ord:][:digit:]})EEEEEEEEEEEEEEEEEEEEE/////" + "/////////////){177}C", + 0, 0 }, + { "(^).[:alnum:][^[(\?=[(\?{[})DA5{)[[I~y&O\?9>])]][:" + "blankcntrl:]M[:alpha:]x9[:upperword:]|[:xdigit:]b", + 1, 0 }, { "()[:digit:][^[U}-]]{,206}V*WJ@R]\?", 1, 0 }, { "[^](\?#{}(\?[<=)yv)]r", 0, 0 }, { "({,-192}//////////////////////7!eW_0eoL){}", 1, 0 }, { "^[:punct:(]+)IIIIIIIII[:punct:]P$pP", 0, 0 }, { "[(\?=|U)^-]{-52,-72}[:digit:]*6666666666\?{{{", 0, 0 }, - { "([^f(\?:+{1((\?=34,}]))^)s0bux7\?5`Bwr[:upperword:])Dy+", 1, 0 }, - { "AL{}:::::::::::::::::::::::::::::::{,(104}~@,Ysey@h).", 1, 0 }, - { "[^((.)))(\?()))))))))))))))))))))(\?msxims:))))))))))[)][:upperword:][:alpha:])", 0, 0 }, - { "[^(()f])G^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^T{}N*nK[G]{,61}^^^^^^^^]", 0, 0 }, - { "[(N::(\?<=[:digit:][:graph:][:space:]xB5[(:xdigit:]|Yv{}HHHHHHHHHHHHHHHHHHHHHHHHd).[:g(\?<=raph:])[:digit:]<<)[:digit:])[:space:]Q[:punct:]x7C]", 0, 0 }, - { "[^((\?(\?(())a)(\?!){})W)pP3333333333(33333333333333333333hhh]{})", 0, 0 }, - { "[^ [ a*FFFFF[^FFFFFFFFFFF(\?<[^!FFFF(\?=FF])])L1]{,-52}{B-bxsPKg{,8}[:digit:][:punct:][:upperword:]DD${,-131}", 0, 0 }, - { "($$$$$$$$$$$$$$$$$$$$$$$$$$$$$^pP),,,,,,,,,,,,,(,,,,,,,,,,,,)QQQQQQQQQQQQQQQQQQQQQQQQ", 2, 0 }, + { "([^f(\?:+{1((\?=34,}]))^)s0bux7\?5`Bwr[:upperword:])Dy+", 1, + 0 }, + { "AL{}:::::::::::::::::::::::::::::::{,(104}~@,Ysey@h).", 1, + 0 }, + { "[^((.)))(\?()))))))))))))))))))))(\?msxims:))))))))))[)][:" + "upperword:][:alpha:])", + 0, 0 }, + { "[^(()f])G^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^T{}N*nK[G]{,61}^^^^^" + "^^^]", + 0, 0 }, + { "[(N::(\?<=[:digit:][:graph:][:space:]xB5[(:xdigit:]|Yv{}" + "HHHHHHHHHHHHHHHHHHHHHHHHd).[:g(\?<=raph:])[:digit:]<<)[:" + "digit:])[:space:]Q[:punct:]x7C]", + 0, 0 }, + { "[^((\?(\?(())a)(\?!){})W)pP3333333333(" + "33333333333333333333hhh]{})", + 0, 0 }, + { "[^ [ " + "a*FFFFF[^FFFFFFFFFFF(\?<[^!FFFF(\?=FF])])L1]{,-52}{B-bxsPKg{" + ",8}[:digit:][:punct:][:upperword:]DD${,-131}", + 0, 0 }, + { "($$$$$$$$$$$$$$$$$$$$$$$$$$$$$^pP),,,,,,,,,,,,,(,,,,,,,,,,,," + ")QQQQQQQQQQQQQQQQQQQQQQQQ", + 2, 0 }, { "[:lowerprint:]|l{(,-54}C{}*-)IIIIIIIIIIIIIIIII", 1, 0 }, { "()+", 1, 0 }, - { "[(([(\?{[:punct:]]|))[[[[[[[[[[})]WWWWWWWW&$$$$$$$[:graph:]", 0, 0 }, - { "[^(\?{}){(107[(^,}][:space:[]))^w,&aPPPPPP[^PPPPP{117,-213}s\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?]]]222222[:d(\?(igit:]NNNNNN)NNNNNNNNNNNNN8)I", 0, 0 }, + { "[(([(\?{[:punct:]]|))[[[[[[[[[[})]WWWWWWWW&$$$$$$$[:graph:]", + 0, 0 }, + { "[^(\?{}){(107[(^,}][:space:[]))^w,&aPPPPPP[^PPPPP{117,-213}" + "s\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?]]]222222[:d(\?(" + "igit:]NNNNNN)NNNNNNNNNNNNN8)I", + 0, 0 }, { "[^(\?<!$)|TTTTTTTTTTTTTTTTTTTTTT(TTTT]a8)2<", 0, 0 }, - { "([^[]%[^[^]-][:alpha:]37*:[:space:]]lQvu)[:xdigit:][:blankcntrl:]", 1, 0 }, - { "[[Bl_>9C^:\?X_KK]2sw@hHZT!],uuuuuuut|lFW()'''''''''''''''''''''[:graph:]<~v{-251}0[:digit:]C[{222,}]{,41}{}*g^UuS/{-114}", 1, 0 }, - { "(D{,-79}[:gra(ph:(\?(]C[:ascii:]))I[tC.%tkllll[^llllllllllllllll]&&&&&&)&&&&&&&&&&&&&&&&&&&&&&)]10435", 1, 0 }, - { "[:al(\?{[^num:]]})}x'[:(\?#xdigit:])xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKKKKKKKKKKKKKKKKKKKKKKKKKKKKTTTr*%{~f", 0, 0 }, - { "[ZQKEEEEEEEEEEEEEEEEE(\?<!]3|.~~~~~~~~~~~~~~303)33333333333333333", 0, 0 }, - { "(-62([:ascii:]5555){-230,}<<<<<<SM[:punct:]{72}|E{160,})Pfqba!{,-188}DS{ +2tRu\"0JG$", 2, 0 }, - { "([^(\?:(Ea00000000000000[:punct:][:graph:]{}]))[:xdigit:]{-65}t){164,}", 1, 0 }, - { "[\?$$$$$$$$$$$$$$$$$$$$$$$$$F......(\?(.).q#R:j6%TTLCdtuM|8*54<GHoqEh9FBW0:W]L0)o][:upperword:]", 0, 0 }, + { "([^[]%[^[^]-][:alpha:]37*:[:space:]]lQvu)[:xdigit:][:" + "blankcntrl:]", + 1, 0 }, + { "[[Bl_>9C^:\?X_KK]2sw@hHZT!],uuuuuuut|lFW()''''''''''''''''''" + "'''[:graph:]<~v{-251}0[:digit:]C[{222,}]{,41}{}*g^UuS/" + "{-114}", + 1, 0 }, + { "(D{,-79}[:gra(ph:(\?(]C[:ascii:]))I[tC.%tkllll[^" + "llllllllllllllll]&&&&&&)&&&&&&&&&&&&&&&&&&&&&&)]10435", + 1, 0 }, + { "[:al(\?{[^num:]]})}x'[:(\?#xdigit:])" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKKKKKKKKKKKKKKKKKKKKKKKKKKKKTT" + "Tr*%{~f", + 0, 0 }, + { "[ZQKEEEEEEEEEEEEEEEEE(\?<!]3|.~~~~~~~~~~~~~~303)" + "33333333333333333", + 0, 0 }, + { "(-62([:ascii:]5555){-230,}<<<<<<SM[:punct:]{72}|E{160,})" + "Pfqba!{,-188}DS{ +2tRu\"0JG$", + 2, 0 }, + { "([^(\?:(Ea00000000000000[:punct:][:graph:]{}]))[:xdigit:]{-" + "65}t){164,}", + 1, 0 }, + { "[\?$$$$$$$$$$$$$$$$$$$$$$$$$F......(\?(.).q#R:j6%TTLCdtuM|8*" + "54<GHoqEh9FBW0:W]L0)o][:upperword:]", + 0, 0 }, { "[(\?>[:alnum:]W[:space:]]D)|L", 0, 0 }, { "(M(MM)[:alnum:]|[:lowerprint:]4)", 2, 0 }, { "[[^(\?:{}{2[2(\?>0,})]]]Etu)-)", 0, 0 }, - { "([^[^^z[:graph:]]#{-144,96}[:punct:]!4LY//////////////////SSSSSSSSSSSSSSSSSSSSSSSSS[[^:xdigit:]\?`-!L#p0{52}]%{-121,}[:graph:]]WqJ>$6UBg{,7}[:blankcntrl:])[:upperword:]y2wW!A[:blankcntrl:]0CN\?", 1, 0 }, - { "[[^(\?:|+bII(IIIIIII(\?(\?>!)275SIIIIIIIIII(IIIIIII(\?=IIIIII[:graph:]|)`]S\?.}A)[:alnum:]Jgggggggggg{-150,}{-89,})[:alpha:]Q)|07be5:j)]", 0, 0 }, - { "([(\?i(ms(\?=x-x(\?>:))C)]){})>eIqm~lFb[:upperword:][:blankcntrl:]w=[:digit:][:graph:]", 1, 0 }, - { "([HHHHHHHHHHHHHHHHHHHHHHHHHH[^HHH(\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?!!!!!!!!!!!!!!!!!!!!{23}]~J=[:ascii:]tttttttttttttttt])-216", 1, 0 }, - { "B{[^-32,246}{13(\?!0}q>GVQw*[:digit:][:punct:].77777777777777777777`T(-t01odD]\?${}{-247}+gV{131})+[:lowerprint:]m/z~d", 0, 0 }, - { "[t[$FV+(\?=E=[^])]-$U{-22[5,}{253,}08g]$[{}][:xdigit:][:punct:]{-18}{-173,}]{,-191}V_|90", 0, 0 }, + { "([^[^^z[:graph:]]#{-144,96}[:punct:]!4LY//////////////////" + "SSSSSSSSSSSSSSSSSSSSSSSSS[[^:xdigit:]\?`-!L#p0{52}]%{-121,}[" + ":graph:]]WqJ>$6UBg{,7}[:blankcntrl:])[:upperword:]y2wW!A[:" + "blankcntrl:]0CN\?", + 1, 0 }, + { "[[^(\?:|+bII(IIIIIII(\?(\?>!)275SIIIIIIIIII(IIIIIII(\?=" + "IIIIII[:graph:]|)`]S\?.}A)[:alnum:]Jgggggggggg{-150,}{-89,})" + "[:alpha:]Q)|07be5:j)]", + 0, 0 }, + { "([(\?i(ms(\?=x-x(\?>:))C)]){})>eIqm~lFb[:upperword:][:" + "blankcntrl:]w=[:digit:][:graph:]", + 1, 0 }, + { "([HHHHHHHHHHHHHHHHHHHHHHHHHH[^HHH(" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?!!!!!!!!!!!!!!!!!!" + "!!{23}]~J=[:ascii:]tttttttttttttttt])-216", + 1, 0 }, + { "B{[^-32,246}{13(\?!0}q>GVQw*[:digit:][:punct:]." + "77777777777777777777`T(-t01odD]\?${}{-247}+gV{131})+[:" + "lowerprint:]m/z~d", + 0, 0 }, + { "[t[$FV+(\?=E=[^])]-$U{-22[5,}{253,}08g]$[{}][:xdigit:][:" + "punct:]{-18}{-173,}]{,-191}V_|90", + 0, 0 }, { "()$", 1, 0 }, - { "[^[^((((((((((((((W[(\?::blankcntrl:]&-JH]J){93}LLLLLLL|r{,221}tY/172]-AS", 0, 0 }, - { "[^()(\?{qqqq(\?msimsx:qqqqqqqqqq3999999999999GGGGG|S*W%{,128}][:xdigit:]AJt]}\"Zf!lRpr{>){,36}})", 0, 0 }, + { "[^[^((((((((((((((W[(\?::blankcntrl:]&-JH]J){93}LLLLLLL|r{," + "221}tY/172]-AS", + 0, 0 }, + { "[^()(\?{qqqq(\?msimsx:qqqqqqqqqq3999999999999GGGGG|S*W%{," + "128}][:xdigit:]AJt]}\"Zf!lRpr{>){,36}})", + 0, 0 }, { "[([]^]^)", 0, 0 }, - { "([.(\?#){}[:alpha:]\?S{2}P%Gw]nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnYiq5)>i*r<", 1, 0 }, - { "[ggggggggggg$PPP:S (:]N{239,}|A[:lowerprint:]vvvvvvvvvv[:lower(print:]{-184}({-133,}+)[:punct:]P/Q.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", 1, 0 }, + { "([.(\?#){}[:alpha:]\?S{2}P%Gw]" + "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnYiq5)>i*r<", + 1, 0 }, + { "[ggggggggggg$PPP:S " + "(:]N{239,}|A[:lowerprint:]vvvvvvvvvv[:lower(print:]{-184}({-" + "133,}+)[:punct:]P/Q.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + 1, 0 }, { "(RRRRRRR[^RRRRR[RRRRRRRRR])]", 1, 0 }, { "[(\?:^])D%", 0, 0 }, { "()[]#C[+[j]{,29}-]", 1, 0 }, - { "(([(\?(((\?{\?!(\?=\?=#[Es*){02$r'}(\?:3pz)uPPPPPPPPPPPPPPPP(\?(\?>:PPPP][:graph:][:ascii:]`.)[:punct:][:a(\?mxi:lnum:])r)$)[:xdigit:]$[:(\?=digit:])aa[^]a)\?])sQQQQQQQQQQQQQQQQQQQQQQQQQQ^|$)-}))", 2, 0 }, + { "(([(\?(((\?{\?!(\?=\?=#[Es*){02$r'}(\?:3pz)" + "uPPPPPPPPPPPPPPPP(\?(\?>:PPPP][:graph:][:ascii:]`.)[:punct:]" + "[:a(\?mxi:lnum:])r)$)[:xdigit:]$[:(\?=digit:])aa[^]a)\?])" + "sQQQQQQQQQQQQQQQQQQQQQQQQQQ^|$)-}))", + 2, 0 }, { "z@@@@@@@y${}[:(\?:upperword:]l\?{,144}-)", 0, 0 }, - { "[:aln(\?:(\?>um:(\?imximsx:]){})FGGGGGGGGGG|-p){,105}", 0, 0 }, - { "[[{17}llllllllllllllll(\?:lllllllll{,(\?#-94}OUUUUUUU(\?#UUUUUUUUUUUUUAA]p[:digit:]{-1(57,}5yyyyyyyyyyyyyyyyyyyyy[:alnum:]v{-185}^^^^^^^^^^^^^)d[[[p)]))", 1, 0 }, + { "[:aln(\?:(\?>um:(\?imximsx:]){})FGGGGGGGGGG|-p){,105}", 0, + 0 }, + { "[[{17}llllllllllllllll(\?:lllllllll{,(\?#-94}OUUUUUUU(\?#" + "UUUUUUUUUUUUUAA]p[:digit:]{-1(57,}5yyyyyyyyyyyyyyyyyyyyy[:" + "alnum:]v{-185}^^^^^^^^^^^^^)d[[[p)]))", + 1, 0 }, { "()|[:digit:].E2o", 1, 0 }, { "()3[:lowerprint:]", 1, 0 }, - { "[(\?{(\?#(\?>SN}[^)z+r^t[:digit:]seP[:alnum:]$b1ZY[U(\?<!U4IIIIIIIIIIIII(\?<=IIIIIIIIII]m)]))]4)", 0, 0 }, - { "{,74} qkk[^p]kbi6>{}000000000000000000000000000000$|)", 0, 0 }, + { "[(\?{(\?#(\?>SN}[^)z+r^t[:digit:]seP[:alnum:]$b1ZY[U(\?<!" + "U4IIIIIIIIIIIII(\?<=IIIIIIIIII]m)]))]4)", + 0, 0 }, + { "{,74} qkk[^p]kbi6>{}000000000000000000000000000000$|)", + 0, 0 }, { "[:(\?=digit:])v{164}", 0, 0 }, - { "[:graph:]h[:upper(\?(wo(\?{rd:)])00000[^000000000000}).4OEVf{,-46}]A", 0, 0 }, + { "[:graph:]h[:upper(\?(wo(\?{rd:)])00000[^000000000000})." + "4OEVf{,-46}]A", + 0, 0 }, { "[](((((((((((((((N{{{{{{{{{{{{{{{{,-1}e]a{-166,-44}", 0, 0 }, - { "([[^[^[(^[]]YYYYYYYYYYY]D.cQ{}[:alpha:]ttttttt000000[^0000(\?<!0000000000000000N::::::::].][:alpha:]#5\?{}{-253,-193}]\\[:ascii:]tS{,35}B)ffffffffffffffffffffffff))/", 1, 0 }, + { "([[^[^[(^[]]YYYYYYYYYYY]D.cQ{}[:alpha:]ttttttt000000[^0000(" + "\?<!0000000000000000N::::::::].][:alpha:]#5\?{}{-253,-193}]" + "\\[:ascii:]tS{,35}B)ffffffffffffffffffffffff))/", + 1, 0 }, { "(G)[:alpha:(\?#])W{-197,-220}w8", 1, 0 }, - { "{-2[^00,(\?#-([84}ig+)]]l[:graph:][:graph:][:space:])aaaaaaaaaaaaaaaaaaa{-208,}ea{,224}", 0, 0 }, - { "[^[W(\?<=[B[:xdigit:]{255,}FAAAAAAAAAAAAAAAAAAAPP])[:xdigit:]+][:lowerprint:]${-195}", 0, 0 }, - { "[v{104,}BB].HHHHHHHHHHHH[:ascii:]bbbbbbbbbbbbbbbbbbbbbbbbbbbb(btttttttttttttttttttttttttt){180}", 1, 0 }, - { "[^(i[^iiiiiiiiiiiiiiiiii(ii)n])#######################]", 0, 0 }, - { "(([:space:])[:g(\?>raph:])[:punct:][:upperword:]LV\"t+t!)[:ascii:][:lowerprint:]q", 2, 0 }, - { "[[[^([7(\?[<!)\\PP~D7L (\?imsimsx:(\?= $GS26L3-J(\?()!)]]{-178}%$[:p(\?!unct:]))yyyyyyyyyyyyyy@w,[11!R86:)G*[(\?(:blankcntrl:]267$~L\?{-108}k[:alnum:]So\?Y/eq]-|[:xdigit:]555555555555555555555555555)55555........W*O))][:alnum:]]I{,-126}[:lowerprint:]8\?[:xdigit:]u%wHc6\?:Pc...........................,,,,,,,,,,,,,,,,,,,,,,,,,,,]", 0, 0 }, + { "{-2[^00,(\?#-([84}ig+)]]l[:graph:][:graph:][:space:])" + "aaaaaaaaaaaaaaaaaaa{-208,}ea{,224}", + 0, 0 }, + { "[^[W(\?<=[B[:xdigit:]{255,}FAAAAAAAAAAAAAAAAAAAPP])[:xdigit:" + "]+][:lowerprint:]${-195}", + 0, 0 }, + { "[v{104,}BB].HHHHHHHHHHHH[:ascii:]" + "bbbbbbbbbbbbbbbbbbbbbbbbbbbb(btttttttttttttttttttttttttt){" + "180}", + 1, 0 }, + { "[^(i[^iiiiiiiiiiiiiiiiii(ii)n])#######################]", 0, + 0 }, + { "(([:space:])[:g(\?>raph:])[:punct:][:upperword:]LV\"t+t!)[:" + "ascii:][:lowerprint:]q", + 2, 0 }, + { "[[[^([7(\?[<!)\\PP~D7L (\?imsimsx:(\?= " + "$GS26L3-J(\?()!)]]{-178}%$[:p(\?!unct:]))yyyyyyyyyyyyyy@w,[" + "11!R86:)G*[(\?(:blankcntrl:]267$~L\?{-108}k[:alnum:]So\?Y/" + "eq]-|[:xdigit:]555555555555555555555555555)55555........W*O)" + ")][:alnum:]]I{,-126}[:lowerprint:]8\?[:xdigit:]u%wHc6\?:Pc.." + ".........................,,,,,,,,,,,,,,,,,,,,,,,,,,,]", + 0, 0 }, { "((3pPp))QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 2, 0 }, - { "[[^]{-244[}(\?([^|W0E4]UUUUUUUUUUUUUU[:upper)word:][:space:]{-57,})+L>R]]$PeFuufcBA`qr!!!!!!!!!!!!!!!!!!!!!!!!!", 0, 0 }, - { "[[(\?#F^(\?<!)|)fff(\?!fffffffffffffffff(\?{ffffff(\?:ffffff[:alnum:])]]c.\?-}))", 0, 0 }, - { "[^[^((\?:)ww[wwww(\?>wwwww)3z/57z){34}]/(/////////////[^//////////////////)]E%)L{-133}]*$]", 1, 0 }, + { "[[^]{-244[}(\?([^|W0E4]UUUUUUUUUUUUUU[:upper)word:][:space:]" + "{-57,})+L>R]]$PeFuufcBA`qr!!!!!!!!!!!!!!!!!!!!!!!!!", + 0, 0 }, + { "[[(\?#F^(\?<!)|)fff(\?!fffffffffffffffff(\?{ffffff(\?:" + "ffffff[:alnum:])]]c.\?-}))", + 0, 0 }, + { "[^[^((\?:)ww[wwww(\?>wwwww)3z/57z){34}]/(/////////////[^////" + "//////////////)]E%)L{-133}]*$]", + 1, 0 }, { "(!)GS[:ascii:][:punct:]{235}T'&-_h\"", 1, 0 }, { "(){}", 1, 0 }, - { "[[^((\?!(\?<=)*QF[:alpha:])([^[^\?<!x60t(\?<!UUUUUUUUUUUUUUUUUUUU)K&d{118}z7nM.G)```````````````````````````E:(\?(){31,}){}]k]){,109}[:space:]]ZZ[:xdigit:]]{-68,}`{}{}e\?[:alnum:]", 0, 0 }, - { "[^{223}.^,-qqqqqqqqq((\?!\?>qqqqqqqqqqqqqqqqqqqqqqqP6W0_'O)Bur*'6&*t)]{65})+", 0, 0 }, - { "([(\?=)]wr$7f5ru){100,}[:xdigit:]y{}[:digit:]{}2n@P|9#mru~97{-189,73}$a", 1, 0 }, + { "[[^((\?!(\?<=)*QF[:alpha:])([^[^\?<!x60t(\?<!" + "UUUUUUUUUUUUUUUUUUUU)K&d{118}z7nM.G)````````````````````````" + "```E:(\?(){31,}){}]k]){,109}[:space:]]ZZ[:xdigit:]]{-68,}`{}" + "{}e\?[:alnum:]", + 0, 0 }, + { "[^{223}.^,-qqqqqqqqq((\?!\?>qqqqqqqqqqqqqqqqqqqqqqqP6W0_'O)" + "Bur*'6&*t)]{65})+", + 0, 0 }, + { "([(\?=)]wr$7f5ru){100,}[:xdigit:]y{}[:digit:]{}2n@P|9#mru~" + "97{-189,73}$a", + 1, 0 }, { "({-113,213}){-172,221}B[:ascii:]{,-48}", 1, 0 }, - { "[^[[Xf`````((\?{(\?<=\?imsmsx:`````````(\?!`````````[```(\?mximsx:``(\?(&|o{xIaO][:)space:]3))\?])+)*<|@@@@@@@@@@@@@@@@@@@@@@){-251,}{}]*[:graph:]1!azE\?|-120u*][:lowerprint:]})", 0, 0 }, - { "[[[^##(\?################(\?>(\?(##t)][:punct:])b))<<<<<<<<<<<<<<<<<<<<<<<<<<[:alnum:]y >u=l:rp8i3Ci#]46%NIO-W[:space:]IIIIIIIIIIIIIIIIII]W[:space:]f]l{-253}", 0, 0 }, - { "[:graph:]L{-136,175}{[^}h(\?=t)Q]ooooooooo(ooooooooooooooooo_)[:space:]q\?", 1, 0 }, + { "[^[[Xf`````((\?{(\?<=\?imsmsx:`````````(\?!`````````[```(" + "\?mximsx:``(\?(&|o{xIaO][:)space:]3))\?])+)*<|@@@@@@@@@@@@@@" + "@@@@@@@@){-251,}{}]*[:graph:]1!azE\?|-120u*][:lowerprint:]}" + ")", + 0, 0 }, + { "[[[^##(\?################(\?>(\?(##t)][:punct:])b))<<<<<<<<<" + "<<<<<<<<<<<<<<<<<[:alnum:]y " + ">u=l:rp8i3Ci#]46%NIO-W[:space:]IIIIIIIIIIIIIIIIII]W[:space:]" + "f]l{-253}", + 0, 0 }, + { "[:graph:]L{-136,175}{[^}h(\?=t)Q]ooooooooo(" + "ooooooooooooooooo_)[:space:]q\?", + 1, 0 }, { "()$.", 1, 0 }, { "[(\?<!^$.\?{197}B]$)", 0, 0 }, - { "[:di(git:])[:low(erprint:])qqqqqqqqqqqqqqqq[:digit:]", 0, 0 }, + { "[:di(git:])[:low(erprint:])qqqqqqqqqqqqqqqq[:digit:]", 0, + 0 }, { "((zzzzzzzzzzzzAUUUU)l$]VD z~)n", 2, 0 }, - { "([^[(\?<=^[]{}][.WWWW)044444444444(\?=44(\?{444(\?{(444444444444e{(\?=}}))..t]+[:(\?<!xdigit:]P]-N}))))|)", 1, 0 }, + { "([^[(\?<=^[]{}][.WWWW)044444444444(\?=44(\?{444(\?{(" + "444444444444e{(\?=}}))..t]+[:(\?<!xdigit:]P]-N}))))|)", + 1, 0 }, { "\\ce[:(\?#asc(\?{ii:])})[:upperword:]`^", 0, 0 }, { "[:graph:(\?<=])[:alpha:]", 0, 0 }, { "([:upp(\?=erword:])pC)lp\?", 1, 0 }, { "(oooooooooooooo\?fN)-[:alpha:]{-213}[:alnum:]qHEu", 1, 0 }, { "[:punct:]TTTTTTTTTTTTTTTTTTT[:d(\?#igit:])[:alpha:]", 0, 0 }, - { "([^[^[^J4(+++++++++++++++++++++SgDE(\?>\"y8].]:::::::::::::::)pP5-]p)O{,199}xxxxxxxxxxxxxxxxxxxxxx[:ascii:]%", 1, 0 }, + { "([^[^[^J4(+++++++++++++++++++++SgDE(\?>\"y8].]::::::::::::::" + ":)pP5-]p)O{,199}xxxxxxxxxxxxxxxxxxxxxx[:ascii:]%", + 1, 0 }, { "([:alpha:]Fs)Z", 1, 0 }, - { "[()]{209}[:alpha:]hhhhhhhhh(hhhhhhhhhhhhhhhhhhhhh)pP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", 1, 0 }, - { "-{-8,}.[:(\?imsxx:ascii(\?<!:]{-231}aa*{}K^UQL\?)d\?[:lowerprint:]W)q>D9'", 0, 0 }, - { "[#(\?msximsx:#########################-IIIIIIIIIIIIII(IIII(\?#IIIII((\?#[^III{})N.[(\?=:lowerprint:]))CwT,,,,,,,,,,,,,,,,,,,,Sq]$CCCCCCCCCCCCCCCCCCCCCCCuuuuuuuu])))", 0, 0 }, + { "[()]{209}[:alpha:]hhhhhhhhh(hhhhhhhhhhhhhhhhhhhhh)pP<<<<<<<<" + "<<<<<<<<<<<<<<<<<<<<<", + 1, 0 }, + { "-{-8,}.[:(\?imsxx:ascii(\?<!:]{-231}aa*{}K^UQL\?)d\?[:" + "lowerprint:]W)q>D9'", + 0, 0 }, + { "[#(\?msximsx:#########################-IIIIIIIIIIIIII(IIII(" + "\?#IIIII((\?#[^III{})N.[(\?=:lowerprint:]))CwT,,,,,,,,,,,,,," + ",,,,,,Sq]$CCCCCCCCCCCCCCCCCCCCCCCuuuuuuuu])))", + 0, 0 }, { "[:xdigit:][(\?#]){13}{,75}lllllllll", 0, 0 }, { "[c]QQQQQQQQ1+{-252[(\?#}33333])[:upperword:]", 0, 0 }, { "P@i #>>PF!@8G<[(\?:^P]-)D", 0, 0 }, - { "uZZZZZZZZZZZZZZ[^ZZZZZl*-211{199}(\?!p])EEEEEEEEEEEEEEEEEEEEEEEEEEED[:lowerp(\?msximsx:rint:])", 0, 0 }, + { "uZZZZZZZZZZZZZZ[^ZZZZZl*-211{199}(\?!p])" + "EEEEEEEEEEEEEEEEEEEEEEEEEEED[:lowerp(\?msximsx:rint:])", + 0, 0 }, { "[(\?!^])021[:graph:]'", 0, 0 }, { "\\(\?>[(\?<=:ascii:]{}[:alpha:]d8}G))", 0, 0 }, { "[^[((\?!1)[^,a|]\?{,242}[:alnum:])X\"a", 0, 0 }, - { "pP[((\?simx::a(\?!lnum:]vvvvvvvvvvvvvvvvvvvvvvvvv)|O0)[:digit:]ooooooooooooooooooooo)\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"", 0, 0 }, + { "pP[((\?simx::a(\?!lnum:]vvvvvvvvvvvvvvvvvvvvvvvvv)|O0)[:" + "digit:]ooooooooooooooooooooo)" + "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"", + 0, 0 }, { "_ L:8J-~ Y$[:uppe(rword:]{,-184}]{}6.A)", 0, 0 }, { "{,105}.(9]]{-12})N@0nOOE", 1, 0 }, { "HHHHHHHHHH[:xdigit:]uuuuuuuuuuuu{}E^X\\\\\\12601", -1, 1 }, { "( o)=\"OU7h{V>", 1, 0 }, - { "[[:xdigit:])))))$[:xdigit:]+{152}{,-50}(c),,,,,,!!!!!!!!!!!!!!(\?>!!!!!!!!!!!!!.[:digit:]i>\"O'i9])-175d_", 0, 0 }, - { "[([^[^[^([[Eeee[^eeeeeee(\?(\?<!(eeeeeeeeeeeeeeeeeef|]][:alph()\?>(\?!(\?>a:]a{,166})/////////////////////[:gr[^aph:])Gpu", 0, 0 }, + { "[[:xdigit:])))))$[:xdigit:]+{152}{,-50}(c),,,,,,!!!!!!!!!!!!" + "!!(\?>!!!!!!!!!!!!!.[:digit:]i>\"O'i9])-175d_", + 0, 0 }, + { "[([^[^[^([[Eeee[^eeeeeee(\?(\?<!(eeeeeeeeeeeeeeeeeef|]][:" + "alph()\?>(\?!(\?>a:]a{,166})/////////////////////" + "[:gr[^aph:])Gpu", + 0, 0 }, { "(7)NNNNNNNNNNN132", 1, 0 }, { "[([\?#^[]{QKm$v])][:alp[^ha:]]", 0, 0 }, { "(:{86})7{K|[:alpha:]{O", 1, 0 }, - { "([Y(\?{[[^:alnum:][:alnum:][:digit:][:a(\?(lpha(\?(:].})", 1, 0 }, - { "[[({29,-30}([[^:digit:])Y]]J=~{,220}[:blankcntrl:])0ooooooooooooooooooooooooooooooo[:punct:]&]", 0, 0 }, + { "([Y(\?{[[^:alnum:][:alnum:][:digit:][:a(\?(lpha(\?(:].})", 1, + 0 }, + { "[[({29,-30}([[^:digit:])Y]]J=~{,220}[:blankcntrl:])" + "0ooooooooooooooooooooooooooooooo[:punct:]&]", + 0, 0 }, { "[^1Dx32[:alnum:]]{[(\?::punct:]MMMMMMMMMM)12759", 0, 0 }, { "([[[]]*|(_])[:u(\?{pperword:]})", 2, 0 }, { "[:upper(\?(wo)rd:]){-16,250}", 0, 0 }, { "([^{194}i(\?({161)}PP\\S{}{,-14}]))z{208,225}BpPEt", 1, 0 }, - { "[(\?m-ms:)}&!@29k0sUqzt9}<-x|A$!+G>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CCCCCCCCCC-][[:space:]][:space:]El", 0, 0 }, - { "()[:digit:(\?isx(\?>ix:]K^WQQQQQQQQQQQQQQs)[:lowerprint:])", 1, 0 }, - { "[a|(\?imix:S(\?(SSSS)SS(\?>S)]W)8t[:ascii:]f$)[:alnum:]111111111111111111111[^[:space:]x{12729}+'''''''''''''''']", 0, 0 }, - { "[^(\?!(\?(\?#=)a)[:punct:]=2)(){}$$$$$$$$$(\?ims(\?#-isx:$$$$$$$$$$$$$$$$(\?#$$s)x{294b}##############################slllll)]){,209}333333333333333333G:v2/K", 0, 0 }, - { "[^]ub(\?<=)vQ6(\?#Z\"3.)[:space:]u[[:digit:]]7777777777777777U'{}sssssssssss", 0, 0 }, + { "[(\?m-ms:)}&!@29k0sUqzt9}<-x|A$!+G>>>>>>>>>>>>>>>>>>>>>>>>>>" + ">>>>>>CCCCCCCCCC-][[:space:]][:space:]El", + 0, 0 }, + { "()[:digit:(\?isx(\?>ix:]K^WQQQQQQQQQQQQQQs)[:lowerprint:])", + 1, 0 }, + { "[a|(\?imix:S(\?(SSSS)SS(\?>S)]W)8t[:ascii:]f$)[:alnum:]" + "111111111111111111111[^[:space:]x{12729}+'''''''''''''''']", + 0, 0 }, + { "[^(\?!(\?(\?#=)a)[:punct:]=2)(){}$$$$$$$$$(\?ims(\?#-isx:$$$" + "$$$$$$$$$$$$$(\?#$$s)x{294b}##############################" + "slllll)]){,209}333333333333333333G:v2/K", + 0, 0 }, + { "[^]ub(\?<=)vQ6(\?#Z\"3.)[:space:]u[[:digit:]]" + "7777777777777777U'{}sssssssssss", + 0, 0 }, { "(([(])`[:ascii:]b)", 2, 0 }, { "[[[^[^([^[^(\?=(\?imxisx:[[^w])", 0, 0 }, { "pppp(pppppppppp-{-175}Nb>k&)sssss{-190,-54}", 1, 0 }, - { "()OJ@`'%[:(as(\?!cii(\?#:]))+pffffffffffffffffffffffffffff{,162}[:ascii:]5)s-[:graph:]", 1, 0 }, - { "[(M{}Ux5{jaW/{}[^u[:alpha:]s^{84,}PPb@Wt$(\?>nha<Yf41a)]{}[:lowerprint:])*[:lowerprint:]][:upperword:]^1gS.^=pp{}FFFFFFFFFFFFFFFFFFFFFFFFFFF33333333333{}", 0, 0 }, + { "()OJ@`'%[:(as(\?!cii(\?#:]))+pffffffffffffffffffffffffffff{," + "162}[:ascii:]5)s-[:graph:]", + 1, 0 }, + { "[(M{}Ux5{jaW/" + "{}[^u[:alpha:]s^{84,}PPb@Wt$(\?>nha<Yf41a)]{}[:lowerprint:])" + "*[:lowerprint:]][:upperword:]^1gS.^=pp{}" + "FFFFFFFFFFFFFFFFFFFFFFFFFFF33333333333{}", + 0, 0 }, { ")\?L9~h4BQnNp F\\Q{}", 0, 0 }, - { "($)[:upperwor(\?:d:])N[:alnum:]bcccccccc5555555555555555555555555.N[:blankcntrl:]", 1, 0 }, - { "2222222222222222222ppppppppppppppppp[:lowerprint:]))[^B\\e{{{{{f]6#+{,-104}{{{{{{{{{{{{{", 0, 0 }, + { "($)[:upperwor(\?:d:])N[:alnum:]" + "bcccccccc5555555555555555555555555.N[:blankcntrl:]", + 1, 0 }, + { "2222222222222222222ppppppppppppppppp[:lowerprint:]))[^B\\e{{" + "{{{f]6#+{,-104}{{{{{{{{{{{{{", + 0, 0 }, { "<[(\?>:al[^pha:]])\"O\"vN", 0, 0 }, - { "[(\?>d8E@b.{(\?<=,-250}(\?=mx48[:punct:]^&)]nAeYY)W)-13272", 0, 0 }, - { "22222222222222222222222222///////////////////[:digi(\?#t:]eM)[:lowerprint:][:alpha:][:alpha:]EEEEEEEEEEE", 0, 0 }, - { "[(\?={38,223})^\\\\\\\\\\\\\\\\L(\?:{,-50}3|)}r]aW\\x70U{-110,}8LUf)w]4+oav", 0, 0 }, + { "[(\?>d8E@b.{(\?<=,-250}(\?=mx48[:punct:]^&)]nAeYY)W)-13272", + 0, 0 }, + { "22222222222222222222222222///////////////////" + "[:digi(\?#t:]eM)[:lowerprint:][:alpha:][:alpha:]EEEEEEEEEEE", + 0, 0 }, + { "[(\?={38,223})^\\\\\\\\\\\\\\\\L(\?:{,-50}3|)}r]aW\\x70U{-" + "110,}8LUf)w]4+oav", + 0, 0 }, { "G[:upperword:]v[:lowerprint:]-tu)j8CK", 0, 0 }, - { "[([([^().(\?(\?><=c)'(\?<(='(\?<!''''''''(\?(\?<!!'''''''''''(\?=''''''/(|dHj(P>L\?q!G))|)(\?=n(\?(^tk)T-z$q!D|2<rc[^{,53})]jZy))))6)[:bla)nkcntrl:])010])7pE`l[:space:]([:lowerprint:]eXXXXXXXXXXXXXXXXXXXTTTrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr]+[:alph(\?!a:]7)444444444444444444444444l{34,}]J{}yyyyyyyyyyyyyyyyyyyyyyyyyyy)\?'z9~9s.mA", 1, 0 }, + { "[([([^().(\?(\?><=c)'(\?<(='(\?<!''''''''(\?(\?<!!''''''''''" + "'(\?=''''''/" + "(|dHj(P>L\?q!G))|)(\?=n(\?(^tk)T-z$q!D|2<rc[^{,53})]jZy))))" + "6)[:bla)nkcntrl:])010])7pE`l[:space:]([:lowerprint:]" + "eXXXXXXXXXXXXXXXXXXXTTTrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr]+[:" + "alph(\?!a:]7)444444444444444444444444l{34,}]J{}" + "yyyyyyyyyyyyyyyyyyyyyyyyyyy)\?'z9~9s.mA", + 1, 0 }, { "().", 1, 0 }, - { "{-205(,}[:al(ph(\?>[^a:]W,[4DLR[^^8THMtVv~KKw(\?>)pPF)].{-245,}]))fffffffffd[:alpha:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 1, 0 }, - { "[^[[^]{-[1(\?imximx:83,}{,182}][:graph:]]^])-bTO X0P", 0, 0 }, - { "[11111111111(\?#11111111]U[:asc([\?!ii:]{,37}+{-89}){-170,218}{-21,})f[:xdigit:]]P.[:xdig(\?:it:]145)YYYYYY$S@:@@@@@@@@@{-150,-109}", 0, 0 }, + { "{-205(,}[:al(ph(\?>[^a:]W,[4DLR[^^8THMtVv~KKw(\?>)pPF)].{-" + "245,}]))fffffffffd[:alpha:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzz", + 1, 0 }, + { "[^[[^]{-[1(\?imximx:83,}{,182}][:graph:]]^])-bTO X0P", 0, + 0 }, + { "[11111111111(\?#11111111]U[:asc([\?!ii:]{,37}+{-89}){-170," + "218}{-21,})f[:xdigit:]]P.[:xdig(\?:it:]145)YYYYYY$S@:@@@@@@@" + "@@{-150,-109}", + 0, 0 }, { "{-40}<o][^D[(:graph:]]d).Q", 0, 0 }, { "()APPLn[:xdigit:]", 1, 0 }, - { "[([^\?+++++++++++ [ (\?> (\?( (\?{ (\?!]E{-29})pP)})ZpP", 0, 0 }, - { "(t|{}c[^z^\?(@YLD]bSSSSSSSSSSSSSSS)+{{{{{{{{{{{{{{{[:xdigit:]n>1)WkF}7", 1, 0 }, - { "W22[0Q[^d-d{}PPPPPPPPPPPPPPP<^FZ(\?<=\"[U]Yo}9H'cYy]S[:alnum:]^8wTDH)^u", 0, 0 }, - { "([^[(\?:(\?>((\?#$)(\?{^(\?>))///////////(\?>/ggggggggggggggggg{1(\?!90,-13}\\D)Dyyyyyyyyyyyy(\?!y(\?<!yyyyyyy)})]]$)[:xdigit:]|{}-)#a))nPpP[:lowerprint:]AA)V+q^[:blankcntrl:]", 1, 0 }, + { "[([^\?+++++++++++ [ (\?> (\?( (\?{ " + "(\?!]E{-29})pP)})ZpP", + 0, 0 }, + { "(t|{}c[^z^\?(@YLD]bSSSSSSSSSSSSSSS)+{{{{{{{{{{{{{{{[:xdigit:" + "]n>1)WkF}7", + 1, 0 }, + { "W22[0Q[^d-d{}PPPPPPPPPPPPPPP<^FZ(\?<=\"[U]Yo}9H'cYy]S[:" + "alnum:]^8wTDH)^u", + 0, 0 }, + { "([^[(\?:(\?>((\?#$)(\?{^(\?>))///////////(\?>/" + "ggggggggggggggggg{1(\?!90,-13}\\D)Dyyyyyyyyyyyy(\?!y(\?<!" + "yyyyyyy)})]]$)[:xdigit:]|{}-)#a))nPpP[:lowerprint:]AA)V+q^[:" + "blankcntrl:]", + 1, 0 }, { "([^(\?!]))D{,97}", 1, 0 }, { "(c){,141}", 1, 0 }, - { "nn[:s(\?<=pace:])[:upperword:]ooooooooooooooooooo*^[:space:]`{-188,129}mmmmmmmmmmmmm^.", 0, 0 }, - { "[[G{(\?imsximsx:2(49}{,-46}r(\?(\?=#Gw]u))[:bl(\?>ankcntrl:]))(^m+)zSiZ F4[!]VV$E{-9,-100}''''('''''''''\?DEOOOOOOOOOOOO###############[:space:])HHHH)[:digit:]'////////////", 2, 0 }, - { "[^*}(\?>)(\?:7Q=#+]KKKKKKKKKKKKKKKKKKKKKKKKKKKG)]]]]]]]]]]]]]]]]]]]]]]]]]][:alpha:]-{}", 0, 0 }, - { "[n(\?<(\?#!nnnnnn55555{205,}!)[:alnum:]^]!!!!!!!!!!!!!!!!!!!!!!![:punct:])[:x(\?(digit:]vr)|'n6W5 D&jk[:punct:]5)", 0, 0 }, + { "nn[:s(\?<=pace:])[:upperword:]ooooooooooooooooooo*^[:space:]" + "`{-188,129}mmmmmmmmmmmmm^.", + 0, 0 }, + { "[[G{(\?imsximsx:2(49}{,-46}r(\?(\?=#Gw]u))[:bl(\?>ankcntrl:]" + "))(^m+)zSiZ " + "F4[!]VV$E{-9,-100}''''('''''''''\?DEOOOOOOOOOOOO############" + "###[:space:])HHHH)[:digit:]'////////////", + 2, 0 }, + { "[^*}(\?>)(\?:7Q=#+]KKKKKKKKKKKKKKKKKKKKKKKKKKKG)]]]]]]]]]]]]" + "]]]]]]]]]]]]]][:alpha:]-{}", + 0, 0 }, + { "[n(\?<(\?#!nnnnnn55555{205,}!)[:alnum:]^]!!!!!!!!!!!!!!!!!!!" + "!!!![:punct:])[:x(\?(digit:]vr)|'n6W5 D&jk[:punct:]5)", + 0, 0 }, { "[^P(P{(\?i(msxisx:235,}))***])[:alpha:]^", 0, 0 }, - { "[([t(\?<!(\?<!4])[:u(\?=pperword:]))-])}}}}}}}}}}}}}}}}}c{-39,}[:digit:]$-", 0, 0 }, - { "([^)]{241}[:xdigit:][:upp(\?=erwo(\?(rd:]-xF5b{})q[:ascii:])T4U{185}9999999999)()X&Ny[:alpha:]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{69,}[:alnum:]x{d7f8}p-[:digit:]", 2, 0 }, - { "(f)(${,111}{25,}!\\d{,94}[:blankcntrl:]@[:space:][:ascii:])-237{,232}DQVVVVVVVVVVVVVV)-", 2, 0 }, + { "[([t(\?<!(\?<!4])[:u(\?=pperword:]))-])}}}}}}}}}}}}}}}}}c{-" + "39,}[:digit:]$-", + 0, 0 }, + { "([^)]{241}[:xdigit:][:upp(\?=erwo(\?(rd:]-xF5b{})q[:ascii:])" + "T4U{185}9999999999)()X&Ny[:alpha:]@@@@@@@@@@@@@@@@@@@@@@@@@@" + "@@@@@@{69,}[:alnum:]x{d7f8}p-[:digit:]", + 2, 0 }, + { "(f)(${,111}{25,}!\\d{,94}[:blankcntrl:]@[:space:][:ascii:])-" + "237{,232}DQVVVVVVVVVVVVVV)-", + 2, 0 }, { "PP[:g(\?!raph:]){}", 0, 0 }, { "([[^-][^4[:digit:]NNNNNNNNNNN]TVU:])[:ascii:]", 1, 0 }, - { "(([^(\?[[^<=)][:graph:]+iiiiiiiiiiiiiiiiiiiiiiiiii0INFX[:xdigi(\?(t:][:blankcntrl:]][:graph:]qM6A[:alpha:][:graph:])1*]eFvvvvvvvvvv)v-)U))t{89}", 2, 0 }, - { "[^ZZZZZZZZZZZZZZZiiiiiiiiiiiii(iiiiiiiiiiiiiii{}))))))))))))))))))]))))))))))))))))))))))))[:digit:]-", 0, 0 }, - { "ddddddddd+zzzzzzzzzzzz[:graph(:])ssssssM{-223}[:graph:]", 0, 0 }, + { "(([^(\?[[^<=)][:graph:]+iiiiiiiiiiiiiiiiiiiiiiiiii0INFX[:" + "xdigi(\?(t:][:blankcntrl:]][:graph:]qM6A[:alpha:][:graph:])" + "1*]eFvvvvvvvvvv)v-)U))t{89}", + 2, 0 }, + { "[^ZZZZZZZZZZZZZZZiiiiiiiiiiiii(iiiiiiiiiiiiiii{}))))))))))))" + "))))))]))))))))))))))))))))))))[:digit:]-", + 0, 0 }, + { "ddddddddd+zzzzzzzzzzzz[:graph(:])ssssssM{-223}[:graph:]", 0, + 0 }, { "[:alph(\?>a:])x11{-144,45}.", 0, 0 }, - { "[]{#y.^(\?{{}&&&&(\?:[^&&&&&&&&)[:punct:]n{190}OylBQ{(\?!-73})2u',x(\?#Ds(\?#{})j(\?{-})})u0(((((((\?{(((([:alnum:])MC})b=71TncyE>[:xdigit:]*\\f]{}]\"p#!8twZT\")[:punct:][:space:]", 0, 0 }, - { "[^(Z6]8)|'@p8{}[:upperword:]MMMMMMMMMMMMMMMMMMMMMMMMMMMM{}7c", 0, 0 }, + { "[]{#y.^(\?{{}&&&&(\?:[^&&&&&&&&)[:punct:]n{190}OylBQ{(\?!-" + "73})2u',x(\?#Ds(\?#{})j(\?{-})})u0(((((((\?{(((([:alnum:])" + "MC})b=71TncyE>[:xdigit:]*\\f]{}]\"p#!8twZT\")[:punct:][:" + "space:]", + 0, 0 }, + { "[^(Z6]8)|'@p8{}[:upperword:]MMMMMMMMMMMMMMMMMMMMMMMMMMMM{}" + "7c", + 0, 0 }, { "$0)@#vp,VcJ.Bdh", 0, 0 }, - { "[[^(-])nnnn+s`[:alpha:][:blankcnt[^rl:][:upperword:]{-15,}][:g(raph:]c]){,-177}6[:upperword:]##################{,-14}", 0, 0 }, - { "[[(5C{86(,}PPrrrrrrrrrrrrrrrrrrrrr{150,182})N{}LSC|)-[:alnum:]{}KKKKKKKKKKKKKKKK<4=~7K3PPPPPPPPPPPPPPPPPPPPPPP[:lowerprint:]]]", -1, 0 }, + { "[[^(-])nnnn+s`[:alpha:][:blankcnt[^rl:][:upperword:]{-15,}][" + ":g(raph:]c]){,-177}6[:upperword:]##################{,-14}", + 0, 0 }, + { "[[(5C{86(,}PPrrrrrrrrrrrrrrrrrrrrr{150,182})N{}LSC|)-[:" + "alnum:]{}KKKKKKKKKKKKKKKK<4=~7K3PPPPPPPPPPPPPPPPPPPPPPP[:" + "lowerprint:]]]", + -1, 0 }, { "([^(x{145b[5}^hfc.0)+]z@_&lA{-34,}])X\?", 1, 0 }, { "([(\?<=)(\?!])l)L", 1, 0 }, { "({-104,}DrPPDF4444444444444[:space:])[:space:]", 1, 0 }, { "())))", 1, 0 }, - { "[[^((\?>\?(\?[{})q5v}r7t(P)xtffffffffffff))]{,-66}kdExX&-SCeCzzzzzzzzzEc)E,\"^I]x{e629}|{}]", 0, 0 }, - { "[h[:punct:]p\\[\\\\(\?:\\\\[^\\\\)Eo#:C$u[^T/ysA[*%nM:f]{,221}[:lowerprin[^t:]{]bx{f285}E]E[:alnum:]+]1oe3B][:alp(ha:]]fh7}M$l)D{17}", 0, 0 }, - { "IIIIIIII[^IIIIIIX]-_S[:digit(\?#:])33333333333333333333333333[:punct:]iiiiiiiiiiiiiiiiii", 0, 0 }, - { "[^[[:punct:](\?((\?:^ #Q_po(\?=[:alpha:]{}z()(\?!======'wq$Q2)LLLLLLLLLLLLLLLe(C9gggggggggggggggggg[(\?<=:alnum:]()\?<!{-85,}W[[[[[[[[[[[[[[[[(\?{[[[[[[^)(]\?])|uuu[uuuuuuuuuuuuuuuuuu{,-20}p${}]MHI&7s:\?$[:digit:]-:)_V`*{-52,}{250}$:ME9izF/uP[:blankcntrl:]})''''''''''''''''''''''''''''')CCCCCCCCCCCCCCCCCCCCCCCCdd[:ascii:][:lowerprint:].Mcccccccccc2B{-230,}$[:digit:]", 1, 0 }, - { "()|mOAuK~P144[:space:]^9dddddddddddddddddddddddddddddd[:blankcntrl:]", 1, 0 }, + { "[[^((\?>\?(\?[{})q5v}r7t(P)xtffffffffffff))]{,-66}kdExX&-" + "SCeCzzzzzzzzzEc)E,\"^I]x{e629}|{}]", + 0, 0 }, + { "[h[:punct:]p\\[\\\\(\?:\\\\[^\\\\)Eo#:C$u[^T/" + "ysA[*%nM:f]{,221}[:lowerprin[^t:]{]bx{f285}E]E[:alnum:]+]" + "1oe3B][:alp(ha:]]fh7}M$l)D{17}", + 0, 0 }, + { "IIIIIIII[^IIIIIIX]-_S[:digit(\?#:])" + "33333333333333333333333333[:punct:]iiiiiiiiiiiiiiiiii", + 0, 0 }, + { "[^[[:punct:](\?((\?:^ " + "#Q_po(\?=[:alpha:]{}z()(\?!======'wq$Q2)LLLLLLLLLLLLLLLe(" + "C9gggggggggggggggggg[(\?<=:alnum:]()\?<!{-85,}W[[[[[[[[[[[[[" + "[[[(\?{[[[[[[^)(]\?])|uuu[uuuuuuuuuuuuuuuuuu{,-20}p${}]MHI&" + "7s:\?$[:digit:]-:)_V`*{-52,}{250}$:ME9izF/" + "uP[:blankcntrl:]})''''''''''''''''''''''''''''')" + "CCCCCCCCCCCCCCCCCCCCCCCCdd[:ascii:][:lowerprint:]." + "Mcccccccccc2B{-230,}$[:digit:]", + 1, 0 }, + { "()|mOAuK~P144[:space:]^9dddddddddddddddddddddddddddddd[:" + "blankcntrl:]", + 1, 0 }, { "[^[^[^.L[^-vEUl(\?>(\?=a!Ib1P]])])~~~~~~~]xE9", 0, 0 }, { "X()", 1, 0 }, - { "[^()(\?#G(\?<!)(\?=^r])*,XXXXXXXXXXXXXXXXX@)444444444", 0, 0 }, + { "[^()(\?#G(\?<!)(\?=^r])*,XXXXXXXXXXXXXXXXX@)444444444", 0, + 0 }, { "([[((\?<=({,-70})-[:xd(\?=igit:]{,138})", -1, 0 }, { "[(^]{62,67})", 0, 0 }, { "([((])[:space:]))", 1, 0 }, - { "(a{(109,})[:alpha:]{,-121}{})]RRRRRRRRRRRRRRRRRRRRRRRR{}{125,}ttttttttt{46,}`[:space:]", 2, 0 }, + { "(a{(109,})[:alpha:]{,-121}{})]RRRRRRRRRRRRRRRRRRRRRRRR{}{" + "125,}ttttttttt{46,}`[:space:]", + 2, 0 }, { "[^[^([q[8]~.IPmiBSspP)]QpX[pT==8@lulANS]]{,-98}]", 0, 0 }, { "[^77777777777777777777777(\?>777777])", 0, 0 }, { "(),e<^X~{[:alpha:]{}G{70}", 1, 0 }, { "({-211,}'){}", 1, 0 }, - { "[^(\?imsxsx:{}[*])cccccccccccccccccccccccccccccccc<z0W8]$", 0, 0 }, + { "[^(\?imsxsx:{}[*])cccccccccccccccccccccccccccccccc<z0W8]$", + 0, 0 }, { "(){2,89}$z", 1, 0 }, { "((050[^\"\"\"\"\"\"\"\"z]8|j{}{,-112}$).pP)qq1~hW}L", 2, 0 }, - { "[[^[(+xx(\?<!xxxxxxxx(\?!xxxxxxxxxx(\?#(\?>[x))(\?:]r.]]]))[:graph(\?<=:])))", 0, 0 }, - { "[^([(\?#)(\?(\?(<=)l|\?(\?!])kkkkkkkkkkkkkkkkkkkkkkkkkk", 0, 0 }, - { "[:xdigit:]K(KKKKKKK)^3c.OOO{-240,-10}2{-97,-139}*{-34,}[:xdigit:]", 1, 0 }, - { "[([^66666666F(\?>FFFFFFFFFFwpP)LLLLLDeDA&Am$l[:xdigit:]!T5#]n[:alpha:]U*)))))))))))))PP]", 0, 0 }, - { "[[[:punct:]u^[:xdigit:]L(\?:[:xdigit:][[:graph:]PP{21}A[:alpha:]8%I(M%b<eE~#C@r=uG~~~~~~~~~~~~~~~~~~~~~~~~~~~~+w]pP)T]]$$$$$$$$$$$$$$${-121,}|l", 0, 0 }, + { "[[^[(+xx(\?<!xxxxxxxx(\?!xxxxxxxxxx(\?#(\?>[x))(\?:]r.]]]))[" + ":graph(\?<=:])))", + 0, 0 }, + { "[^([(\?#)(\?(\?(<=)l|\?(\?!])kkkkkkkkkkkkkkkkkkkkkkkkkk", 0, + 0 }, + { "[:xdigit:]K(KKKKKKK)^3c.OOO{-240,-10}2{-97,-139}*{-34,}[:" + "xdigit:]", + 1, 0 }, + { "[([^66666666F(\?>FFFFFFFFFFwpP)LLLLLDeDA&Am$l[:xdigit:]!T5#]" + "n[:alpha:]U*)))))))))))))PP]", + 0, 0 }, + { "[[[:punct:]u^[:xdigit:]L(\?:[:xdigit:][[:graph:]PP{21}A[:" + "alpha:]8%I(M%b<eE~#C@r=uG~~~~~~~~~~~~~~~~~~~~~~~~~~~~+w]pP)" + "T]]$$$$$$$$$$$$$$${-121,}|l", + 0, 0 }, { "([(107{,-4(\?=}~[^D)])f]{,46}+ri<)", 1, 0 }, { "[(\?<=]{,208}+~)", 0, 0 }, - { "[^444(\?<=4444444[:alnum:]&[,i]0)[:alpha:][:upperword:]", 0, 0 }, - { "[^([^(\?()*+)SS(\?>SSSSSSSSSSSSSSSSSSSSSS]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]{,-1}])[:blankcntrl:]===============================[:punct:][:blankcntrl:]Z[:space:][:ascii:]$|$[:blankcntrl:] JR.{,133}[:alpha:]$\?)<]", -1, 0 }, - { "(OL[:u[pperword(:][:s[^pace:].[:spac(e:],,,,]*])$)\?)", 1, 0 }, + { "[^444(\?<=4444444[:alnum:]&[,i]0)[:alpha:][:upperword:]", 0, + 0 }, + { "[^([^(\?()*+)SS(\?>SSSSSSSSSSSSSSSSSSSSSS]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]{,-1}])[:blankcntrl:]============================" + "===[:punct:][:blankcntrl:]Z[:space:][:ascii:]$|$[:" + "blankcntrl:] JR.{,133}[:alpha:]$\?)<]", + -1, 0 }, + { "(OL[:u[pperword(:][:s[^pace:].[:spac(e:],,,,]*])$)\?)", 1, + 0 }, { "(VI[:digit:][:alpha:]6)EG", 1, 0 }, { "({}){-2,-40}rrrrrrrrrrrrrrrrrrrrrrr[:punct:]", 1, 0 }, { "()q", 1, 0 }, - { "[^([^[([^C|])]{,-56}[:xdigit:]{-144,}V])fYv{-[40,-58}$@@@@@@@@@@@@@]|Y(-]-.]h-[:dig(it:])>>>dddddddddddddddddddddddddd{101,}", 1, 0 }, - { "([P,{1(\?(\?(<=28,-218[^)}LoZX)])!!!!!!!!!!!!!!*[:blank(\?!cntrl:]ed)\\\\\\\\\\\\\\\\\\\\[\\L\?][:graph:]:*Y{-108,120}xCC)]", 1, 0 }, + { "[^([^[([^C|])]{,-56}[:xdigit:]{-144,}V])fYv{-[40,-58}$@@@@@@" + "@@@@@@@]|Y(-]-.]h-[:dig(it:])>>>dddddddddddddddddddddddddd{" + "101,}", + 1, 0 }, + { "([P,{1(\?(\?(<=28,-218[^)}LoZX)])!!!!!!!!!!!!!!*[:blank(\?!" + "cntrl:]ed)\\\\\\\\\\\\\\\\\\\\[\\L\?][:graph:]:*Y{-108,120}" + "xCC)]", + 1, 0 }, { "(A[:space:]PP{185}a^!!!!!!lllllll)*db\?$Pfr", 1, 0 }, - { "{-21,-118}kG[(\?{:xdigit:]})[:punct:]{69}Qyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy5{}TTTTTTTTTTTTTTTTTTTTT", 0, 0 }, - { "[[^[P(\?<=P$X>0^d.[:punct:](\?#ccccccccccccccccccccccccc{}3N000(\?>00000000000000000000000000000]f[:punct:]5)).R================{,222}^wwwwwwww$)]-{} ]{,-22}CjP{242,}", 0, 0 }, + { "{-21,-118}kG[(\?{:xdigit:]})[:punct:]{69}" + "Qyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy5{}TTTTTTTTTTTTTTTTTTTTT", + 0, 0 }, + { "[[^[P(\?<=P$X>0^d.[:punct:](\?#ccccccccccccccccccccccccc{}" + "3N000(\?>00000000000000000000000000000]f[:punct:]5)).R======" + "=========={,222}^wwwwwwww$)]-{} " + "]{,-22}CjP{242,}", + 0, 0 }, { "[(\?#^]{})", 0, 0 }, - { "[^([[([([[([^[^(\?:(\?(\?(!)]\"))h>\"RRRRRRRRRRRRRRRR[^RRRRR{68,-65}7Q(\?{]", 0, 0 }, + { "[^([[([([[([^[^(\?:(\?(\?(!)]\"))h>\"RRRRRRRRRRRRRRRR[^" + "RRRRR{68,-65}7Q(\?{]", + 0, 0 }, { "(P{}){175,}PP{}rttttttttttt", 1, 0 }, - { "[:bla(\?{nkcntrl(\?#:]})))))))))))))))))))))))!!!!sR{})", 0, 0 }, + { "[:bla(\?{nkcntrl(\?#:]})))))))))))))))))))))))!!!!sR{})", 0, + 0 }, { " [:digit:]dAAAAAAAAAAAAA^[:ascii(:]55)^", 0, 0 }, { "($*)dZY", -1, 0 }, - { "[:graph:][:lowerprint:]S[:gr(\?=aph:]{-128,}666666666666666666666{}[:upperword:]|nnnnnnnnnnnnnnnnnnnnnnnnnnB)c[:xdigit:]{-225,}{-4,}{-192,}QQQQQQQQQQQQQQQ@@@@@@@@@@@@@@@@@@@@@@.", 0, 0 }, + { "[:graph:][:lowerprint:]S[:gr(\?=aph:]{-128,}" + "666666666666666666666{}[:upperword:]|" + "nnnnnnnnnnnnnnnnnnnnnnnnnnB)c[:xdigit:]{-225,}{-4,}{-192,}" + "QQQQQQQQQQQQQQQ@@@@@@@@@@@@@@@@@@@@@@.", + 0, 0 }, { "([:digit:]s{44,}{}{-31,}c{,-130}pP){-241,}UeN", 1, 0 }, - { "([^)((\?>\?#{}hK\"V2\?d][KKK(\?imsxim:KKKKKKKKKKKKKKKKKKKK[^KKKKKKKKKWWWW[WWWWWWWWWWWWWWWWW)B])_l_3", 1, 0 }, + { "([^)((\?>\?#{}hK\"V2\?d][KKK(\?imsxim:KKKKKKKKKKKKKKKKKKKK[^" + "KKKKKKKKKWWWW[WWWWWWWWWWWWWWWWW)B])_l_3", + 1, 0 }, { "[(^[(\?!*){[^,91}].j]*]L)*c|[:alpha:]&", 0, 0 }, - { "[^[[[^[777GGG(\?:W_U(\?imsxms:[:punct:]A]-)[:digit:][:blankcntrl(\?(:]][:alnum:)])]WRRRRRRRRRRRRRRRRRRRRRRRRRRR]{31,}[:xdigit:]][:xdigit:]))))))))))))))))))))))$[:xdigit:]", 0, 0 }, - { "[:ascii:]m*[:punct:]#[(\?<!:punct:][:alpha:]-,7vyXeeeeeeeeeeeeeeeeeeeeeeeee^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:digit:]''''''''''''''''')", 0, 0 }, - { "([^*[(:punct:]9999999999999999999{147,}]j{,193}{171}Z-)){208}0[:graph:]yDt", 1, 0 }, - { "(dw[[:alpha:]U]ttt[tttttttttttttttttttt]Q^171e)[:xdigit:]/", 1, 0 }, - { "[[^((\?#)Tqqqqqqqqqqqqqqqqqqqqqqqqq105++++++++++++++++++++++++++b7V+7dit]])|D", 0, 0 }, - { "{}P7.Ajh[:xdigit:]^[:blankc((\?(\?<=nt[rl:]FFF)-]){}o|a[:grap(\?!h:]))PsssssssssssssssssssssssssssssssN^{-60,}Kb", 0, 0 }, - { "[:alpha(\?(:]$!_+777777777777777777777777O)666)lll[^llllll[^l{{{{{{{{{{{{{{{{{{{{{{|]{-217,}MoEl`7)^)LlU[:alph[a:]({-241,27})]]{-212}{,249}n)X", 1, 0 }, + { "[^[[[^[777GGG(\?:W_U(\?imsxms:[:punct:]A]-)[:digit:][:" + "blankcntrl(\?(:]][:alnum:)])]WRRRRRRRRRRRRRRRRRRRRRRRRRRR]{" + "31,}[:xdigit:]][:xdigit:]))))))))))))))))))))))$[:xdigit:]", + 0, 0 }, + { "[:ascii:]m*[:punct:]#[(\?<!:punct:][:alpha:]-," + "7vyXeeeeeeeeeeeeeeeeeeeeeeeee^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + "^%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:digit:]''''''''''''''''')", + 0, 0 }, + { "([^*[(:punct:]9999999999999999999{147,}]j{,193}{171}Z-)){" + "208}0[:graph:]yDt", + 1, 0 }, + { "(dw[[:alpha:]U]ttt[tttttttttttttttttttt]Q^171e)[:xdigit:]/", + 1, 0 }, + { "[[^((\?#)Tqqqqqqqqqqqqqqqqqqqqqqqqq105++++++++++++++++++++++" + "++++b7V+7dit]])|D", + 0, 0 }, + { "{}P7.Ajh[:xdigit:]^[:blankc((\?(\?<=nt[rl:]FFF)-]){}o|a[:" + "grap(\?!h:]))PsssssssssssssssssssssssssssssssN^{-60,}Kb", + 0, 0 }, + { "[:alpha(\?(:]$!_+777777777777777777777777O)666)lll[^llllll[^" + "l{{{{{{{{{{{{{{{{{{{{{{|]{-217,}MoEl`7)^)LlU[:alph[a:]({-" + "241,27})]]{-212}{,249}n)X", + 1, 0 }, { "[U|ajP[:alnum:]n[(:digit:]]W)[:graph:]b[:xdigit:].P", 0, 0 }, - { "(([:low(\?-imsx:erprint:]|{}[:ascii:][:gr(\?:aph:])>>>>>>>>>>>>>{,-129}))\?{-226,}^P)R", 2, 0 }, - { "[^[[nnnnnnnnnn(\?=nnnn(\?!nnnnnnnnnnnn(\?#nnnnnn{,-38}N){202,}]$[:alnum:])]t][:alnum:[]^=w){237}][:alpha:]-[:alpha:]+e", 0, 0 }, + { "(([:low(\?-imsx:erprint:]|{}[:ascii:][:gr(\?:aph:])>>>>>>>>>" + ">>>>{,-129}))\?{-226,}^P)R", + 2, 0 }, + { "[^[[nnnnnnnnnn(\?=nnnn(\?!nnnnnnnnnnnn(\?#nnnnnn{,-38}N){" + "202,}]$[:alnum:])]t][:alnum:[]^=w){237}][:alpha:]-[:alpha:]+" + "e", + 0, 0 }, { "()[(\?(:digit):]+qc)O88888888{,151}aJ", 1, 0 }, { "([^([(\?!sv(\?=)d]{-200,})N))]Z{-73,15}", 1, 0 }, - { "([\?\?\?\?|||||||||||(\?{||(\?=||||||||-}[))Ehhhhhhhhhhhhh{,202}&TcfL((\?:>)((\?!\?>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$8[:alpha:]\\d])]C[:graph:]h*,\"\?u{|mU,a)[:blankcntrl:][:lowerp(\?>rint:])PPnP+9.[:xdigit:]*PPjjjjjjjjjj~y<#*scf_\"^e[:xdig(\?(i)t(:])~$y)^){-131,77}^L%", 1, 0 }, - { "[^[(((\?>)$}h9$B5+yhU/Nqh$YYYYYYYYYYYYYYYYYYYYYShK)3WHw1vMMMMMMMMMMMMM(\?=MMMMMMMMMMMM[:alnum:]/)dddddddddddd(dddddd\"e5zLW)+![:space:]+BHGHfAS]\?IIIIIIIIIIIIIIII*&&&&&&&&&&&&&&&&&&)NNvwDteepjdm<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<${61,219}D][:digit:]0", -1, 0 }, + { "([\?\?\?\?|||||||||||(\?{||(\?=||||||||-}[))Ehhhhhhhhhhhhh{," + "202}&TcfL((\?:>)((\?!\?>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$8[:" + "alpha:]\\d])]C[:graph:]h*,\"\?u{|mU,a)[:blankcntrl:][:" + "lowerp(\?>rint:])PPnP+9.[:xdigit:]*PPjjjjjjjjjj~y<#*scf_\"^" + "e[:xdig(\?(i)t(:])~$y)^){-131,77}^L%", + 1, 0 }, + { "[^[(((\?>)$}h9$B5+yhU/" + "Nqh$YYYYYYYYYYYYYYYYYYYYYShK)3WHw1vMMMMMMMMMMMMM(\?=" + "MMMMMMMMMMMM[:alnum:]/" + ")dddddddddddd(dddddd\"e5zLW)+![:space:]+BHGHfAS]" + "\?IIIIIIIIIIIIIIII*&&&&&&&&&&&&&&&&&&)NNvwDteepjdm<<<<<<<<<<" + "<<<<<<<<<<<<<<<<<<<<${61,219}D][:digit:]0", + -1, 0 }, { "[:punct:][{177,(\?=234}]ix9*)", 0, 0 }, { "([^K{,3(\?<=4}]I)\?U)", 1, 0 }, { "[([^[[[^([([^[^(\?=])X", 0, 0 }, - { "[:blankcntrl:(])qd_R\?{\?r[=\"[^[^6]vX8)a+{C%H84CK6Uy#E]sE{208}", 0, 0 }, - { "PPPPPPPPPPPPPPPPPPPPPPPPPPnnnnnnnnnn()[:upperword:]us", 1, 0 }, + { "[:blankcntrl:(])qd_R\?{\?r[=\"[^[^6]vX8)a+{C%H84CK6Uy#E]sE{" + "208}", + 0, 0 }, + { "PPPPPPPPPPPPPPPPPPPPPPPPPPnnnnnnnnnn()[:upperword:]us", 1, + 0 }, { "x{,46}[:graph:]LU{}CU)", 0, 0 }, { "()-t|[^W{}][:lo[^werprint:]{}]\?b5", 1, 0 }, { "()x5A", 1, 0 }, - { "[([^]-217)]s{-47,135}0000000000000000000000000000000{,-108}", 0, 0 }, + { "[([^]-217)]s{-47,135}0000000000000000000000000000000{,-108}", + 0, 0 }, { "[^((\?{[^L\?u]})f", 0, 0 }, { "()[[^^(\?{y(\?=VF_(\?<=]D}))]-= {46,})^5bIEQ{,-96}Z", 1, 0 }, - { "([^{}f[:punct:]\"X%%%%%%%%%%%%%%%%%%%%]5{-194}A[:punct:]mnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn+AAAAAAAAAA-)", 1, 0 }, + { "([^{}f[:punct:]\"X%%%%%%%%%%%%%%%%%%%%]5{-194}A[:punct:]" + "mnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn+AAAAAAAAAA-)", + 1, 0 }, { "(CCCCCCCCCCCCCCCCCCCC{-230}352{-182,-68}O4{})", 1, 0 }, - { "([^[^\?[:space:]$TTTTTTTTTTTTLLLLL[^LLLLLLLLLL[^({}{4,-179}]]J] C]){}C{}{-224,})QQQQQQQQQQQQQQQQQ^", 1, 0 }, + { "([^[^\?[:space:]$TTTTTTTTTTTTLLLLL[^LLLLLLLLLL[^({}{4,-179}]" + "]J] C]){}C{}{-224,})QQQQQQQQQQQQQQQQQ^", + 1, 0 }, { "([[:alnum:]].){-155,-82}dzI{55,}^", 1, 0 }, - { "([[:alnum:](\?#{88,-178})[:graph:]NC\"pI[:punct:]rmWd5y^p+gUP]YYYYYYYYYYYYYYYYYYYY~{,-62}{,200}{-109}{}+333333333333333333333333333333{}p)^.hhhhhhhhhhhhhhh", 1, 0 }, - { "[000000(\?mmsx:00000000000000000000000)M]]]]2*`[^]QQQQQQQQ(\?<=QQQQQQQQQQQQQQQQQQQQQQQ])\"<h\?", 0, 0 }, - { "[^((<g(\?>5j[bbbbbbb(\?{bb)o{}3(\?imxisx:E]g})YYYYY[:blankcntr(\?#l:].(()w264[:ascii:]^)[:ascii:]G)&(n {^PGn[:xdigit:])nv_e|]{-103,30}", 3, 0 }, - { "[^(([(\?!{}@[^HCO[[^^D[|]{,-49}][:xdigit:]]c`4[:ascii(\?<!:])$66666666666)*)]PP$Z[:alpha:]{,-235}UK],(aT/+6rbMqs60EloA)[:g(\?isx:raph:]!)]z$o{-24,}x1E[:blankcntrl:]ZDFvk", 1, 0 }, + { "([[:alnum:](\?#{88,-178})[:graph:]NC\"pI[:punct:]rmWd5y^p+" + "gUP]YYYYYYYYYYYYYYYYYYYY~{,-62}{,200}{-109}{}+" + "333333333333333333333333333333{}p)^.hhhhhhhhhhhhhhh", + 1, 0 }, + { "[000000(\?mmsx:00000000000000000000000)M]]]]2*`[^]QQQQQQQQ(" + "\?<=QQQQQQQQQQQQQQQQQQQQQQQ])\"<h\?", + 0, 0 }, + { "[^((<g(\?>5j[bbbbbbb(\?{bb)o{}3(\?imxisx:E]g})YYYYY[:" + "blankcntr(\?#l:].(()w264[:ascii:]^)[:ascii:]G)&(n " + "{^PGn[:xdigit:])nv_e|]{-103,30}", + 3, 0 }, + { "[^(([(\?!{}@[^HCO[[^^D[|]{,-49}][:xdigit:]]c`4[:ascii(\?<!:]" + ")$66666666666)*)]PP$Z[:alpha:]{,-235}UK],(aT/" + "+6rbMqs60EloA)[:g(\?isx:raph:]!)]z$o{-24,}x1E[:blankcntrl:]" + "ZDFvk", + 1, 0 }, { "[:blank(\?=cntrl:]US@.!\"[:digit:]*E)$16182", 0, 0 }, - { "[-{}x{3772[}][:(\?<=xdigit:][:u(\?#pperword:].W)aD)<pfN<b=C|-{-38}EZdOP|!>ggggggggggggggg\\\\\\\\\\\\\\\\\\\\\\\\\\Ef[:space:]\?][:ascii:]{21,}", 0, 0 }, - { "([:xdigit:]W[:u(pperword(\?::]jS [:upperword:]*)[:alpha:]nnnnnnnnnnn))-148}SSu", 1, 0 }, + { "[-{}x{3772[}][:(\?<=xdigit:][:u(\?#pperword:].W)aD)<pfN<b=C|" + "-{-38}EZdOP|!>ggggggggggggggg\\\\\\\\\\\\\\\\\\\\\\\\\\Ef[:" + "space:]\?][:ascii:]{21,}", + 0, 0 }, + { "([:xdigit:]W[:u(pperword(\?::]jS " + "[:upperword:]*)[:alpha:]nnnnnnnnnnn))-148}SSu", + 1, 0 }, { "([^(\?!\?)[(:upperword:])Bx^x$~lCr6*)6", 1, 0 }, - { "[{,-78}Y[:xdigit:][^s(\?>]P[:space:])]YYYYYYYYY[:punct:][:alnum:][:blankcntrl:]", 0, 0 }, - { "([MMMMMM(\?(MMM)M(\?<=MMMMMMMMMMMMMMM[^M)]en][:punct:]-[:alpha:]))Nr[:space:]", 1, 0 }, - { "~=1([^(\?=(\?:l){}])j{-44}{-18}[^u[:graph:]]{-187,}[:xdigit:]w[:alpha:])", 1, 0 }, - { "[ccccc(\?>c(\?{cccc[ccccwetoCei+)w&-+{,-142}[:alpha:]PP66io4(|zkA=],,,,,,,,,,,,,,,,,,,,,Lx5Cx{d2bb}]{188}U~~~~~~~~~~~~~~~~~~~~~~~})", 0, 0 }, + { "[{,-78}Y[:xdigit:][^s(\?>]P[:space:])]YYYYYYYYY[:punct:][:" + "alnum:][:blankcntrl:]", + 0, 0 }, + { "([MMMMMM(\?(MMM)M(\?<=MMMMMMMMMMMMMMM[^M)]en][:punct:]-[:" + "alpha:]))Nr[:space:]", + 1, 0 }, + { "~=1([^(\?=(\?:l){}])j{-44}{-18}[^u[:graph:]]{-187,}[:xdigit:" + "]w[:alpha:])", + 1, 0 }, + { "[ccccc(\?>c(\?{cccc[ccccwetoCei+)w&-+{,-142}[:alpha:]" + "PP66io4(|zkA=],,,,,,,,,,,,,,,,,,,,,Lx5Cx{d2bb}]{188}U~~~~~~~" + "~~~~~~~~~~~~~~~~})", + 0, 0 }, { "Q|0\"[:d(\?:igit:]^{,-174})", 0, 0 }, { "[^[(\?>rh])]", 0, 0 }, { "[ees{{{{{{{{{{{{{{{{{bbbbbbb4`ml******(\?=****+])", 0, 0 }, - { "((hdG[((\?<=:dig(it:])[^[:alpha:]$(\?sxi:)x{11390}[(\?{:upperword:]~)i 8[:blankcn[trl:(])]+{,-183}Zqp", 2, 0 }, + { "((hdG[((\?<=:dig(it:])[^[:alpha:]$(\?sxi:)x{11390}[(\?{:" + "upperword:]~)i 8[:blankcn[trl:(])]+{,-183}Zqp", + 2, 0 }, { "Dd{D8`+DW={-[53,1(\?<=71}])", 0, 0 }, { "[:(\?(alpha:][:punct:])", 0, 0 }, - { ".LLLLLLLLLLLLLLLLLLLLLLLLLLLL{}pP[:punct:]x0CZ{30,}!!!(!!!!!!!!!!!!!!!!!!!!!!!!!==@77.%[:graph:]D)", 1, 0 }, - { "[^[^[[r(\?#]){-237,}RRRRRRRRRRRRRRRRRRRRRRRR[^Rll(\?!(\?{lllll]", 0, 0 }, + { ".LLLLLLLLLLLLLLLLLLLLLLLLLLLL{}pP[:punct:]x0CZ{30,}!!!(!!!!!" + "!!!!!!!!!!!!!!!!!!!!==@77.%[:graph:]D)", + 1, 0 }, + { "[^[^[[r(\?#]){-237,}RRRRRRRRRRRRRRRRRRRRRRRR[^Rll(\?!(\?{" + "lllll]", + 0, 0 }, { "()*ooooooooooooooooooooyyyyyyyyyyyyyyy", 1, 0 }, { "{,4(}D)JJJJJJJJJJJJJJJJJJJJJJJJJ", 1, 0 }, - { "((b.D{}[:al[pha:]{64}]{})==========================[:alnum:]h>77b)!Ab", 2, 0 }, - { "([^[^[^oooooooooooooooooooooo][:space:][:punct:]PeniKe*~$g\?${>[:lowerprint:]w))))))))))))))){}yyyyyyyyyyyyyyyyyy]pP.|QhZ]{,190})sssssssssssssr+=[:blankcntrl:]WWWWWWWWWWWWWWWWWWWWW", 1, 0 }, - { "([*(\?{})hhhhhhhhhhhhhhhh]G{,-170}QdErrrrrrrc-jjjjjjjjjjjjjjjjjjjjn+{-130,-10})PpDS@Bee", 1, 0 }, + { "((b.D{}[:al[pha:]{64}]{})==========================[:alnum:]" + "h>77b)!Ab", + 2, 0 }, + { "([^[^[^oooooooooooooooooooooo][:space:][:punct:]PeniKe*~$" + "g\?${>[:lowerprint:]w))))))))))))))){}yyyyyyyyyyyyyyyyyy]pP." + "|QhZ]{,190})sssssssssssssr+=[:blankcntrl:]" + "WWWWWWWWWWWWWWWWWWWWW", + 1, 0 }, + { "([*(\?{})hhhhhhhhhhhhhhhh]G{,-170}QdErrrrrrrc-" + "jjjjjjjjjjjjjjjjjjjjn+{-130,-10})PpDS@Bee", + 1, 0 }, { "([:b(\?=lankcntrl:]))T[:alnum:]{-224}ywt", 1, 0 }, - { "([633(\?<=333(\?<=3333333333(333333)^\?]aGA)[:digi(\?>(\?{t:])$[[:space:][:xdigit:])|8T\?',_{171}{}{113}b\?5kAv0/7{})`huh>xM]C8pYRz]s$Eu08)", 1, 0 }, + { "([633(\?<=333(\?<=3333333333(333333)^\?]aGA)[:digi(\?>(\?{t:" + "])$[[:space:][:xdigit:])|8T\?',_{171}{}{113}b\?5kAv0/" + "7{})`huh>xM]C8pYRz]s$Eu08)", + 1, 0 }, { "-(pP)[:alnum:]$^", 1, 0 }, { "[^x(\?{{17681}]P*)U(_t/8E_\"iN})3333333", 1, 0 }, - { "(([^([[r(\?=[[^^*kx$][:alpha:]:::[:::::[^[^::::::::((\?{\?{::]).^p[:space:]}){52}{}]W{}fn", 2, 0 }, - { "[:(\?>punct:]Ef[:xdigit:]x{c07b}{-50}Z{129,}YL1T`\\A)x[:punc(\?=t:]e[:xdigit:]2c6E46Y)+n ", 0, 0 }, - { "[^(\?!{,-79}[:punct:]'|}>,)][:blankcntrl:]{-118,-231}{-119,-50}:XXXXXXXXXXXXXXXXX-~{}$txlB)3KFL", 0, 0 }, - { "[^(([^fccccccccccccccccccc(\?<!ccccgQeKMfKzz]X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$[:l(\?<=(\?<=owerprint:]))s{-97}{}))EUi${,-132}'{79}---------{,-93}77777777777777777[:lowerprint:].:H)[:punct:]nnnnnncP\?s1:dGed{186}N@pppppppppppppppppppppP{-212,-110}[:space:][:lowerprint:]$S}7{-112,164}-*.{-184,}OOOOOOOOOO]f\?", 0, 0 }, + { "(([^([[r(\?=[[^^*kx$][:alpha:]:::[:::::[^[^::::::::((\?{\?{:" + ":]).^p[:space:]}){52}{}]W{}fn", + 2, 0 }, + { "[:(\?>punct:]Ef[:xdigit:]x{c07b}{-50}Z{129,}YL1T`\\A)x[:" + "punc(\?=t:]e[:xdigit:]2c6E46Y)+n ", + 0, 0 }, + { "[^(\?!{,-79}[:punct:]'|}>,)][:blankcntrl:]{-118,-231}{-119,-" + "50}:XXXXXXXXXXXXXXXXX-~{}$txlB)3KFL", + 0, 0 }, + { "[^(([^fccccccccccccccccccc(\?<!ccccgQeKMfKzz]X$$$$$$$$$$$$$$" + "$$$$$$$$$$$$$$$$$[:l(\?<=(\?<=owerprint:]))s{-97}{}))EUi${,-" + "132}'{79}---------{,-93}77777777777777777[:lowerprint:].:H)[" + ":punct:]nnnnnncP\?s1:dGed{186}N@pppppppppppppppppppppP{-212," + "-110}[:space:][:lowerprint:]$S}7{-112,164}-*.{-184,}" + "OOOOOOOOOO]f\?", + 0, 0 }, { "(([\?#(\?>)])qcU$Q7|82\?{})", 2, 0 }, { "[^yyyyyyyyyyyyyyyyyyyy(\?#yyyyyyyyyyya][:ascii:]\?)", 0, 0 }, - { "(([((\?{)EEEE(\?<!EEEEE(\?:EEEEEE~)}){244,}QQQQQQQQQQQQQQQQQQQ(\?>QQQQQQ(\?!QQQQQ][:digit:]\?))99999999999999)[:digit:][:upperword:]b))PP{}{}", 2, 0 }, + { "(([((\?{)EEEE(\?<!EEEEE(\?:EEEEEE~)}){244,}" + "QQQQQQQQQQQQQQQQQQQ(\?>QQQQQQ(\?!QQQQQ][:digit:]\?))" + "99999999999999)[:digit:][:upperword:]b))PP{}{}", + 2, 0 }, { "(K(c=B))", 2, 0 }, { "(G`*s\?b[:g(raph:]))", 1, 0 }, - { "[^[([[[*QQQQQQQQQQQQQQQQ(\?=(\?=QQQQQQ(\?<!QQQQQQQQZddddddddd((\?{\?>ddddddddddc{22,}iiiiiiiii(iiiiiiiiiiiiiii(\?#iiiiiii[^i))\?\?\?\?\?\?]WWW)[:lowerprint:])]{-60,202}+[:upperword:]f[:xdigit:][:alnum:]{,-214})1~~~~~~~MMMMMMMMMMMMMMMMMM.", 0, 0 }, + { "[^[([[[*QQQQQQQQQQQQQQQQ(\?=(\?=QQQQQQ(\?<!" + "QQQQQQQQZddddddddd((\?{\?>ddddddddddc{22,}iiiiiiiii(" + "iiiiiiiiiiiiiii(\?#iiiiiii[^i))\?\?\?\?\?\?]WWW)[:" + "lowerprint:])]{-60,202}+[:upperword:]f[:xdigit:][:alnum:]{,-" + "214})1~~~~~~~MMMMMMMMMMMMMMMMMM.", + 0, 0 }, { "({-102,})A.", 1, 0 }, - { "[((((\?<!(\?[^>(\?#\?()))p\"JD.{}(\?>)))((\?{l(\?<=).'053][:xdigit:]N+)})]WWWW%[:asc(\?{ii:]}))B[:alnum:]X){}s[:digit:]", 0, 0 }, - { "x7&{139}WWWWWWWWWWWWWW[:blankcntr[^(\?<!l:]-71]\"{-167}cqkI)[:dig[^it:]{}{}[:digit:]*[:punct:]-[l11111111111111111(\?(111111111{175,-216}~[:alnum:]`+X1F)vCpWSp(\?>~[^n@f`````````````)````````P])Y,N{}{}]{}pXF@)", 0, 0 }, + { "[((((\?<!(\?[^>(\?#\?()))p\"JD.{}(\?>)))((\?{l(\?<=).'053][:" + "xdigit:]N+)})]WWWW%[:asc(\?{ii:]}))B[:alnum:]X){}s[:digit:]", + 0, 0 }, + { "x7&{139}WWWWWWWWWWWWWW[:blankcntr[^(\?<!l:]-71]\"{-167}cqkI)" + "[:dig[^it:]{}{}[:digit:]*[:punct:]-[l11111111111111111(\?(" + "111111111{175,-216}~[:alnum:]`+X1F)vCpWSp(\?>~[^n@f`````````" + "````)````````P])Y,N{}{}]{}pXF@)", + 0, 0 }, { "G[([(\?(^)$])P]^[:alnum:]){,-48}[:blankcntrl:]{}", 0, 0 }, - { "[[^[^f(\?=f(\?<=fffffff[^fffffffff[^fffffffff(\?<=fff]){-194,150}fx{e5a4}V", 0, 0 }, + { "[[^[^f(\?=f(\?<=fffffff[^fffffffff[^fffffffff(\?<=fff]){-" + "194,150}fx{e5a4}V", + 0, 0 }, { "9[:xdigit(\?{:]})", 0, 0 }, - { "[^([[(\?>()$xxxxxxxxxxxxxx[xxxxxxxxxxxxxxxx((\?=aA)s13]])pp[(\?>pppppppppppppppp|{}){20,}]b)]{-179,183}{-204,}[:ascii:])]-11111111{}{,132}qooooooooooooooooooo{}${}|9t", 0, 0 }, + { "[^([[(\?>()$xxxxxxxxxxxxxx[xxxxxxxxxxxxxxxx((\?=aA)s13]])pp[" + "(\?>pppppppppppppppp|{}){20,}]b)]{-179,183}{-204,}[:ascii:])" + "]-11111111{}{,132}qooooooooooooooooooo{}${}|9t", + 0, 0 }, { "([^[{}]\"[^6]*-{,-106}{}u]BR~8WG,U-)[:blankcntrl:]", 1, 0 }, { "[''''''''(''''''''''z])c", 0, 0 }, { "[^[(\?>])[:alnum:]r[:alnum:]+{,215}D]", 0, 0 }, - { "([({,127}7Qr(\?:z)pPNev%}(\?msximsx:4(\?<!){}&.D5555(\?<=55555555555555555555i$[:xdigit:]){,-157}[:graph:]U[:punct:]nn(\?=nnnnnnnnnnnn(\?>nn(\?:nnnnnnnn_U{}]E)):^oooooooooooooooooooooooooooo)", 1, 0 }, - { "[^(\?#)(\?<!k2z]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]BW[:alnum:][:graph:]{157}Y]s$C)[:graph:]{,-189}", 0, 0 }, - { "$+CCCCCCCCC[^CCCCCC(\?<=Ca=]r{-81}[:alpha:][:alpha:])E=", -1, 0 }, - { "[(((\?=\?{([^(\?<=)])>!(([:alnum:]{252}{}})ffffffffffffl){}A2r\?~ImE\"[:punct:]){}[:digit:]", 2, 0 }, + { "([({,127}7Qr(\?:z)pPNev%}(\?msximsx:4(\?<!){}&.D5555(\?<=" + "55555555555555555555i$[:xdigit:]){,-157}[:graph:]U[:punct:]" + "nn(\?=nnnnnnnnnnnn(\?>nn(\?:nnnnnnnn_U{}]E)):^" + "oooooooooooooooooooooooooooo)", + 1, 0 }, + { "[^(\?#)(\?<!k2z]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]BW[:alnum:][:" + "graph:]{157}Y]s$C)[:graph:]{,-189}", + 0, 0 }, + { "$+CCCCCCCCC[^CCCCCC(\?<=Ca=]r{-81}[:alpha:][:alpha:])E=", -1, + 0 }, + { "[(((\?=\?{([^(\?<=)])>!(([:alnum:]{252}{}})ffffffffffffl){}" + "A2r\?~ImE\"[:punct:]){}[:digit:]", + 2, 0 }, { "([:blank[cntrl:]].t^P)", 1, 0 }, { "[^[(\?:X])|rrrrrrrrrrrrrrrrrrrrrrrrrr*P]Q", 0, 0 }, - { "[[[^(\?{((\?<!))s})(\?<!A){14}(\?:L*+TTTTTTT]U{[^-12([\?!,}\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)Y`Y)L]|]]|]", 0, 0 }, + { "[[[^(\?{((\?<!))s})(\?<!A){14}(\?:L*+TTTTTTT]U{[^-12([\?!,}" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)Y`Y)L]|]]|" + "]", + 0, 0 }, { "hkXzf',]yP$+[:u(pperword:])", -1, 0 }, { "(#[:blankcnt(\?iximsx:rl:])$QQQQQQ{}[:digit:])\?A", 1, 0 }, { "(B{-34,})*{,106}", 1, 0 }, { "[(\?{:graph:]})", 0, 0 }, { "((){}{,63}[:punct:]^t[:space:])^17737", 2, 0 }, - { "([^[SSSSSSSSS[SSSSSSSSSSSSSSS[([[[{38,}]Jn][:alpha:]])])$'", 1, 0 }, - { "[^({}{95})B{1(\?>15}]x{f779}ZZ,Wo)O[:alpha:][:lowerprint:]{81,228}Q[:upperword:]", 0, 0 }, - { "[[^[^()n[[[[[[[[[[[[^[[[[[[[[[[(\?: G)(\?{K![^m) j(\?:C|((\?:n*Xlaa908:n$m,))[:xdigit:]x(\?{{1a5cd}pppppppppppppp(\?(pppp)p(pQ)))ddddddddddddddddddddddddddddddd]q[:alnum:(\?{]Ga})\?})@[:lowerprint:]{,169}[:blankcntrl:][:graph:]]n{-76,}|U\"{,-54}t]I{}{-64,-232}]\?].\?{-111,227}) @hFp\?j=H$Wbu<{,209}De{,145}{206}-})[:blankcntrl:]", 0, 0 }, - { "[^[^(LLLLLLLLLLLLLL[^L[L[:alpha:]3{,189}(\?#(\?>n){}^EXXXXXXXXXXXXXXXXXXXXXXXXX]c*)^r=$WWWWWWWWWWWWW", 0, 0 }, + { "([^[SSSSSSSSS[SSSSSSSSSSSSSSS[([[[{38,}]Jn][:alpha:]])])$'", + 1, 0 }, + { "[^({}{95})B{1(\?>15}]x{f779}ZZ,Wo)O[:alpha:][:lowerprint:]{" + "81,228}Q[:upperword:]", + 0, 0 }, + { "[[^[^()n[[[[[[[[[[[[^[[[[[[[[[[(\?: G)(\?{K![^m) " + "j(\?:C|((\?:n*Xlaa908:n$m,))[:xdigit:]x(\?{{1a5cd}" + "pppppppppppppp(\?(pppp)p(pQ)))" + "ddddddddddddddddddddddddddddddd]q[:alnum:(\?{]Ga})\?})@[:" + "lowerprint:]{,169}[:blankcntrl:][:graph:]]n{-76,}|U\"{,-54}" + "t]I{}{-64,-232}]\?].\?{-111,227}) " + "@hFp\?j=H$Wbu<{,209}De{,145}{206}-})[:blankcntrl:]", + 0, 0 }, + { "[^[^(LLLLLLLLLLLLLL[^L[L[:alpha:]3{,189}(\?#(\?>n){}^" + "EXXXXXXXXXXXXXXXXXXXXXXXXX]c*)^r=$WWWWWWWWWWWWW", + 0, 0 }, { ")w###################", 0, 0 }, - { "{,121}[:d(\?(i)git:])E\?[:punct:]LLLLLLLLL[:ascii:]+", 0, 0 }, + { "{,121}[:d(\?(i)git:])E\?[:punct:]LLLLLLLLL[:ascii:]+", 0, + 0 }, { "([]]]]]]]]]]]]][:space:]Jrt3o.]b)pwwwwwwwwwwwQfm~", 1, 0 }, - { "[+-{,-120}*(\?!()t*(\?(\?{>G)F)yd]V{}f<\?}){245}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[:upperword:]", 0, 0 }, - { "(DDDDDDDDDDDDDDDDDDDDDDDDDDDDDc[:space:][:pu[^nct:]{-11,12}[:ascii:][:alpha:]{,155}P])", 1, 0 }, + { "[+-{,-120}*(\?!()t*(\?(\?{>G)F)yd]V{}f<\?}){245}" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[:upperword:]", + 0, 0 }, + { "(DDDDDDDDDDDDDDDDDDDDDDDDDDDDDc[:space:][:pu[^nct:]{-11,12}[" + ":ascii:][:alpha:]{,155}P])", + 1, 0 }, { "()ggggggg{-136,-21}", 1, 0 }, - { "([^((\?<=U\?)(\?=^^^^^^^^^^^[^^^^^^^^^^^^^///(\?#//[////////////////////(\?()#######b+]$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$^[:digit:])\\U]Q8@}4d)\\U", 1, 0 }, - { "A[:graph(\?::])-mo=U[:upperword:]ttttttttttttttttttttttttttt", 0, 0 }, - { "[^(((\?=\?im-m(sx:)c~~[^~~~~~~~~~~~~~(\?>~~~~~~~~~~~~~SSSSSSSSSSSSSSSSSSSS]{51,}[:digit:]{,-179}N))kk[kkkkkkkkkkkkkkg$)[(\?::punct:]zWl)]|)*", 0, 0 }, + { "([^((\?<=U\?)(\?=^^^^^^^^^^^[^^^^^^^^^^^^^///(\?#//[////////" + "////////////" + "(\?()#######b+]$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$^[:digit:])" + "\\U]Q8@}4d)\\U", + 1, 0 }, + { "A[:graph(\?::])-mo=U[:upperword:]" + "ttttttttttttttttttttttttttt", + 0, 0 }, + { "[^(((\?=\?im-m(sx:)c~~[^~~~~~~~~~~~~~(\?>~~~~~~~~~~~~~" + "SSSSSSSSSSSSSSSSSSSS]{51,}[:digit:]{,-179}N))kk[" + "kkkkkkkkkkkkkkg$)[(\?::punct:]zWl)]|)*", + 0, 0 }, { "[((\?=()+A)][:graph:]x0B)[:graph:]", 0, 0 }, - { "(nR%B[:blankcntrl:]C=|en-[:digit:]n[:graph:]HHHH[HH]D\?%[:digit:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.z(oF9zW8A7cfff(f))-[:blankcntrl:][:blankcntrl:]A[:digit:])D{,-243}", 3, 0 }, + { "(nR%B[:blankcntrl:]C=|en-[:digit:]n[:graph:]HHHH[HH]D\?%[:" + "digit:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.z(oF9zW8A7cfff(f))-[" + ":blankcntrl:][:blankcntrl:]A[:digit:])D{,-243}", + 3, 0 }, { "([[()]]{,-251(})\?L)uw@", 2, 0 }, - { "\"|{(,-144})A.ooooooooo(ooooooFFFFFFFFFFFFF\?)n{,-18}", 2, 0 }, + { "\"|{(,-144})A.ooooooooo(ooooooFFFFFFFFFFFFF\?)n{,-18}", 2, + 0 }, { "([^([(([[^([000000[0(0(\?!0(\?=0000000])45|E]", 1, 0 }, - { "[B[[[[[[[[[[[|{}*oKqv%(\?<=wsQ{1pMeK1^6%nLNqi<@ge][:punct:]= M@* D|NwL\\-117\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"~Qnd]h.O\"01x:[:alpha:]^){}D}\"", 0, 0 }, - { "([[RRRRRRRRRRRRRRRRRRRRRRRRRRRRxpSrx{7d79}*oJ2`Ft{n1,3g:1H@bT$D &[n/Cg)=ld@Ir{Fk>*4*`(\?>````````````````````(\?:`````.....................]]{,246})7 \"F4[^F|/g)]+e`rw@{,-69}H)", 1, 0 }, - { "([(\?<=)X[:digit:]PP.[(\?#:((\?#\?#graph:])[:digit:][Q+)(N][:alpha:]]f)[:graph:])+Elllllllllllllllll[:digit:]=)pP{uU-20bzY|ZKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKt<c", 1, 0 }, - { "[^(([^$(\?:(\?#w)[(\?::punct:]]d{-149,}[:ascii:])[:blankcntrl:]@@@@@[@@@@@@@@@@@@@@[:graph:][:xdigit:]O[:alpha:]2$-[:graph:])[:lowerprint:]-\?#S[:blankcntrl:][:alnum:]){-77,}]d[:digit:]N5v+Sqqqqqqq^% -I4]*.)^[:alnum:]JDfjMRU7ttttttttttttjjjjjjjjjjjjjjjjjjjjjjCCCCCCCCCCCCCCCCCCCD{,21}{0,67}[:graph:]{,208}B", -1, 0 }, - { "(%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:ascii:])i{}[:lowerprint:]epxxxxxxxxxxxxxx[:lowerprint:]r-", 1, 0 }, + { "[B[[[[[[[[[[[|{}*oKqv%(\?<=wsQ{1pMeK1^6%nLNqi<@ge][:punct:]=" + " M@* " + "D|NwL\\-" + "117\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"~" + "Qnd]h.O\"01x:[:alpha:]^){}D}\"", + 0, 0 }, + { "([[RRRRRRRRRRRRRRRRRRRRRRRRRRRRxpSrx{7d79}*oJ2`Ft{n1,3g:1H@" + "bT$D " + "&[n/" + "Cg)=ld@Ir{Fk>*4*`(\?>````````````````````(\?:`````.........." + "...........]]{,246})7 \"F4[^F|/g)]+e`rw@{,-69}H)", + 1, 0 }, + { "([(\?<=)X[:digit:]PP.[(\?#:((\?#\?#graph:])[:digit:][Q+)(N][" + ":alpha:]]f)[:graph:])+Elllllllllllllllll[:digit:]=)pP{uU-" + "20bzY|ZKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKt<c", + 1, 0 }, + { "[^(([^$(\?:(\?#w)[(\?::punct:]]d{-149,}[:ascii:])[:" + "blankcntrl:]@@@@@[@@@@@@@@@@@@@@[:graph:][:xdigit:]O[:alpha:" + "]2$-[:graph:])[:lowerprint:]-\?#S[:blankcntrl:][:alnum:]){-" + "77,}]d[:digit:]N5v+Sqqqqqqq^% " + "-I4]*.)^[:alnum:]" + "JDfjMRU7ttttttttttttjjjjjjjjjjjjjjjjjjjjjjCCCCCCCCCCCCCCCCCC" + "CD{,21}{0,67}[:graph:]{,208}B", + -1, 0 }, + { "(%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[:ascii:])i{}[:lowerprint:]" + "epxxxxxxxxxxxxxx[:lowerprint:]r-", + 1, 0 }, { "([(^w(\?!)()])-s", 1, 0 }, - { "[aIIIIIIIIIIIII(\?imsxims(\?=x:IIIIIIIm^NXXXXX(\?!(\?isximsx:XXXXXXXXXXXXXS0]F)z))+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr{,-237})ZZZZZZZZZZZZZZZZZZZZZZ", 0, 0 }, + { "[aIIIIIIIIIIIII(\?imsxims(\?=x:IIIIIIIm^NXXXXX(\?!(" + "\?isximsx:XXXXXXXXXXXXXS0]F)z))+" + "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr{,-237})" + "ZZZZZZZZZZZZZZZZZZZZZZ", + 0, 0 }, { "(Z)[:alpha:]", 1, 0 }, { "U#Z(=)", 1, 0 }, - { "([:lowerprint:][:punct:])1cVb*[:xdigit:]&&&&&&&&&&&&&&&&&&&&&&&&O", 1, 0 }, + { "([:lowerprint:][:punct:])1cVb*[:xdigit:]&&&&&&&&&&&&&&&&&&&&" + "&&&&O", + 1, 0 }, { "()~K`3/[^*h[]G6[:upperw(\?()ord:]w)[:punct:]]{}", 1, 0 }, - { "[[[]V[:digit(\?>:])|l*KKKKKKKKKKKKKKKKK,,,,,,,[,,,s.{148,}P33333][:lo(\?<!werprin(\?!t:]ZZZZZZZZZZZZZZZZZZZZZZZ]{,-229}{-160,}){,-211}XPPP].{}z[:alnum:][:alpha:(\?=]t{166,}uuuuu6]i*p(m))[:space:]E|S", 1, 0 }, - { "[^(h(\?(\?({#2})(\?(\?#>Q){,57}%[:digit:]\?\?\?\?\?\?\?\?\?\?.[)]]d{)-49,}f)^O{,68})\?C", 0, 0 }, + { "[[[]V[:digit(\?>:])|l*KKKKKKKKKKKKKKKKK,,,,,,,[,,,s.{148,}" + "P33333][:lo(\?<!werprin(\?!t:]ZZZZZZZZZZZZZZZZZZZZZZZ]{,-" + "229}{-160,}){,-211}XPPP].{}z[:alnum:][:alpha:(\?=]t{166,}" + "uuuuu6]i*p(m))[:space:]E|S", + 1, 0 }, + { "[^(h(\?(\?({#2})(\?(\?#>Q){,57}%[:digit:]" + "\?\?\?\?\?\?\?\?\?\?.[)]]d{)-49,}f)^O{,68})\?C", + 0, 0 }, { "(}u])18621", 1, 0 }, - { "[:as(\?=cii:][^(\?=)(S-{.F-[:punct:]3-105^[:lowerprint:]111111111111111111111111---)][:alnum:][:ascii:]JJJJJwHSk", -1, 0 }, - { "[^3>>>>>>-sZ^^^^(\?>]Y[:di(\?(\?imxim:#git:]{-158,-102}[:punct:]{}{87,})))[:upperword:]", 0, 0 }, + { "[:as(\?=cii:][^(\?=)(S-{.F-[:punct:]3-105^[:lowerprint:]" + "111111111111111111111111---)][:alnum:][:ascii:]JJJJJwHSk", + -1, 0 }, + { "[^3>>>>>>-sZ^^^^(\?>]Y[:di(\?(\?imxim:#git:]{-158,-102}[:" + "punct:]{}{87,})))[:upperword:]", + 0, 0 }, { "[(\?<!^r]$W){}*[:alpha:].[:digit:]", 0, 0 }, { "[:ascii(\?::[^])X]-", 0, 0 }, { "[([^]Z)[:upperword:]N{}*[:graph:]*^", 0, 0 }, - { "([[(\?#^[(:graph:]]){205,}[:gr(aph:]T%]^MMMMMMMMMMMMMMMMMMMM){) <v\\[:digit:])", 1, 0 }, - { "[^Y.h~b(\?<=~P{(\?=169,65}\?[^\?\?\?\?\?\?\?\?\?[\?\?\?\?\?\?\?\?\?K\"s`[yT7oP[:alpha:]{})]zrrrrrrrrrrrrrr)]KKKKKKKKKKKKKKK[:digit:]S][:lowerprint:][:digit:]", 0, 0 }, + { "([[(\?#^[(:graph:]]){205,}[:gr(aph:]T%]^" + "MMMMMMMMMMMMMMMMMMMM){) <v\\[:digit:])", + 1, 0 }, + { "[^Y.h~b(\?<=~P{(\?=169,65}\?[^\?\?\?\?\?\?\?\?\?[" + "\?\?\?\?\?\?\?\?\?K\"s`[yT7oP[:alpha:]{})]zrrrrrrrrrrrrrr)]" + "KKKKKKKKKKKKKKK[:digit:]S][:lowerprint:][:digit:]", + 0, 0 }, { "(s)", 1, 0 }, - { "[u(\?!uuuuuuuuuuuuuuuuuuuu[:digit:]{,48}[:graph:]WL[:alnum:]]v=_)VN>{AjBBBBBBBBBBBBBBBBBBBBBBB[:upperword:]`'W)", 0, 0 }, - { "[^([[()DN1[^][|]\?]{-104,}])[:space:]][:lowerprint:]r[:alpha:].DU", 0, 0 }, - { "[^((33333333333333333333333(\?<=3333333D))kkkkkkkkkkkkkkkkkkkkkkk[k[:alpha:]])]X+", 0, 0 }, + { "[u(\?!uuuuuuuuuuuuuuuuuuuu[:digit:]{,48}[:graph:]WL[:alnum:]" + "]v=_)VN>{AjBBBBBBBBBBBBBBBBBBBBBBB[:upperword:]`'W)", + 0, 0 }, + { "[^([[()DN1[^][|]\?]{-104,}])[:space:]][:lowerprint:]r[:" + "alpha:].DU", + 0, 0 }, + { "[^((33333333333333333333333(\?<=3333333D))" + "kkkkkkkkkkkkkkkkkkkkkkk[k[:alpha:]])]X+", + 0, 0 }, { "[({,-17})[@e{220,(\?#41}])]]{-213,-225}", 0, 0 }, - { "[[^(\?#[(\?:^[[(\?(^]))]])]vvvvvvvvvvvvvvvvvvvvv{,96}|m]{-79,248}[:alpha:])", 0, 0 }, - { "([[(\?imsisx:^}$,-[:al(\?>num:]Xqqqqqqqqqqqq{-185,154}]b#+T){-241,})A{-27}[(\?<!:lowerprint:]X)[:punct:]ME-]+BBBBBBBBBBBBBBBBa|{-40}M8mhgD 0HU]{16})", -1, 0 }, - { "[^(\?>([\?()(\?#))]--R1rk^UnP.[(\?!:digit:]])^)[:upperword:]{}0000000000000000000000000000000~U{-139,-19}z<L-228", 0, 0 }, + { "[[^(\?#[(\?:^[[(\?(^]))]])]vvvvvvvvvvvvvvvvvvvvv{,96}|m]{-" + "79,248}[:alpha:])", + 0, 0 }, + { "([[(\?imsisx:^}$,-[:al(\?>num:]Xqqqqqqqqqqqq{-185,154}]b#+T)" + "{-241,})A{-27}[(\?<!:lowerprint:]X)[:punct:]ME-]+" + "BBBBBBBBBBBBBBBBa|{-40}M8mhgD 0HU]{16})", + -1, 0 }, + { "[^(\?>([\?()(\?#))]--R1rk^UnP.[(\?!:digit:]])^)[:upperword:]" + "{}0000000000000000000000000000000~U{-139,-19}z<L-228", + 0, 0 }, { "()-:=3uE$[:alnum:]bP%{-210,}", 1, 0 }, - { "(U)7777]]]]]]]]]]]]]]]]]]]]]]]]]]]]]c::AA[:alpha:]{,3}f1{NzH@3lTf{}{", 1, 0 }, + { "(U)7777]]]]]]]]]]]]]]]]]]]]]]]]]]]]]c::AA[:alpha:]{,3}f1{" + "NzH@3lTf{}{", + 1, 0 }, { "[C{(\?>})RR(\?=R<]p'N~&.-})6]", 0, 0 }, - { "[^\?[^(\?(lFt]).[^7Q-])kkkkkkkkkkkk]XTFy\"1Deiv!,'xVK", 0, 0 }, - { "[^$[^[:xdigit:](\?{*{245,99}h8v(\?!)]]u)Z[:punct:]})[:alnum:]+|[:blankcntrl:]u{}[:lowerprint:]+bBJ4+k-v{-116}", 0, 0 }, + { "[^\?[^(\?(lFt]).[^7Q-])kkkkkkkkkkkk]XTFy\"1Deiv!,'xVK", 0, + 0 }, + { "[^$[^[:xdigit:](\?{*{245,99}h8v(\?!)]]u)Z[:punct:]})[:alnum:" + "]+|[:blankcntrl:]u{}[:lowerprint:]+bBJ4+k-v{-116}", + 0, 0 }, { "S)f{,180}[:graph:]&{12,244}", 0, 0 }, - { "(([[(.()[^^{80(\?>(\?<=,235})ddddddddd[^ddddddddd(\?<=d.__B{36}````````````````(\?:```(\?>```````,,,,,,,(\?:,,)P$U,[:xdigit:])zzzzzzzzzzzzz]UUUU[uB]n<&[(:ascii:].][:alnum:])\?S]{})d{138,}s9========[:lowerprint:]]OOOOOOOOOOOOOOO|yyyyyyyyyyyyyyy$LZ[:lowerprint:]EEEEEEE[:ascii:][:punct:]VpP^{-48}D){,46}x))2P))a[:lowerprint:]r", 2, 0 }, - { "[^(((\?<!):())PPPPPPPPPPPPPPP(\?=[PPPPPPP(\?{PPPPPPPP$)})77777777777777777]{,-57}::::::::::::(::::::::::::::::)]g{89}__________________[:xdigit:]l[:punct:])N", 1, 0 }, - { ":02-k\?p3I7aEhJ\\265-[:space:]pP[:space:]x0F[:alnum:]aM4[:lowerprint:]sA@@@@@@@@@@@@@@@@@@@@@@@@@@@@", -1, 1 }, + { "(([[(.()[^^{80(\?>(\?<=,235})ddddddddd[^ddddddddd(\?<=d.__B{" + "36}````````````````(\?:```(\?>```````,,,,,,,(\?:,,)P$U,[:" + "xdigit:])zzzzzzzzzzzzz]UUUU[uB]n<&[(:ascii:].][:alnum:])\?S]" + "{})d{138,}s9========[:lowerprint:]]OOOOOOOOOOOOOOO|" + "yyyyyyyyyyyyyyy$LZ[:lowerprint:]EEEEEEE[:ascii:][:punct:]" + "VpP^{-48}D){,46}x))2P))a[:lowerprint:]r", + 2, 0 }, + { "[^(((\?<!):())PPPPPPPPPPPPPPP(\?=[PPPPPPP(\?{PPPPPPPP$)})" + "77777777777777777]{,-57}::::::::::::(::::::::::::::::)]g{89}" + "__________________[:xdigit:]l[:punct:])N", + 1, 0 }, + { ":02-k\?p3I7aEhJ\\265-[:space:]pP[:space:]x0F[:alnum:]aM4[:" + "lowerprint:]sA@@@@@@@@@@@@@@@@@@@@@@@@@@@@", + -1, 1 }, { "a[:upper(\?{word:]})X{-173,}-2F[:lowerprint:]", 0, 0 }, - { "u,w<g*Q002S{,130}{239}[:lower(print:]cr{-165,}#$k<L/&)[:blankcntrl:]aaaaaaaaaaaaaaaaaaaaaa[:ascii:]", 0, 0 }, + { "u,w<g*Q002S{,130}{239}[:lower(print:]cr{-165,}#$k<L/" + "&)[:blankcntrl:]aaaaaaaaaaaaaaaaaaaaaa[:ascii:]", + 0, 0 }, { "(xFA^{-161,93})U[:xdigit:]", 1, 0 }, { "[^(\?=]{})mE`", 0, 0 }, { "[[((\?(\?#:alnum:]])x6CS[:digit:]{-197,}.)N", 0, 0 }, { "[^(\?![])C*[:upp(erword:])-176]", 0, 0 }, - { "[[^[[^[55555555555555555555555555(\?>555(\?<!555)S][]]A[:l(\?>owerp(rint:]])]*", 0, 0 }, + { "[[^[[^[55555555555555555555555555(\?>555(\?<!555)S][]]A[:l(" + "\?>owerp(rint:]])]*", + 0, 0 }, { "Au)khgzAfXIZoZ=g[:digit:]){,186}Upvf=x<]Tbd5Rq\?.", 0, 0 }, - { "b{-176,}B^[:bla(\?(<!nkcntrl:]{-6,133}#B :)<<<<<<<<<<<<<<<<<<<)[:alnum:]$}}}}}}}}}}}}}}}}}}}}}}}[:xdigit:]tw", 0, 0 }, - { "(4IIIII(IIIIIIIIIIIIIIIII{})W{-152,-238}){,-56}^{-142,}", 2, 0 }, - { "[^([[(\?(\?(!)>>>>>>>>>>>>>(>>>>>>>>D)Ix{(1(\?imxmsx:762)c}))A)[[[[[[[[[[[[[[5Rp]DDDDDDDDDDDDDDDDDDDD]Us+\\w[:digit:]{-47}[:xdigit:][:blankcntrl:])ddddddddddddddd[^ddddddddddddd[:digit:]|]]*{-165,-230}{-212}{53,}]\?", 0, 0 }, + { "b{-176,}B^[:bla(\?(<!nkcntrl:]{-6,133}#B " + ":)<<<<<<<<<<<<<<<<<<<)[:alnum:]$}}}}}}}}}}}}}}}}}}}}}}}[:" + "xdigit:]tw", + 0, 0 }, + { "(4IIIII(IIIIIIIIIIIIIIIII{})W{-152,-238}){,-56}^{-142,}", 2, + 0 }, + { "[^([[(\?(\?(!)>>>>>>>>>>>>>(>>>>>>>>D)Ix{(1(\?imxmsx:762)c})" + ")A)[[[[[[[[[[[[[[5Rp]DDDDDDDDDDDDDDDDDDDD]Us+\\w[:digit:]{-" + "47}[:xdigit:][:blankcntrl:])ddddddddddddddd[^ddddddddddddd[:" + "digit:]|]]*{-165,-230}{-212}{53,}]\?", + 0, 0 }, { "[^[^]]|[:(\?:alnum:])}}}}}}}}}}}}}}}}}}}}", 0, 0 }, - { "VVVVVVVVVVVVVVVVVVVVVVVVVVVV[:d(i(\?#git:])){{{{{{[:digit:]ZfQ55555555{}Z", 0, 0 }, - { "[L][:blankcnt(\?((\?=rl:(\?=]){-35,[^}){)eJb>>>>>>>>>>>>>>>>>>>>>>$ [:xdigit:]l0Tv2Tw2@C[:space:]Zc/{*)>]N3j~.dMBBBB", 0, 0 }, + { "VVVVVVVVVVVVVVVVVVVVVVVVVVVV[:d(i(\?#git:])){{{{{{[:digit:]" + "ZfQ55555555{}Z", + 0, 0 }, + { "[L][:blankcnt(\?((\?=rl:(\?=]){-35,[^}){)eJb>>>>>>>>>>>>>>>>" + ">>>>>>$ [:xdigit:]l0Tv2Tw2@C[:space:]Zc/{*)>]N3j~.dMBBBB", + 0, 0 }, { "[[^(\?>(([]))])[:graph:]]{65,}as#Q:lQ", 0, 0 }, - { "[^[fPPUUUUUUUUUUU(\?#UUU[^UUUUUU(\?<=UUUUUUUUUGGGGGGGGGGGGGGGGGGG((\?{\?=GGGGGG.MK))+]+)&UxFW)rwv\?@D.", 0, 0 }, + { "[^[fPPUUUUUUUUUUU(\?#UUU[^UUUUUU(\?<=" + "UUUUUUUUUGGGGGGGGGGGGGGGGGGG((\?{\?=GGGGGG.MK))+]+)&UxFW)" + "rwv\?@D.", + 0, 0 }, { "{-(60,})m", 1, 0 }, { "b[(])^w", 0, 0 }, { "[][^qVs(\?:(p])X)\?'", 0, 0 }, { "()8", 1, 0 }, { "(t[:punc[^t:(\?{][:blankcntrl:])})[^8\?]z*]", 1, 0 }, - { "[:lowerprint:])[:graph:]lppppppppppppppppppppppppppppf", 0, 0 }, + { "[:lowerprint:])[:graph:]lppppppppppppppppppppppppppppf", 0, + 0 }, { "[:alph(a:])[:ascii:]g +z-Bc-U{,%Gk", 0, 0 }, { "u[:graph:(\?=]*)W:::", 0, 0 }, { "([:alnum(:])l)", 1, 0 }, - { "[[[}}}}}}}}(\?<!}}}}}}}+(\?{),,,,,,,,,,,,,,(\?!,,,,,,,,]99999999999&R[:ascii:]ZZZZ-{-10,}{96}Ed*][:graph:])]}){}{}G{-9,}", 0, 0 }, - { "([^[{}]]Z[[^:graph:]{-47}55555555555555555555555555555[:ascii:]s]6,$:3qAew1Y)+)[:punct:]", 1, 0 }, + { "[[[}}}}}}}}(\?<!}}}}}}}+(\?{),,,,,,,,,,,,,,(\?!,,,,,,,,]" + "99999999999&R[:ascii:]ZZZZ-{-10,}{96}Ed*][:graph:])]}){}{}G{" + "-9,}", + 0, 0 }, + { "([^[{}]]Z[[^:graph:]{-47}55555555555555555555555555555[:" + "ascii:]s]6,$:3qAew1Y)+)[:punct:]", + 1, 0 }, { "[[[[[([[[[[[[[[[[[[[[[[[[[[[[[8!1i]')", 0, 0 }, { "([((\?(\?#>)(\?{,)At]%M9FSq5)EB", 1, 0 }, - { "(}````````````````(``{210,})[:(\?#space:]P[:digit:])PP.{-227,}$pK~mm ImR|{,51}[:alnum:]<)[:alpha:]", 2, 0 }, + { "(}````````````````(``{210,})[:(\?#space:]P[:digit:])PP.{-" + "227,}$pK~mm ImR|{,51}[:alnum:]<)[:alpha:]", + 2, 0 }, { "[^(\?<=])[:digit:]", 0, 0 }, - { "[^'''''''{(\?:178,}e{,16}$QQQQQQQQQQQQQQQQQQQQQQQ$])", 0, 0 }, + { "[^'''''''{(\?:178,}e{,16}$QQQQQQQQQQQQQQQQQQQQQQQ$])", 0, + 0 }, { "[^(\?>@K*)(\?#d18]{78,}B)[:digit:]{-193,}=wg{,59}", 0, 0 }, - { "[^.{156,}!(\?<=!!!!!!!!!!!!!!(\?{!(\?(!!!!!!!!!!!!!)})TTTTTTTTTTTTTTTTTTTTTTTTTTTTT[^}}}}}}}}}}}})}}}}}}}}}}}}}]]){}^L#%-{}FC", 0, 0 }, - { "(eeeee{-169,-100}-fa[:upperword:]N)$Nellllllllllllll", 1, 0 }, - { "[[(\?!())\?[(\?!:alnum:]e{,28}M])[:punct:]CCCCCCCCCCCCCCCCCCCC]{-150,}{-167}", 0, 0 }, + { "[^.{156,}!(\?<=!!!!!!!!!!!!!!(\?{!(\?(!!!!!!!!!!!!!)})" + "TTTTTTTTTTTTTTTTTTTTTTTTTTTTT[^}}}}}}}}}}}})}}}}}}}}}}}}}]])" + "{}^L#%-{}FC", + 0, 0 }, + { "(eeeee{-169,-100}-fa[:upperword:]N)$Nellllllllllllll", 1, + 0 }, + { "[[(\?!())\?[(\?!:alnum:]e{,28}M])[:punct:]" + "CCCCCCCCCCCCCCCCCCCC]{-150,}{-167}", + 0, 0 }, { "[[@[@(\?#@[@]P]Z{')]{-186,117}]+)7f-", 0, 0 }, { "\\Q+kD}]AEM)u ", 0, 0 }, - { "([(\?{(\?=:::::::::::::&){,210}]^})P{-31,}8[:space:]C[:alnum:][:a(scii:]z|[:upperword:])[:alnum:][:graph:])zr~Zk", 1, 0 }, + { "([(\?{(\?=:::::::::::::&){,210}]^})P{-31,}8[:space:]C[:" + "alnum:][:a(scii:]z|[:upperword:])[:alnum:][:graph:])zr~Zk", + 1, 0 }, { ".[:space:]e[:g(\?{(\?{raph:]})})@@@@@@@@@@@@@wb|~k", 0, 0 }, - { "()ooooooooo\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"[:graph:]", 1, 0 }, - { "[^64h(\?(@Eyw][:xdi[git:]pP%%%%%u(uuu[:up[perword:]`8Utdh{)}]]))lW[:punct:]W.hhhhhhhhhhhhhhhhhhhhhhhh'm<<}O8`ZXtG.$", 1, 0 }, + { "()ooooooooo\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"[:graph:]", 1, + 0 }, + { "[^64h(\?(@Eyw][:xdi[git:]pP%%%%%u(uuu[:up[perword:]`8Utdh{)}" + "]]))lW[:punct:]W.hhhhhhhhhhhhhhhhhhhhhhhh'm<<}O8`ZXtG.$", + 1, 0 }, { "BPP[:digit:]bbbbbbbbbbb(bb)S+[:alnum:]", 1, 0 }, - { "um.[:ascii((\?#\?!:])*)+KKKKKKKKKKKKKKKKKKKKKKKKKS.=<Bf", 0, 0 }, + { "um.[:ascii((\?#\?!:])*)+KKKKKKKKKKKKKKKKKKKKKKKKKS.=<Bf", 0, + 0 }, { "", -1, 0 }, - { "(()$[:lowerprint:][:s[pace:]2]bbbbbbbbbyoooooooooooooooooo*{39,}$')qV`AcH>,eDl", -1, 0 }, + { "(()$[:lowerprint:][:s[pace:]2]bbbbbbbbbyoooooooooooooooooo*{" + "39,}$')qV`AcH>,eDl", + -1, 0 }, { "(()[^])e{-241,}", -1, 0 }, - { "()[:alpha:]rliiiiiiii[:alnum:]Mb*QW9N.>\?{115,}&u*j", -1, 0 }, + { "()[:alpha:]rliiiiiiii[:alnum:]Mb*QW9N.>\?{115,}&u*j", -1, + 0 }, { "()[]p", -1, 0 }, { "(I[^]pfL)$[:punct:]", -1, 0 }, { "([])>>>>>>>>>>[:alnum:]", -1, 0 }, - { "([])O\\\\\\\\\\\\\\fffffffffffffffffffffff=s6jCZy/b+ir2'*{151,}", -1, 0 }, + { "([])O\\\\\\\\\\\\\\fffffffffffffffffffffff=s6jCZy/" + "b+ir2'*{151,}", + -1, 0 }, { "([])nnnnnnnnnnnnnnnnnnnnnnnnnn[:xdigit:]^N$f", -1, 0 }, { "([]M)[:lowerprint:]a(pg$Z[:punct:])77777777777.", -1, 0 }, { "([]XXXXXXXXXXXXXXXXXXXXXX-===========)", -1, 0 }, - { "([]lkX{-224}[:blankcntrl:]$gPKIZlSC#F@XX I'^}{234}yZm)uuuuuuuuuuuuuuuuuuuuuurS", -1, 0 }, - { "([^0kYkg9])IIIIIIIIIIIIIIIIIIIIII/{(192,-118}l+FoSD6\?A)c[:xdigit:]`````````````````e-{-4,-170}x{4620}Z[:upperword:]", -1, 0 }, - { "([^[^[^()(\?>){}B]XYF+#[:alpha:]{-85((,-55[^}t]n).{,-33}]](bQJ!|O+{175,})RFh)Z+^.{137,}:VpP[:alpha:]-MceqVVkkkk(kkkkkkkkkkkkkkkkkk)\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{-115,-67})``````````````````````````````", -1, 0 }, - { "([^]EzU[:alnum:]+^^^^^^^^^^^^^^^^^^^)[:xdigit:]HHHHHHHH$66666666666666666666666666666666UUUUUUUUUUUUUUUUUUUUL{}iiii{-76}X", -1, 0 }, + { "([]lkX{-224}[:blankcntrl:]$gPKIZlSC#F@XX " + "I'^}{234}yZm)uuuuuuuuuuuuuuuuuuuuuurS", + -1, 0 }, + { "([^0kYkg9])IIIIIIIIIIIIIIIIIIIIII/" + "{(192,-118}l+FoSD6\?A)c[:xdigit:]`````````````````e-{-4,-" + "170}x{4620}Z[:upperword:]", + -1, 0 }, + { "([^[^[^()(\?>){}B]XYF+#[:alpha:]{-85((,-55[^}t]n).{,-33}]](" + "bQJ!|O+{175,})RFh)Z+^.{137,}:VpP[:alpha:]-MceqVVkkkk(" + "kkkkkkkkkkkkkkkkkk)" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{-" + "115,-67})``````````````````````````````", + -1, 0 }, + { "([^]EzU[:alnum:]+^^^^^^^^^^^^^^^^^^^)[:xdigit:]HHHHHHHH$" + "66666666666666666666666666666666UUUUUUUUUUUUUUUUUUUUL{}iiii{" + "-76}X", + -1, 0 }, { "([^]~~~~~~~~~~{240,})]NOp", -1, 0 }, { "(sb)[:digit:]VVVVVVVVx{9569}52,|]", -1, 0 }, { "(x{19762}){}", -1, 0 }, @@ -971,19 +2146,36 @@ regex_validate(void **state) { { "121|", -1, 0 }, { "141[:xdigit:][:lowerprint:]{24}{59,191}[:digit:]/", -1, 0 }, { "G[^],,,,,,,,,,,,,+\"DiX", -1, 0 }, - { "Gm(ho9:\"8{-188,-200}Z[:blankcntrl:]{,171}\?\?\?\?\?\?\?\?\?\?\?[:blankcntrl:]LLLLLLLLLLLLLLLLLLLLLLL{}^[:graph:][:blankc(\?#ntrl:])w", -1, 0 }, - { "N\"\"\"\"\"\"\"-------------------------|[:alnum:]AAAAAAAAAAAAAAAAAAAAf\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", -1, 0 }, + { "Gm(ho9:\"8{-188,-200}Z[:blankcntrl:]{,171}" + "\?\?\?\?\?\?\?\?\?\?\?[:blankcntrl:]LLLLLLLLLLLLLLLLLLLLLLL{" + "}^[:graph:][:blankc(\?#ntrl:])w", + -1, 0 }, + { "N\"\"\"\"\"\"\"-------------------------|[:alnum:]" + "AAAAAAAAAAAAAAAAAAAAf\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", + -1, 0 }, { "U{-30,}^\?\?\?", -1, 0 }, { "W^*04rAY(Ee*>[^o3[]]_)", -1, 0 }, { "X[^]}*C[:alnum:]", -1, 0 }, - { "[${,-3}]+^\?[|x8A|][:space:]'''''['''''JJJJJJJJJJJJJJJJJJJJJJJJJJJJJyl}.Y7G]", -1, 0 }, - { "[()&[&&&]\?\?[\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?pg%k8ug`Wqk4|NR{h[CK5Ez=]jHpQw&`{:]{,91}D", -1, 0 }, - { "[(\?#(\?:)[)([\?>)(\?>(\?:[:alnum:])]G]{85}[^)w]N]gYrUs|", -1, 0 }, + { "[${,-3}]+^\?[|x8A|][:space:]'''''['''''" + "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJyl}.Y7G]", + -1, 0 }, + { "[()&[&&&]\?\?[" + "\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?" + "pg%k8ug`Wqk4|NR{h[CK5Ez=]jHpQw&`{:]{,91}D", + -1, 0 }, + { "[(\?#(\?:)[)([\?>)(\?>(\?:[:alnum:])]G]{85}[^)w]N]gYrUs|", + -1, 0 }, { "[(\?<=)[:digit:]\?]{152,}VR|", -1, 0 }, - { "[****(\?>**********(\?<!*******Q)Vr){[^25,}*:FFFFFFFFFFFFFFFFFFFFFFFF(\?{FFFF(({}D]|", -1, 0 }, - { "[:ascii:]+{124,}:*]\?$-{92}D[:lowerprint:]`````````````````````", -1, 0 }, + { "[****(\?>**********(\?<!*******Q)Vr){[^25,}*:" + "FFFFFFFFFFFFFFFFFFFFFFFF(\?{FFFF(({}D]|", + -1, 0 }, + { "[:ascii:]+{124,}:*]\?$-{92}D[:lowerprint:]``````````````````" + "```", + -1, 0 }, { "[:ascii:]\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?A<", -1, 0 }, - { "[:blankcntrl:]p\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?$\?TTTTTTTTTTTTTTTTT[:ascii:][:upperword:]", -1, 0 }, + { "[:blankcntrl:]p\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?$" + "\?TTTTTTTTTTTTTTTTT[:ascii:][:upperword:]", + -1, 0 }, { "[:punct:]{254}DDDDDDDDDDDDDDD@[:alpha:]Z\?\?-----R", -1, 0 }, { "[:upperword:]J\?\?nqCAdfyW5", -1, 0 }, { "[:upperword:]{-39}|", -1, 0 }, @@ -991,7 +2183,9 @@ regex_validate(void **state) { { "[Z*e ]NdmP\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", -1, 0 }, { "[[:punct:]q]ex{15625}-", -1, 0 }, { "[[[^([^L((\?{b(\?=C\?]-134{,-207}[:ascii:]Hz}XIz}|", -1, 0 }, - { "[[^V(\?:(\?<!(\?>))TTTTTTTTTTTTTTTTTTTTTTT)[:punct:][:digit:]]GGGGGGGGGGGGGGGGGGGGG,]|.{-224}{96}{239,}1", -1, 0 }, + { "[[^V(\?:(\?<!(\?>))TTTTTTTTTTTTTTTTTTTTTTT)[:punct:][:digit:" + "]]GGGGGGGGGGGGGGGGGGGGG,]|.{-224}{96}{239,}1", + -1, 0 }, { "[[^^PP]{,-222}{182}{141}]zFD}-.", -1, 0 }, { "[] Hn&[:xdigit:][:upperword:]f", -1, 0 }, { "[]$.B", -1, 0 }, @@ -1002,7 +2196,9 @@ regex_validate(void **state) { { "[]-#yyK", -1, 0 }, { "[]-(S$5)AxbdTKO[:alnum:]", -1, 0 }, { "[]2883", -1, 0 }, - { "[]2dhd-[:alpha:]sssssssssssssssss55555555555555555555555555555555Z[:punct:]", -1, 0 }, + { "[]2dhd-[:alpha:]" + "sssssssssssssssss55555555555555555555555555555555Z[:punct:]", + -1, 0 }, { "[]4", -1, 0 }, { "[]44444444444444444G", -1, 0 }, { "[]\?", -1, 0 }, @@ -1029,8 +2225,11 @@ regex_validate(void **state) { { "[]{-128,}hc", -1, 0 }, { "[]{-181,}&[:xdigit:].\?}}}}}}}}}}}}}}}}}}}}}}", -1, 0 }, { "[]{}F&}i`7|ZAH", -1, 0 }, - { "[^(\?())u{196,}pP][r^ndddddddddddddddddddddd]{31,246}\?J", -1, 0 }, - { "[^.ii.1-S]lwwwwwwwwwwwwwwwwww[^wwwwwwwwwwwwww[:alnum:]DOpP+<N][^]44{179}{-194,56}", -1, 0 }, + { "[^(\?())u{196,}pP][r^ndddddddddddddddddddddd]{31,246}\?J", + -1, 0 }, + { "[^.ii.1-S]lwwwwwwwwwwwwwwwwww[^wwwwwwwwwwwwww[:alnum:]DOpP+<" + "N][^]44{179}{-194,56}", + -1, 0 }, { "[^2[:alnum:]]\?t\?\?", -1, 0 }, { "[^[((\?{[^^<<<<(\?(\?<!{)})(\?<!]{,184}{-213}|", -1, 0 }, { "[^[^[]\?{89,}PPsvf{[:space:]]]vd{161,}", -1, 0 }, @@ -1064,13 +2263,20 @@ regex_validate(void **state) { { "[^]{}{}{}[:xdigit:]+", -1, 0 }, { "[^]|9{,-108}{}.LVIJJJJJJJJJJJJJJJPP", -1, 0 }, { "[^{,-254}]|", -1, 0 }, - { "[o(\?{(\?<=}[))f++++++++++++++++777777777777777777777777yzPPs]\?\?dRRRRRRRRRRRRRRRRRRRRRRRRRRRR&]>%fffffffffff", -1, 0 }, + { "[o(\?{(\?<=}[))f++++++++++++++++" + "777777777777777777777777yzPPs]" + "\?\?dRRRRRRRRRRRRRRRRRRRRRRRRRRRR&]>%fffffffffff", + -1, 0 }, { "aW|", -1, 0 }, { "cT{}[]C^r2``tm", -1, 0 }, - { "kkkkkkkkkkkkkkkkkkkkkkk[:blankcntrl:]|{}3{26,}{151,}[:punct:]JJJlH$gP%(2WUE%%%%%%%%%%%%%%%%%%%%a){ibf{}\?", -1, 0 }, + { "kkkkkkkkkkkkkkkkkkkkkkk[:blankcntrl:]|{}3{26,}{151,}[:punct:" + "]JJJlH$gP%(2WUE%%%%%%%%%%%%%%%%%%%%a){ibf{}\?", + -1, 0 }, { "lZ\?\?\?\?\?\?\?\?\?\?\?-P2eZt[:punct:]", -1, 0 }, { "vF3qn[^]N.", -1, 0 }, - { "wwwwwwwwwwwwww{-176,}275[^]>.UUUUUUUUUUUUUUUUUUUUeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee2$Yd", -1, 0 }, + { "wwwwwwwwwwwwww{-176,}275[^]>." + "UUUUUUUUUUUUUUUUUUUUeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee2$Yd", + -1, 0 }, { "{-197,223}bf]]]]]]]]]]\?&}/s\?\?~c", -1, 0 }, { "{-37,}EpP|", -1, 0 }, { "{}@]a[][:xdigit:]z{a", -1, 0 }, @@ -1086,20 +2292,21 @@ regex_validate(void **state) { /* * Check if we get the expected response. */ - for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) { + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { regex_t preg; memset(&preg, 0, sizeof(preg)); r = regcomp(&preg, tests[i].expression, REG_EXTENDED); if (((r != 0 && tests[i].expect != -1) || - (r == 0 && tests[i].expect == -1)) && !tests[i].exception) + (r == 0 && tests[i].expect == -1)) && + !tests[i].exception) { if (verbose) { print_error("regcomp(%s) -> %s expected %s\n", tests[i].expression, r != 0 ? "bad" : "good", - tests[i].expect == -1 - ? "bad" : "good"); + tests[i].expect == -1 ? "bad" + : "good"); } } else if (r == 0 && preg.re_nsub != (unsigned int)tests[i].expect && @@ -1117,12 +2324,12 @@ regex_validate(void **state) { regfree(&preg); } } -#endif +#endif /* ifdef HAVE_REGEX_H */ /* * Check if we get the expected response. */ - for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) { + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { r = isc_regex_validate(tests[i].expression); if (r != tests[i].expect) { print_error("# %s -> %d expected %d\n", @@ -1162,4 +2369,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/result_test.c b/lib/isc/tests/result_test.c index 39f972b8..f1242dc6 100644 --- a/lib/isc/tests/result_test.c +++ b/lib/isc/tests/result_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> #include <stdlib.h> -#include <setjmp.h> #include <string.h> #define UNIT_TESTING @@ -68,13 +66,13 @@ tables(void **state) { for (result = 0; result < ISC_R_NRESULTS; result++) { str = isc_result_toid(result); assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); + assert_string_not_equal(str, "(result code text not " + "available)"); str = isc_result_totext(result); assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); + assert_string_not_equal(str, "(result code text not " + "available)"); } str = isc_result_toid(result); @@ -86,18 +84,17 @@ tables(void **state) { assert_string_equal(str, "(result code text not available)"); for (result = ISC_RESULTCLASS_PK11; - result < (ISC_RESULTCLASS_PK11 + PK11_R_NRESULTS); - result++) + result < (ISC_RESULTCLASS_PK11 + PK11_R_NRESULTS); result++) { str = isc_result_toid(result); assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); + assert_string_not_equal(str, "(result code text not " + "available)"); str = isc_result_totext(result); assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); + assert_string_not_equal(str, "(result code text not " + "available)"); } str = isc_result_toid(result); @@ -130,4 +127,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/safe_test.c b/lib/isc/tests/safe_test.c index af1d377c..fbe3190e 100644 --- a/lib/isc/tests/safe_test.c +++ b/lib/isc/tests/safe_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,16 +11,14 @@ /* ! \file */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - -#include <string.h> #include <stdlib.h> +#include <string.h> #define UNIT_TESTING #include <cmocka.h> @@ -35,12 +33,12 @@ isc_safe_memequal_test(void **state) { assert_true(isc_safe_memequal("test", "test", 4)); assert_true(!isc_safe_memequal("test", "tesc", 4)); - assert_true(isc_safe_memequal("\x00\x00\x00\x00", - "\x00\x00\x00\x00", 4)); - assert_true(!isc_safe_memequal("\x00\x00\x00\x00", - "\x00\x00\x00\x01", 4)); - assert_true(!isc_safe_memequal("\x00\x00\x00\x02", - "\x00\x00\x00\x00", 4)); + assert_true( + isc_safe_memequal("\x00\x00\x00\x00", "\x00\x00\x00\x00", 4)); + assert_true( + !isc_safe_memequal("\x00\x00\x00\x00", "\x00\x00\x00\x01", 4)); + assert_true( + !isc_safe_memequal("\x00\x00\x00\x02", "\x00\x00\x00\x00", 4)); } /* test isc_safe_memwipe() */ @@ -50,7 +48,7 @@ isc_safe_memwipe_test(void **state) { /* These should pass. */ isc_safe_memwipe(NULL, 0); - isc_safe_memwipe((void *) -1, 0); + isc_safe_memwipe((void *)-1, 0); /* * isc_safe_memwipe(ptr, size) should function same as @@ -104,4 +102,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/siphash_test.c b/lib/isc/tests/siphash_test.c new file mode 100644 index 00000000..1657fa5b --- /dev/null +++ b/lib/isc/tests/siphash_test.c @@ -0,0 +1,181 @@ +/* + * 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. + */ + +#if HAVE_CMOCKA + +#include <sched.h> +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> + +#define UNIT_TESTING +#include <cmocka.h> + +#include <isc/siphash.h> + +#include "../siphash.c" + +const uint8_t vectors_sip64[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74 }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85 }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18 }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93 }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4 }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75 }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14 }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7 }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69 }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0 }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93 }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8 }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8 }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17 }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6 }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32 }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71 }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7 }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12 }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15 }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31 }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02 }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18 }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4 }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9 }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9 }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0 }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6 }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7 }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1 }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81 }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24 }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7 }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60 }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66 }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5 }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95 } +}; + +const uint8_t vectors_hsip32[64][4] = { + { 0xa9, 0x35, 0x9f, 0x5b }, { 0x27, 0x47, 0x5a, 0xb8 }, + { 0xfa, 0x62, 0xa6, 0x03 }, { 0x8a, 0xfe, 0xe7, 0x04 }, + { 0x2a, 0x6e, 0x46, 0x89 }, { 0xc5, 0xfa, 0xb6, 0x69 }, + { 0x58, 0x63, 0xfc, 0x23 }, { 0x8b, 0xcf, 0x63, 0xc5 }, + { 0xd0, 0xb8, 0x84, 0x8f }, { 0xf8, 0x06, 0xe7, 0x79 }, + { 0x94, 0xb0, 0x79, 0x34 }, { 0x08, 0x08, 0x30, 0x50 }, + { 0x57, 0xf0, 0x87, 0x2f }, { 0x77, 0xe6, 0x63, 0xff }, + { 0xd6, 0xff, 0xf8, 0x7c }, { 0x74, 0xfe, 0x2b, 0x97 }, + { 0xd9, 0xb5, 0xac, 0x84 }, { 0xc4, 0x74, 0x64, 0x5b }, + { 0x46, 0x5b, 0x8d, 0x9b }, { 0x7b, 0xef, 0xe3, 0x87 }, + { 0xe3, 0x4d, 0x10, 0x45 }, { 0x61, 0x3f, 0x62, 0xb3 }, + { 0x70, 0xf3, 0x67, 0xfe }, { 0xe6, 0xad, 0xb8, 0xbd }, + { 0x27, 0x40, 0x0c, 0x63 }, { 0x26, 0x78, 0x78, 0x75 }, + { 0x4f, 0x56, 0x7b, 0x5f }, { 0x3a, 0xb0, 0xe6, 0x69 }, + { 0xb0, 0x64, 0x40, 0x00 }, { 0xff, 0x67, 0x0f, 0xb4 }, + { 0x50, 0x9e, 0x33, 0x8b }, { 0x5d, 0x58, 0x9f, 0x1a }, + { 0xfe, 0xe7, 0x21, 0x12 }, { 0x33, 0x75, 0x32, 0x59 }, + { 0x6a, 0x43, 0x4f, 0x8c }, { 0xfe, 0x28, 0xb7, 0x29 }, + { 0xe7, 0x5c, 0xc6, 0xec }, { 0x69, 0x7e, 0x8d, 0x54 }, + { 0x63, 0x68, 0x8b, 0x0f }, { 0x65, 0x0b, 0x62, 0xb4 }, + { 0xb6, 0xbc, 0x18, 0x40 }, { 0x5d, 0x07, 0x45, 0x05 }, + { 0x24, 0x42, 0xfd, 0x2e }, { 0x7b, 0xb7, 0x86, 0x3a }, + { 0x77, 0x05, 0xd5, 0x48 }, { 0xd7, 0x52, 0x08, 0xb1 }, + { 0xb6, 0xd4, 0x99, 0xc8 }, { 0x08, 0x92, 0x20, 0x2e }, + { 0x69, 0xe1, 0x2c, 0xe3 }, { 0x8d, 0xb5, 0x80, 0xe5 }, + { 0x36, 0x97, 0x64, 0xc6 }, { 0x01, 0x6e, 0x02, 0x04 }, + { 0x3b, 0x85, 0xf3, 0xd4 }, { 0xfe, 0xdb, 0x66, 0xbe }, + { 0x1e, 0x69, 0x2a, 0x3a }, { 0xc6, 0x89, 0x84, 0xc0 }, + { 0xa5, 0xc5, 0xb9, 0x40 }, { 0x9b, 0xe9, 0xe8, 0x8c }, + { 0x7d, 0xbc, 0x81, 0x40 }, { 0x7c, 0x07, 0x8e, 0xc5 }, + { 0xd4, 0xe7, 0x6c, 0x73 }, { 0x42, 0x8f, 0xcb, 0xb9 }, + { 0xbd, 0x83, 0x99, 0x7a }, { 0x59, 0xea, 0x4a, 0x74 } +}; + +static void +isc_siphash24_test(void **state) { + UNUSED(state); + + uint8_t in[64], out[8], key[16]; + for (size_t i = 0; i < ARRAY_SIZE(key); i++) { + key[i] = i; + } + + for (size_t i = 0; i < ARRAY_SIZE(in); i++) { + in[i] = i; + isc_siphash24(key, in, i, out); + assert_memory_equal(out, vectors_sip64[i], 8); + } +} + +static void +isc_halfsiphash24_test(void **state) { + UNUSED(state); + + uint8_t in[64], out[4], key[16]; + for (size_t i = 0; i < ARRAY_SIZE(key); i++) { + key[i] = i; + } + + for (size_t i = 0; i < ARRAY_SIZE(in); i++) { + in[i] = i; + isc_halfsiphash24(key, in, i, out); + assert_memory_equal(out, vectors_hsip32[i], 4); + } +} + +int +main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(isc_siphash24_test), + cmocka_unit_test(isc_halfsiphash24_test), + }; + + return (cmocka_run_group_tests(tests, NULL, NULL)); +} + +#else /* HAVE_CMOCKA */ + +#include <stdio.h> + +int +main(void) { + printf("1..0 # Skipped: cmocka not available\n"); + return (0); +} + +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/sockaddr_test.c b/lib/isc/tests/sockaddr_test.c index c1b2beb4..59ed4c63 100644 --- a/lib/isc/tests/sockaddr_test.c +++ b/lib/isc/tests/sockaddr_test.c @@ -3,21 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> +#include <sched.h> /* IWYU pragma: keep */ #include <setjmp.h> - +#include <stdarg.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -26,8 +24,8 @@ #include <cmocka.h> #include <isc/netaddr.h> -#include <isc/sockaddr.h> #include <isc/print.h> +#include <isc/sockaddr.h> #include <isc/util.h> #include "isctest.h" @@ -92,14 +90,10 @@ sockaddr_isnetzero(void **state) { const char *string; bool expect; } data4[] = { - { "0.0.0.0", true }, - { "0.0.0.1", true }, - { "0.0.1.0", true }, - { "0.1.0.0", true }, - { "1.0.0.0", false }, - { "0.0.0.127", true }, - { "0.0.0.255", true }, - { "127.0.0.1", false }, + { "0.0.0.0", true }, { "0.0.0.1", true }, + { "0.0.1.0", true }, { "0.1.0.0", true }, + { "1.0.0.0", false }, { "0.0.0.127", true }, + { "0.0.0.255", true }, { "127.0.0.1", false }, { "255.255.255.255", false }, }; /* @@ -119,14 +113,14 @@ sockaddr_isnetzero(void **state) { UNUSED(state); - for (i = 0; i < sizeof(data4)/sizeof(data4[0]); i++) { + for (i = 0; i < sizeof(data4) / sizeof(data4[0]); i++) { in.s_addr = inet_addr(data4[i].string); isc_sockaddr_fromin(&addr, &in, 1); r = isc_sockaddr_isnetzero(&addr); assert_int_equal(r, data4[i].expect); } - for (i = 0; i < sizeof(data6)/sizeof(data6[0]); i++) { + for (i = 0; i < sizeof(data6) / sizeof(data6[0]); i++) { ret = inet_pton(AF_INET6, data6[i].string, &in6); assert_int_equal(ret, 1); isc_sockaddr_fromin6(&addr, &in6, 1); @@ -170,8 +164,8 @@ sockaddr_eqaddrprefix(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(sockaddr_hash, - _setup, _teardown), + cmocka_unit_test_setup_teardown(sockaddr_hash, _setup, + _teardown), cmocka_unit_test(sockaddr_isnetzero), cmocka_unit_test(sockaddr_eqaddrprefix), }; @@ -189,4 +183,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/socket_test.c b/lib/isc/tests/socket_test.c index 0df13589..f894393c 100644 --- a/lib/isc/tests/socket_test.c +++ b/lib/isc/tests/socket_test.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,25 +11,24 @@ /*! \file */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> +#include <sched.h> /* IWYU pragma: keep */ #include <setjmp.h> - +#include <stdarg.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> -#include <unistd.h> #include <time.h> +#include <unistd.h> #define UNIT_TESTING #include <cmocka.h> +#include <isc/atomic.h> #include <isc/platform.h> +#include <isc/print.h> #include <isc/socket.h> #include <isc/task.h> -#include <isc/print.h> #include "../unix/socket_p.h" #include "isctest.h" @@ -37,6 +36,8 @@ static bool recv_dscp; static unsigned int recv_dscp_value; static bool recv_trunc; +isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; +isc_task_t *test_task = NULL; /* * Helper functions @@ -58,20 +59,33 @@ static int _teardown(void **state) { UNUSED(state); + if (s1 != NULL) { + isc_socket_detach(&s1); + } + if (s2 != NULL) { + isc_socket_detach(&s2); + } + if (s3 != NULL) { + isc_socket_detach(&s3); + } + if (test_task != NULL) { + isc_task_detach(&test_task); + } + isc_test_end(); return (0); } typedef struct { - bool done; + atomic_bool done; isc_result_t result; isc_socket_t *socket; } completion_t; static void completion_init(completion_t *completion) { - completion->done = false; + atomic_init(&completion->done, false); completion->socket = NULL; } @@ -83,7 +97,7 @@ accept_done(isc_task_t *task, isc_event_t *event) { UNUSED(task); completion->result = nevent->result; - completion->done = true; + atomic_store(&completion->done, true); if (completion->result == ISC_R_SUCCESS) { completion->socket = nevent->newsocket; } @@ -101,34 +115,34 @@ event_done(isc_task_t *task, isc_event_t *event) { switch (event->ev_type) { case ISC_SOCKEVENT_RECVDONE: case ISC_SOCKEVENT_SENDDONE: - sev = (isc_socketevent_t *) event; + sev = (isc_socketevent_t *)event; completion->result = sev->result; if ((sev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) { recv_dscp = true; - recv_dscp_value = sev->dscp;; + recv_dscp_value = sev->dscp; } else { recv_dscp = false; } recv_trunc = ((sev->attributes & ISC_SOCKEVENTATTR_TRUNC) != 0); break; case ISC_SOCKEVENT_CONNECT: - connev = (isc_socket_connev_t *) event; + connev = (isc_socket_connev_t *)event; completion->result = connev->result; break; default: assert_false(true); } - completion->done = true; + atomic_store(&completion->done, true); isc_event_free(&event); } static isc_result_t waitfor(completion_t *completion) { int i = 0; - while (!completion->done && i++ < 5000) { + while (!atomic_load(&completion->done) && i++ < 5000) { isc_test_nap(1000); } - if (completion->done) { + if (atomic_load(&completion->done)) { return (ISC_R_SUCCESS); } return (ISC_R_FAILURE); @@ -136,17 +150,18 @@ waitfor(completion_t *completion) { static void waitbody(void) { - isc_test_nap(1000); + isc_test_nap(1000); } static isc_result_t waitfor2(completion_t *c1, completion_t *c2) { int i = 0; - while (!(c1->done && c2->done) && i++ < 5000) { + while (!(atomic_load(&c1->done) && atomic_load(&c2->done)) && + i++ < 5000) { waitbody(); } - if (c1->done && c2->done) { + if (atomic_load(&c1->done) && atomic_load(&c2->done)) { return (ISC_R_SUCCESS); } return (ISC_R_FAILURE); @@ -158,12 +173,10 @@ waitfor2(completion_t *c1, completion_t *c2) { /* Test UDP sendto/recv (IPv4) */ static void -udp_sendto_test(void **state) { +udp_sendto_test(void **state) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; - isc_socket_t *s1 = NULL, *s2 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; @@ -190,36 +203,30 @@ udp_sendto_test(void **state) { assert_int_equal(result, ISC_R_SUCCESS); assert_true(isc_sockaddr_getport(&addr2) != 0); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - result = isc_socket_sendto(s1, &r, task, event_done, &completion, + result = isc_socket_sendto(s1, &r, test_task, event_done, &completion, &addr2, NULL); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - } /* Test UDP sendto/recv with duplicated socket */ @@ -228,8 +235,6 @@ udp_dup_test(void **state) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; - isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; @@ -259,59 +264,52 @@ udp_dup_test(void **state) { result = isc_socket_dup(s2, &s3); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - result = isc_socket_sendto(s1, &r, task, event_done, &completion, + result = isc_socket_sendto(s1, &r, test_task, event_done, &completion, &addr2, NULL); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); snprintf(sendbuf, sizeof(sendbuf), "World"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - result = isc_socket_sendto(s1, &r, task, event_done, &completion, + result = isc_socket_sendto(s1, &r, test_task, event_done, &completion, &addr2, NULL); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s3, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "World"); - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - isc_socket_detach(&s3); - } /* Test UDP sendto/recv (IPv4) */ @@ -320,8 +318,6 @@ udp_dscp_v4_test(void **state) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; - isc_socket_t *s1 = NULL, *s2 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; @@ -329,7 +325,6 @@ udp_dscp_v4_test(void **state) { UNUSED(state); - in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 0); isc_sockaddr_fromin(&addr2, &in, 0); @@ -350,24 +345,24 @@ udp_dscp_v4_test(void **state) { assert_int_equal(result, ISC_R_SUCCESS); assert_true(isc_sockaddr_getport(&addr2) != 0); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, - event_done, &completion); + socketevent = isc_socket_socketevent( + test_mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); assert_non_null(socketevent); if ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0) { socketevent->dscp = 056; /* EF */ socketevent->attributes |= ISC_SOCKEVENTATTR_DSCP; } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV4) != 0) { - isc_socket_dscp(s1, 056); /* EF */ + isc_socket_dscp(s1, 056); /* EF */ socketevent->dscp = 0; socketevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; } @@ -375,19 +370,20 @@ udp_dscp_v4_test(void **state) { recv_dscp = false; recv_dscp_value = 0; - result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); + result = isc_socket_sendto2(s1, &r, test_task, &addr2, NULL, + socketevent, 0); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); @@ -397,11 +393,6 @@ udp_dscp_v4_test(void **state) { } else { assert_false(recv_dscp); } - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - } /* Test UDP sendto/recv (IPv6) */ @@ -410,8 +401,6 @@ udp_dscp_v6_test(void **state) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in6_addr in6; - isc_socket_t *s1 = NULL, *s2 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; @@ -420,7 +409,6 @@ udp_dscp_v6_test(void **state) { UNUSED(state); - n = inet_pton(AF_INET6, "::1", &in6.s6_addr); assert_true(n == 1); isc_sockaddr_fromin6(&addr1, &in6, 0); @@ -444,42 +432,43 @@ udp_dscp_v6_test(void **state) { assert_int_equal(result, ISC_R_SUCCESS); assert_true(isc_sockaddr_getport(&addr2) != 0); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, - event_done, &completion); + socketevent = isc_socket_socketevent( + test_mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); assert_non_null(socketevent); if ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0) { socketevent->dscp = 056; /* EF */ socketevent->attributes = ISC_SOCKEVENTATTR_DSCP; } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV6) != 0) { - isc_socket_dscp(s1, 056); /* EF */ + isc_socket_dscp(s1, 056); /* EF */ } recv_dscp = false; recv_dscp_value = 0; - result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); + result = isc_socket_sendto2(s1, &r, test_task, &addr2, NULL, + socketevent, 0); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) { @@ -488,12 +477,6 @@ udp_dscp_v6_test(void **state) { } else { assert_false(recv_dscp); } - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - } /* Test TCP sendto/recv (IPv4) */ @@ -502,15 +485,12 @@ tcp_dscp_v4_test(void **state) { isc_result_t result; isc_sockaddr_t addr1; struct in_addr in; - isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion, completion2; isc_region_t r; UNUSED(state); - in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 0); @@ -529,47 +509,48 @@ tcp_dscp_v4_test(void **state) { result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s2); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); completion_init(&completion2); - result = isc_socket_accept(s1, task, accept_done, &completion2); + result = isc_socket_accept(s1, test_task, accept_done, &completion2); assert_int_equal(result, ISC_R_SUCCESS); completion_init(&completion); - result = isc_socket_connect(s2, &addr1, task, event_done, &completion); + result = isc_socket_connect(s2, &addr1, test_task, event_done, + &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor2(&completion, &completion2); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - assert_true(completion2.done); + assert_true(atomic_load(&completion2.done)); assert_int_equal(completion2.result, ISC_R_SUCCESS); s3 = completion2.socket; - isc_socket_dscp(s2, 056); /* EF */ + isc_socket_dscp(s2, 056); /* EF */ snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; recv_dscp = false; recv_dscp_value = 0; completion_init(&completion); - result = isc_socket_sendto(s2, &r, task, event_done, &completion, + result = isc_socket_sendto(s2, &r, test_task, event_done, &completion, NULL, NULL); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s3, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); @@ -580,13 +561,6 @@ tcp_dscp_v4_test(void **state) { } else { assert_false(recv_dscp); } - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - isc_socket_detach(&s3); - } /* Test TCP sendto/recv (IPv6) */ @@ -595,8 +569,6 @@ tcp_dscp_v6_test(void **state) { isc_result_t result; isc_sockaddr_t addr1; struct in6_addr in6; - isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; - isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion, completion2; isc_region_t r; @@ -604,7 +576,6 @@ tcp_dscp_v6_test(void **state) { UNUSED(state); - n = inet_pton(AF_INET6, "::1", &in6.s6_addr); assert_true(n == 1); isc_sockaddr_fromin6(&addr1, &in6, 0); @@ -626,47 +597,48 @@ tcp_dscp_v6_test(void **state) { &s2); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); completion_init(&completion2); - result = isc_socket_accept(s1, task, accept_done, &completion2); + result = isc_socket_accept(s1, test_task, accept_done, &completion2); assert_int_equal(result, ISC_R_SUCCESS); completion_init(&completion); - result = isc_socket_connect(s2, &addr1, task, event_done, &completion); + result = isc_socket_connect(s2, &addr1, test_task, event_done, + &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor2(&completion, &completion2); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - assert_true(completion2.done); + assert_true(atomic_load(&completion2.done)); assert_int_equal(completion2.result, ISC_R_SUCCESS); s3 = completion2.socket; - isc_socket_dscp(s2, 056); /* EF */ + isc_socket_dscp(s2, 056); /* EF */ snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; recv_dscp = false; recv_dscp_value = 0; completion_init(&completion); - result = isc_socket_sendto(s2, &r, task, event_done, &completion, + result = isc_socket_sendto(s2, &r, test_task, event_done, &completion, NULL, NULL); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); - result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s3, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); @@ -681,13 +653,6 @@ tcp_dscp_v6_test(void **state) { } else { assert_false(recv_dscp); } - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - isc_socket_detach(&s3); - } /* probe dscp capabilities */ @@ -701,26 +666,26 @@ net_probedscp_test(void **state) { assert_true((n & ~ISC_NET_DSCPALL) == 0); /* ISC_NET_DSCPSETV4 MUST be set if any is set. */ - if (n & (ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4)) { + if (n & (ISC_NET_DSCPPKTV4 | ISC_NET_DSCPRECVV4)) { assert_true((n & ISC_NET_DSCPSETV4) != 0); } /* ISC_NET_DSCPSETV6 MUST be set if any is set. */ - if (n & (ISC_NET_DSCPPKTV6|ISC_NET_DSCPRECVV6)) { + if (n & (ISC_NET_DSCPPKTV6 | ISC_NET_DSCPRECVV6)) { assert_true((n & ISC_NET_DSCPSETV6) != 0); } #if 0 - fprintf(stdout, "IPv4:%s%s%s\n", + fprintf(stdout,"IPv4:%s%s%s\n", (n & ISC_NET_DSCPSETV4) ? " set" : "none", (n & ISC_NET_DSCPPKTV4) ? " packet" : "", (n & ISC_NET_DSCPRECVV4) ? " receive" : ""); - fprintf(stdout, "IPv6:%s%s%s\n", + fprintf(stdout,"IPv6:%s%s%s\n", (n & ISC_NET_DSCPSETV6) ? " set" : "none", (n & ISC_NET_DSCPPKTV6) ? " packet" : "", (n & ISC_NET_DSCPRECVV6) ? " receive" : ""); -#endif +#endif /* if 0 */ } /* Test UDP truncation detection */ @@ -729,9 +694,7 @@ udp_trunc_test(void **state) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; - isc_socket_t *s1 = NULL, *s2 = NULL; - isc_task_t *task = NULL; - char sendbuf[BUFSIZ*2], recvbuf[BUFSIZ]; + char sendbuf[BUFSIZ * 2], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; isc_socketevent_t *socketevent; @@ -757,7 +720,7 @@ udp_trunc_test(void **state) { assert_int_equal(result, ISC_R_SUCCESS); assert_true(isc_sockaddr_getport(&addr2) != 0); - result = isc_task_create(taskmgr, 0, &task); + result = isc_task_create(taskmgr, 0, &test_task); assert_int_equal(result, ISC_R_SUCCESS); /* @@ -765,29 +728,30 @@ udp_trunc_test(void **state) { */ memset(sendbuf, 0xff, sizeof(sendbuf)); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); - socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, - event_done, &completion); + socketevent = isc_socket_socketevent( + test_mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); assert_non_null(socketevent); - result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); + result = isc_socket_sendto2(s1, &r, test_task, &addr2, NULL, + socketevent, 0); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); recv_trunc = false; - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); assert_false(recv_trunc); @@ -797,38 +761,33 @@ udp_trunc_test(void **state) { */ memset(sendbuf, 0xff, sizeof(sendbuf)); snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *) sendbuf; + r.base = (void *)sendbuf; r.length = sizeof(sendbuf); completion_init(&completion); - socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, - event_done, &completion); + socketevent = isc_socket_socketevent( + test_mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); assert_non_null(socketevent); - result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); + result = isc_socket_sendto2(s1, &r, test_task, &addr2, NULL, + socketevent, 0); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); - r.base = (void *) recvbuf; + r.base = (void *)recvbuf; r.length = BUFSIZ; completion_init(&completion); recv_trunc = false; - result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); + result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); assert_int_equal(result, ISC_R_SUCCESS); waitfor(&completion); - assert_true(completion.done); + assert_true(atomic_load(&completion.done)); assert_int_equal(completion.result, ISC_R_SUCCESS); assert_string_equal(recvbuf, "Hello"); assert_true(recv_trunc); - - isc_task_detach(&task); - - isc_socket_detach(&s1); - isc_socket_detach(&s2); - } /* @@ -837,22 +796,22 @@ udp_trunc_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(udp_sendto_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(udp_dup_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(tcp_dscp_v4_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(tcp_dscp_v6_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(udp_dscp_v4_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(udp_dscp_v6_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(net_probedscp_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(udp_trunc_test, - _setup, _teardown), + cmocka_unit_test_setup_teardown(udp_sendto_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(udp_dup_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(tcp_dscp_v4_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(tcp_dscp_v6_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(udp_dscp_v4_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(udp_dscp_v6_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(net_probedscp_test, _setup, + _teardown), + cmocka_unit_test_setup_teardown(udp_trunc_test, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -866,7 +825,6 @@ int main(void) { printf("1..0 # Skipped: cmocka not available\n"); return (0); - } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/symtab_test.c b/lib/isc/tests/symtab_test.c index 35039522..85b0daba 100644 --- a/lib/isc/tests/symtab_test.c +++ b/lib/isc/tests/symtab_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -24,8 +22,8 @@ #define UNIT_TESTING #include <cmocka.h> -#include <isc/symtab.h> #include <isc/print.h> +#include <isc/symtab.h> #include <isc/util.h> #include "isctest.h" @@ -56,8 +54,8 @@ undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) { UNUSED(arg); assert_int_equal(type, 1); - isc_mem_free(mctx, key); - isc_mem_free(mctx, value.as_pointer); + isc_mem_free(test_mctx, key); + isc_mem_free(test_mctx, value.as_pointer); } /* test symbol table growth */ @@ -71,7 +69,7 @@ symtab_grow(void **state) { UNUSED(state); - result = isc_symtab_create(mctx, 3, undefine, NULL, false, &st); + result = isc_symtab_create(test_mctx, 3, undefine, NULL, false, &st); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(st); @@ -85,14 +83,15 @@ symtab_grow(void **state) { char str[16], *key; snprintf(str, sizeof(str), "%04x", i); - key = isc_mem_strdup(mctx, str); + key = isc_mem_strdup(test_mctx, str); assert_non_null(key); - value.as_pointer = isc_mem_strdup(mctx, str); + value.as_pointer = isc_mem_strdup(test_mctx, str); assert_non_null(value.as_pointer); result = isc_symtab_define(st, key, 1, value, policy); assert_int_equal(result, ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { undefine(key, 1, value, NULL); + } } /* @@ -102,9 +101,9 @@ symtab_grow(void **state) { char str[16], *key; snprintf(str, sizeof(str), "%04x", i); - key = isc_mem_strdup(mctx, str); + key = isc_mem_strdup(test_mctx, str); assert_non_null(key); - value.as_pointer = isc_mem_strdup(mctx, str); + value.as_pointer = isc_mem_strdup(test_mctx, str); assert_non_null(value.as_pointer); result = isc_symtab_define(st, key, 1, value, policy); assert_int_equal(result, ISC_R_EXISTS); @@ -151,8 +150,7 @@ symtab_grow(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(symtab_grow, - _setup, _teardown), + cmocka_unit_test_setup_teardown(symtab_grow, _setup, _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -168,4 +166,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/task_test.c b/lib/isc/tests/task_test.c index 18c1717b..9cbe1c99 100644 --- a/lib/isc/tests/task_test.c +++ b/lib/isc/tests/task_test.c @@ -3,29 +3,28 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA -#include <stdarg.h> -#include <stddef.h> +#include <inttypes.h> +#include <sched.h> /* IWYU pragma: keep */ #include <setjmp.h> - +#include <stdarg.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> -#include <unistd.h> -#include <inttypes.h> #include <string.h> +#include <unistd.h> #define UNIT_TESTING -#include <cmocka.h> +#include <isc/atomic.h> +#include <isc/cmocka.h> #include <isc/commandline.h> #include <isc/condition.h> #include <isc/mem.h> @@ -36,9 +35,8 @@ #include <isc/timer.h> #include <isc/util.h> -#include "isctest.h" - #include "../task_p.h" +#include "isctest.h" /* Set to true (or use -v option) for verbose output */ static bool verbose = false; @@ -46,9 +44,9 @@ static bool verbose = false; static isc_mutex_t lock; static isc_condition_t cv; -int counter = 0; +atomic_int_fast32_t counter; static int active[10]; -static bool done = false; +static atomic_bool done, done2; static int _setup(void **state) { @@ -112,26 +110,24 @@ _teardown(void **state) { static void set(isc_task_t *task, isc_event_t *event) { - int *value = (int *) event->ev_arg; + atomic_int_fast32_t *value = (atomic_int_fast32_t *)event->ev_arg; UNUSED(task); isc_event_free(&event); - LOCK(&lock); - *value = counter++; - UNLOCK(&lock); + atomic_store(value, atomic_fetch_add(&counter, 1)); } static void set_and_drop(isc_task_t *task, isc_event_t *event) { - int *value = (int *) event->ev_arg; + atomic_int_fast32_t *value = (atomic_int_fast32_t *)event->ev_arg; UNUSED(task); isc_event_free(&event); LOCK(&lock); - *value = (int) isc_taskmgr_mode(taskmgr); - counter++; + atomic_store(value, (int)isc_taskmgr_mode(taskmgr)); + atomic_fetch_add(&counter, 1); UNLOCK(&lock); } @@ -156,37 +152,39 @@ all_events(void **state) { isc_result_t result; isc_task_t *task = NULL; isc_event_t *event = NULL; - int a = 0, b = 0; + atomic_int_fast32_t a, b; int i = 0; UNUSED(state); - counter = 1; + atomic_init(&counter, 1); + atomic_init(&a, 0); + atomic_init(&b, 0); result = isc_task_create(taskmgr, 0, &task); assert_int_equal(result, ISC_R_SUCCESS); /* First event */ - event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST, - set, &a, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST, set, &a, + sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(a, 0); + assert_int_equal(atomic_load(&a), 0); isc_task_send(task, &event); - event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST, - set, &b, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST, set, &b, + sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(b, 0); + assert_int_equal(atomic_load(&b), 0); isc_task_send(task, &event); - while ((a == 0 || b == 0) && i++ < 5000) { + while ((atomic_load(&a) == 0 || atomic_load(&b) == 0) && i++ < 5000) { isc_test_nap(1000); } - assert_int_not_equal(a, 0); - assert_int_not_equal(b, 0); + assert_int_not_equal(atomic_load(&a), 0); + assert_int_not_equal(atomic_load(&b), 0); isc_task_destroy(&task); assert_null(task); @@ -198,12 +196,17 @@ privileged_events(void **state) { isc_result_t result; isc_task_t *task1 = NULL, *task2 = NULL; isc_event_t *event = NULL; - int a = 0, b = 0, c = 0, d = 0, e = 0; + atomic_int_fast32_t a, b, c, d, e; int i = 0; UNUSED(state); - counter = 1; + atomic_init(&counter, 1); + atomic_init(&a, 0); + atomic_init(&b, 0); + atomic_init(&c, 0); + atomic_init(&d, 0); + atomic_init(&e, 0); /* * Pause the task manager so we can fill up the work queue @@ -224,43 +227,43 @@ privileged_events(void **state) { assert_false(isc_task_privilege(task2)); /* First event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set, &a, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set, + &a, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(a, 0); + assert_int_equal(atomic_load(&a), 0); isc_task_send(task1, &event); /* Second event: not privileged */ - event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, - set, &b, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, set, + &b, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(b, 0); + assert_int_equal(atomic_load(&b), 0); isc_task_send(task2, &event); /* Third event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set, &c, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set, + &c, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(c, 0); + assert_int_equal(atomic_load(&c), 0); isc_task_send(task1, &event); /* Fourth event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set, &d, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set, + &d, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(d, 0); + assert_int_equal(atomic_load(&d), 0); isc_task_send(task1, &event); /* Fifth event: not privileged */ - event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, - set, &e, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, set, + &e, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(e, 0); + assert_int_equal(atomic_load(&e), 0); isc_task_send(task2, &event); assert_int_equal(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); @@ -270,7 +273,11 @@ privileged_events(void **state) { isc__taskmgr_resume(taskmgr); /* We're waiting for *all* variables to be set */ - while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) { + while ((atomic_load(&a) == 0 || atomic_load(&b) == 0 || + atomic_load(&c) == 0 || atomic_load(&d) == 0 || + atomic_load(&e) == 0) && + i++ < 5000) + { isc_test_nap(1000); } @@ -279,15 +286,15 @@ privileged_events(void **state) { * we do know the privileged tasks that set a, c, and d * would have fired first. */ - assert_true(a <= 3); - assert_true(c <= 3); - assert_true(d <= 3); + assert_true(atomic_load(&a) <= 3); + assert_true(atomic_load(&c) <= 3); + assert_true(atomic_load(&d) <= 3); /* ...and the non-privileged tasks that set b and e, last */ - assert_true(b >= 4); - assert_true(e >= 4); + assert_true(atomic_load(&b) >= 4); + assert_true(atomic_load(&e) >= 4); - assert_int_equal(counter, 6); + assert_int_equal(atomic_load(&counter), 6); isc_task_setprivilege(task1, false); assert_false(isc_task_privilege(task1)); @@ -309,12 +316,17 @@ privilege_drop(void **state) { isc_result_t result; isc_task_t *task1 = NULL, *task2 = NULL; isc_event_t *event = NULL; - int a = -1, b = -1, c = -1, d = -1, e = -1; /* non valid states */ + atomic_int_fast32_t a, b, c, d, e; /* non valid states */ int i = 0; UNUSED(state); - counter = 1; + atomic_init(&counter, 1); + atomic_init(&a, -1); + atomic_init(&b, -1); + atomic_init(&c, -1); + atomic_init(&d, -1); + atomic_init(&e, -1); /* * Pause the task manager so we can fill up the work queue @@ -335,43 +347,43 @@ privilege_drop(void **state) { assert_false(isc_task_privilege(task2)); /* First event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set_and_drop, &a, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, + set_and_drop, &a, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(a, -1); + assert_int_equal(atomic_load(&a), -1); isc_task_send(task1, &event); /* Second event: not privileged */ - event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, - set_and_drop, &b, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, + set_and_drop, &b, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(b, -1); + assert_int_equal(atomic_load(&b), -1); isc_task_send(task2, &event); /* Third event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set_and_drop, &c, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, + set_and_drop, &c, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(c, -1); + assert_int_equal(atomic_load(&c), -1); isc_task_send(task1, &event); /* Fourth event: privileged */ - event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, - set_and_drop, &d, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, + set_and_drop, &d, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(d, -1); + assert_int_equal(atomic_load(&d), -1); isc_task_send(task1, &event); /* Fifth event: not privileged */ - event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, - set_and_drop, &e, sizeof (isc_event_t)); + event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, + set_and_drop, &e, sizeof(isc_event_t)); assert_non_null(event); - assert_int_equal(e, -1); + assert_int_equal(atomic_load(&e), -1); isc_task_send(task2, &event); assert_int_equal(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); @@ -381,8 +393,11 @@ privilege_drop(void **state) { isc__taskmgr_resume(taskmgr); /* We're waiting for all variables to be set. */ - while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) && - i++ < 5000) { + while ((atomic_load(&a) == -1 || atomic_load(&b) == -1 || + atomic_load(&c) == -1 || atomic_load(&d) == -1 || + atomic_load(&e) == -1) && + i++ < 5000) + { isc_test_nap(1000); } @@ -390,15 +405,16 @@ privilege_drop(void **state) { * We need to check that all privilege mode events were fired * in privileged mode, and non privileged in non-privileged. */ - assert_true(a == isc_taskmgrmode_privileged || - c == isc_taskmgrmode_privileged || - d == isc_taskmgrmode_privileged); + assert_true(atomic_load(&a) == isc_taskmgrmode_privileged || + atomic_load(&c) == isc_taskmgrmode_privileged || + atomic_load(&d) == isc_taskmgrmode_privileged); /* ...and neither of the non-privileged tasks did... */ - assert_true(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal); + assert_true(atomic_load(&b) == isc_taskmgrmode_normal || + atomic_load(&e) == isc_taskmgrmode_normal); /* ...but all five of them did run. */ - assert_int_equal(counter, 6); + assert_int_equal(atomic_load(&counter), 6); assert_int_equal(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); @@ -408,6 +424,83 @@ privilege_drop(void **state) { assert_null(task2); } +static void +sleep_cb(isc_task_t *task, isc_event_t *event) { + UNUSED(task); + int p = *(int *)event->ev_arg; + if (p == 1) { + /* + * Signal the main thread that we're running, so that + * it can trigger the race. + */ + LOCK(&lock); + atomic_store(&done2, true); + SIGNAL(&cv); + UNLOCK(&lock); + /* + * Wait for the operations in the main thread to be finished. + */ + LOCK(&lock); + while (!atomic_load(&done)) { + WAIT(&cv, &lock); + } + UNLOCK(&lock); + } else { + /* + * Wait for the operations in the main thread to be finished. + */ + LOCK(&lock); + atomic_store(&done2, true); + SIGNAL(&cv); + UNLOCK(&lock); + } + isc_event_free(&event); +} + +static void +pause_unpause(void **state) { + isc_result_t result; + isc_task_t *task = NULL; + isc_event_t *event1, *event2 = NULL; + UNUSED(state); + atomic_store(&done, false); + atomic_store(&done2, false); + + result = isc_task_create(taskmgr, 0, &task); + assert_int_equal(result, ISC_R_SUCCESS); + + event1 = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST, + sleep_cb, &(int){ 1 }, sizeof(isc_event_t)); + assert_non_null(event1); + event2 = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST, + sleep_cb, &(int){ 2 }, sizeof(isc_event_t)); + assert_non_null(event2); + isc_task_send(task, &event1); + isc_task_send(task, &event2); + /* Wait for event1 to be running */ + LOCK(&lock); + while (!atomic_load(&done2)) { + WAIT(&cv, &lock); + } + UNLOCK(&lock); + /* Pause-unpause-detach is what causes the race */ + isc_task_pause(task); + isc_task_unpause(task); + isc_task_detach(&task); + /* Signal event1 to finish */ + LOCK(&lock); + atomic_store(&done2, false); + atomic_store(&done, true); + SIGNAL(&cv); + UNLOCK(&lock); + /* Wait for event2 to finish */ + LOCK(&lock); + while (!atomic_load(&done2)) { + WAIT(&cv, &lock); + } + UNLOCK(&lock); +} + /* * Basic task functions: */ @@ -422,6 +515,8 @@ basic_cb(isc_task_t *task, isc_event_t *event) { j += 100; } + UNUSED(j); + if (verbose) { print_message("# task %s\n", (char *)event->ev_arg); } @@ -442,7 +537,6 @@ basic_shutdown(isc_task_t *task, isc_event_t *event) { static void basic_tick(isc_task_t *task, isc_event_t *event) { - UNUSED(task); if (verbose) { @@ -471,10 +565,8 @@ basic(void **state) { isc_timer_t *ti2 = NULL; isc_time_t absolute; isc_interval_t interval; - char *testarray[] = { - one, one, one, one, one, one, one, one, one, - two, three, four, two, three, four, NULL - }; + char *testarray[] = { one, one, one, one, one, one, one, one, + one, two, three, four, two, three, four, NULL }; int i; UNUSED(state); @@ -499,24 +591,22 @@ basic(void **state) { isc_time_settoepoch(&absolute); isc_interval_set(&interval, 1, 0); - result = isc_timer_create(timermgr, isc_timertype_ticker, - &absolute, &interval, - task1, basic_tick, tick, &ti1); + result = isc_timer_create(timermgr, isc_timertype_ticker, &absolute, + &interval, task1, basic_tick, tick, &ti1); assert_int_equal(result, ISC_R_SUCCESS); ti2 = NULL; isc_time_settoepoch(&absolute); isc_interval_set(&interval, 1, 0); - result = isc_timer_create(timermgr, isc_timertype_ticker, - &absolute, &interval, - task2, basic_tick, tock, &ti2); + result = isc_timer_create(timermgr, isc_timertype_ticker, &absolute, + &interval, task2, basic_tick, tock, &ti2); assert_int_equal(result, ISC_R_SUCCESS); #ifndef WIN32 sleep(2); -#else +#else /* ifndef WIN32 */ Sleep(2000); -#endif +#endif /* ifndef WIN32 */ for (i = 0; testarray[i] != NULL; i++) { /* @@ -528,7 +618,7 @@ basic(void **state) { * structure (socket, timer, task, etc) but this is just a * test program. */ - event = isc_event_allocate(mctx, (void *)1, 1, basic_cb, + event = isc_event_allocate(test_mctx, (void *)1, 1, basic_cb, testarray[i], sizeof(*event)); assert_non_null(event); isc_task_send(task1, &event); @@ -543,9 +633,9 @@ basic(void **state) { #ifndef WIN32 sleep(10); -#else +#else /* ifndef WIN32 */ Sleep(10000); -#endif +#endif /* ifndef WIN32 */ isc_timer_detach(&ti1); isc_timer_detach(&ti2); } @@ -589,10 +679,10 @@ exclusive_cb(isc_task_t *task, isc_event_t *event) { } isc_task_endexclusive(task); - done = true; + atomic_store(&done, true); } else { active[taskno]++; - (void) spin(10000000); + (void)spin(10000000); active[taskno]--; } @@ -600,8 +690,8 @@ exclusive_cb(isc_task_t *task, isc_event_t *event) { print_message("# task exit %d\n", taskno); } - if (done) { - isc_mem_put(event->ev_destroy_arg, event->ev_arg, sizeof (int)); + if (atomic_load(&done)) { + isc_mem_put(event->ev_destroy_arg, event->ev_arg, sizeof(int)); isc_event_free(&event); } else { isc_task_send(task, &event); @@ -630,13 +720,13 @@ task_exclusive(void **state) { isc_taskmgr_setexcltask(taskmgr, tasks[6]); } - v = isc_mem_get(mctx, sizeof *v); + v = isc_mem_get(test_mctx, sizeof *v); assert_non_null(v); *v = i; - event = isc_event_allocate(mctx, NULL, 1, exclusive_cb, - v, sizeof(*event)); + event = isc_event_allocate(test_mctx, NULL, 1, exclusive_cb, v, + sizeof(*event)); assert_non_null(event); isc_task_send(tasks[i], &event); @@ -656,10 +746,10 @@ maxtask_shutdown(isc_task_t *task, isc_event_t *event) { UNUSED(task); if (event->ev_arg != NULL) { - isc_task_destroy((isc_task_t**) &event->ev_arg); + isc_task_destroy((isc_task_t **)&event->ev_arg); } else { LOCK(&lock); - done = true; + atomic_store(&done, true); SIGNAL(&cv); UNLOCK(&lock); } @@ -674,7 +764,7 @@ maxtask_cb(isc_task_t *task, isc_event_t *event) { if (event->ev_arg != NULL) { isc_task_t *newtask = NULL; - event->ev_arg = (void *)(((uintptr_t) event->ev_arg) - 1); + event->ev_arg = (void *)(((uintptr_t)event->ev_arg) - 1); /* * Create a new task and forward the message. @@ -695,6 +785,7 @@ maxtask_cb(isc_task_t *task, isc_event_t *event) { static void manytasks(void **state) { + isc_mem_t *mctx = NULL; isc_result_t result; isc_event_t *event = NULL; uintptr_t ntasks = 10000; @@ -706,16 +797,16 @@ manytasks(void **state) { (unsigned long)ntasks); } + isc_mutex_init(&lock); isc_condition_init(&cv); isc_mem_debugging = ISC_MEM_DEBUGRECORD; - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mem_create(&mctx); - result = isc_taskmgr_create(mctx, 4, 0, &taskmgr); + result = isc_taskmgr_create(mctx, 4, 0, NULL, &taskmgr); assert_int_equal(result, ISC_R_SUCCESS); - done = false; + atomic_init(&done, false); event = isc_event_allocate(mctx, (void *)1, 1, maxtask_cb, (void *)ntasks, sizeof(*event)); @@ -723,13 +814,15 @@ manytasks(void **state) { LOCK(&lock); maxtask_cb(NULL, event); - while (!done) { + while (!atomic_load(&done)) { WAIT(&cv, &lock); } + UNLOCK(&lock); isc_taskmgr_destroy(&taskmgr); isc_mem_destroy(&mctx); isc_condition_destroy(&cv); + isc_mutex_destroy(&lock); } /* @@ -741,7 +834,7 @@ manytasks(void **state) { static int nevents = 0; static int nsdevents = 0; static int senders[4]; -bool ready = false, all_done = false; +atomic_bool ready, all_done; static void sd_sde1(isc_task_t *task, isc_event_t *event) { @@ -757,7 +850,7 @@ sd_sde1(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); - all_done = true; + atomic_store(&all_done, true); } static void @@ -780,7 +873,7 @@ sd_event1(isc_task_t *task, isc_event_t *event) { UNUSED(task); LOCK(&lock); - while (!ready) { + while (!atomic_load(&ready)) { WAIT(&cv, &lock); } UNLOCK(&lock); @@ -817,7 +910,8 @@ shutdown(void **state) { nevents = nsdevents = 0; event_type = 3; - ready = false; + atomic_init(&ready, false); + atomic_init(&all_done, false); LOCK(&lock); @@ -827,8 +921,8 @@ shutdown(void **state) { /* * This event causes the task to wait on cv. */ - event = isc_event_allocate(mctx, &senders[1], event_type, sd_event1, - NULL, sizeof(*event)); + event = isc_event_allocate(test_mctx, &senders[1], event_type, + sd_event1, NULL, sizeof(*event)); assert_non_null(event); isc_task_send(task, &event); @@ -836,7 +930,7 @@ shutdown(void **state) { * Now we fill up the task's event queue with some events. */ for (i = 0; i < 256; ++i) { - event = isc_event_allocate(mctx, &senders[1], event_type, + event = isc_event_allocate(test_mctx, &senders[1], event_type, sd_event2, NULL, sizeof(*event)); assert_non_null(event); isc_task_send(task, &event); @@ -857,11 +951,11 @@ shutdown(void **state) { /* * Now we free the task by signaling cv. */ - ready = true; + atomic_store(&ready, true); SIGNAL(&cv); UNLOCK(&lock); - while (!all_done) { + while (!atomic_load(&all_done)) { isc_test_nap(1000); } @@ -879,7 +973,7 @@ psd_event1(isc_task_t *task, isc_event_t *event) { LOCK(&lock); - while (!done) { + while (!atomic_load(&done)) { WAIT(&cv, &lock); } @@ -904,7 +998,7 @@ post_shutdown(void **state) { UNUSED(state); - done = false; + atomic_init(&done, false); event_type = 4; isc_condition_init(&cv); @@ -918,8 +1012,8 @@ post_shutdown(void **state) { /* * This event causes the task to wait on cv. */ - event = isc_event_allocate(mctx, &senders[1], event_type, psd_event1, - NULL, sizeof(*event)); + event = isc_event_allocate(test_mctx, &senders[1], event_type, + psd_event1, NULL, sizeof(*event)); assert_non_null(event); isc_task_send(task, &event); @@ -931,7 +1025,7 @@ post_shutdown(void **state) { /* * Release the task. */ - done = true; + atomic_store(&done, true); SIGNAL(&cv); UNLOCK(&lock); @@ -943,10 +1037,10 @@ post_shutdown(void **state) { * Helper for the purge tests below: */ -#define SENDERCNT 3 -#define TYPECNT 4 -#define TAGCNT 5 -#define NEVENTS (SENDERCNT * TYPECNT * TAGCNT) +#define SENDERCNT 3 +#define TYPECNT 4 +#define TAGCNT 5 +#define NEVENTS (SENDERCNT * TYPECNT * TAGCNT) static bool testrange; static void *purge_sender; @@ -955,14 +1049,14 @@ static isc_eventtype_t purge_type_last; static void *purge_tag; static int eventcnt; -bool started = false; +atomic_bool started; static void pg_event1(isc_task_t *task, isc_event_t *event) { UNUSED(task); LOCK(&lock); - while (!started) { + while (!atomic_load(&started)) { WAIT(&cv, &lock); } UNLOCK(&lock); @@ -984,8 +1078,7 @@ pg_event2(isc_task_t *task, isc_event_t *event) { if (testrange) { if ((purge_type_first <= event->ev_type) && - (event->ev_type <= purge_type_last)) - { + (event->ev_type <= purge_type_last)) { type_match = true; } } else { @@ -1026,7 +1119,7 @@ pg_sde(isc_task_t *task, isc_event_t *event) { UNUSED(task); LOCK(&lock); - done = true; + atomic_store(&done, true); SIGNAL(&cv); UNLOCK(&lock); @@ -1044,8 +1137,8 @@ test_purge(int sender, int type, int tag, int exp_purged) { int sender_cnt, type_cnt, tag_cnt, event_cnt, i; int purged = 0; - started = false; - done = false; + atomic_init(&started, false); + atomic_init(&done, false); eventcnt = 0; isc_condition_init(&cv); @@ -1059,8 +1152,8 @@ test_purge(int sender, int type, int tag, int exp_purged) { /* * Block the task on cv. */ - event = isc_event_allocate(mctx, (void *)1, 9999, - pg_event1, NULL, sizeof(*event)); + event = isc_event_allocate(test_mctx, (void *)1, 9999, pg_event1, NULL, + sizeof(*event)); assert_non_null(event); isc_task_send(task, &event); @@ -1073,11 +1166,11 @@ test_purge(int sender, int type, int tag, int exp_purged) { for (sender_cnt = 0; sender_cnt < SENDERCNT; ++sender_cnt) { for (type_cnt = 0; type_cnt < TYPECNT; ++type_cnt) { for (tag_cnt = 0; tag_cnt < TAGCNT; ++tag_cnt) { - eventtab[event_cnt] = - isc_event_allocate(mctx, - &senders[sender + sender_cnt], - (isc_eventtype_t)(type + type_cnt), - pg_event2, NULL, sizeof(*event)); + eventtab[event_cnt] = isc_event_allocate( + test_mctx, + &senders[sender + sender_cnt], + (isc_eventtype_t)(type + type_cnt), + pg_event2, NULL, sizeof(*event)); assert_non_null(eventtab[event_cnt]); @@ -1092,8 +1185,7 @@ test_purge(int sender, int type, int tag, int exp_purged) { */ if (((sender_cnt % 2) != 0) && ((type_cnt % 2) != 0) && - ((tag_cnt % 2) != 0)) - { + ((tag_cnt % 2) != 0)) { eventtab[event_cnt]->ev_attributes |= ISC_EVENTATTR_NOPURGE; } @@ -1110,26 +1202,24 @@ test_purge(int sender, int type, int tag, int exp_purged) { /* * We're testing isc_task_purgerange. */ - purged = isc_task_purgerange(task, purge_sender, - (isc_eventtype_t)purge_type_first, - (isc_eventtype_t)purge_type_last, - purge_tag); + purged = isc_task_purgerange( + task, purge_sender, (isc_eventtype_t)purge_type_first, + (isc_eventtype_t)purge_type_last, purge_tag); assert_int_equal(purged, exp_purged); } else { /* * We're testing isc_task_purge. */ if (verbose) { - print_message("# purge events %p,%u,%p\n", - purge_sender, purge_type_first, - purge_tag); + print_message("# purge events %p,%u,%p\n", purge_sender, + purge_type_first, purge_tag); } purged = isc_task_purge(task, purge_sender, (isc_eventtype_t)purge_type_first, purge_tag); if (verbose) { - print_message("# purged %d expected %d\n", - purged, exp_purged); + print_message("# purged %d expected %d\n", purged, + exp_purged); } assert_int_equal(purged, exp_purged); @@ -1139,7 +1229,7 @@ test_purge(int sender, int type, int tag, int exp_purged) { * Unblock the task, allowing event processing. */ LOCK(&lock); - started = true; + atomic_store(&started, true); SIGNAL(&cv); isc_task_shutdown(task); @@ -1149,7 +1239,7 @@ test_purge(int sender, int type, int tag, int exp_purged) { /* * Wait for shutdown processing to complete. */ - while (!done) { + while (!atomic_load(&done)) { result = isc_time_nowplusinterval(&now, &interval); assert_int_equal(result, ISC_R_SUCCESS); @@ -1303,7 +1393,7 @@ pge_event1(isc_task_t *task, isc_event_t *event) { UNUSED(task); LOCK(&lock); - while (!started) { + while (!atomic_load(&started)) { WAIT(&cv, &lock); } UNLOCK(&lock); @@ -1319,13 +1409,12 @@ pge_event2(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); } - static void pge_sde(isc_task_t *task, isc_event_t *event) { UNUSED(task); LOCK(&lock); - done = true; + atomic_store(&done, true); SIGNAL(&cv); UNLOCK(&lock); @@ -1334,17 +1423,17 @@ pge_sde(isc_task_t *task, isc_event_t *event) { static void try_purgeevent(bool purgeable) { - isc_result_t result; + isc_result_t result; isc_task_t *task = NULL; bool purged; isc_event_t *event1 = NULL; isc_event_t *event2 = NULL; - isc_event_t *event2_clone = NULL;; + isc_event_t *event2_clone = NULL; isc_time_t now; isc_interval_t interval; - started = false; - done = false; + atomic_init(&started, false); + atomic_init(&done, false); eventcnt = 0; isc_condition_init(&cv); @@ -1358,12 +1447,12 @@ try_purgeevent(bool purgeable) { /* * Block the task on cv. */ - event1 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1, + event1 = isc_event_allocate(test_mctx, (void *)1, (isc_eventtype_t)1, pge_event1, NULL, sizeof(*event1)); assert_non_null(event1); isc_task_send(task, &event1); - event2 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1, + event2 = isc_event_allocate(test_mctx, (void *)1, (isc_eventtype_t)1, pge_event2, NULL, sizeof(*event2)); assert_non_null(event2); @@ -1384,7 +1473,7 @@ try_purgeevent(bool purgeable) { * Unblock the task, allowing event processing. */ LOCK(&lock); - started = true; + atomic_store(&started, true); SIGNAL(&cv); isc_task_shutdown(task); @@ -1394,7 +1483,7 @@ try_purgeevent(bool purgeable) { /* * Wait for shutdown processing to complete. */ - while (!done) { + while (!atomic_load(&done)) { result = isc_time_nowplusinterval(&now, &interval); assert_int_equal(result, ISC_R_SUCCESS); @@ -1439,29 +1528,52 @@ purgeevent_notpurge(void **state) { int main(int argc, char **argv) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create_task, _setup, _teardown), - cmocka_unit_test_setup_teardown(shutdown, _setup4, _teardown), cmocka_unit_test(manytasks), cmocka_unit_test_setup_teardown(all_events, _setup, _teardown), cmocka_unit_test_setup_teardown(basic, _setup2, _teardown), - cmocka_unit_test_setup_teardown(privileged_events, - _setup, _teardown), - cmocka_unit_test_setup_teardown(privilege_drop, - _setup, _teardown), - cmocka_unit_test_setup_teardown(task_exclusive, - _setup4, _teardown), - cmocka_unit_test_setup_teardown(post_shutdown, - _setup2, _teardown), + cmocka_unit_test_setup_teardown(create_task, _setup, _teardown), + cmocka_unit_test_setup_teardown(pause_unpause, _setup, + _teardown), + cmocka_unit_test_setup_teardown(post_shutdown, _setup2, + _teardown), + cmocka_unit_test_setup_teardown(privilege_drop, _setup, + _teardown), + cmocka_unit_test_setup_teardown(privileged_events, _setup, + _teardown), cmocka_unit_test_setup_teardown(purge, _setup2, _teardown), - cmocka_unit_test_setup_teardown(purgerange, _setup, _teardown), cmocka_unit_test_setup_teardown(purgeevent, _setup2, _teardown), - cmocka_unit_test_setup_teardown(purgeevent_notpurge, - _setup, _teardown), + cmocka_unit_test_setup_teardown(purgeevent_notpurge, _setup, + _teardown), + cmocka_unit_test_setup_teardown(purgerange, _setup, _teardown), + cmocka_unit_test_setup_teardown(shutdown, _setup4, _teardown), + cmocka_unit_test_setup_teardown(task_exclusive, _setup4, + _teardown), }; + struct CMUnitTest selected[sizeof(tests) / sizeof(tests[0])]; + size_t i; int c; - while ((c = isc_commandline_parse(argc, argv, "v")) != -1) { + memset(selected, 0, sizeof(selected)); + + while ((c = isc_commandline_parse(argc, argv, "lt:v")) != -1) { switch (c) { + case 'l': + for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) + { + if (tests[i].name != NULL) { + fprintf(stdout, "%s\n", tests[i].name); + } + } + return (0); + case 't': + if (!cmocka_add_test_byname( + tests, isc_commandline_argument, selected)) + { + fprintf(stderr, "unknown test '%s'\n", + isc_commandline_argument); + exit(1); + } + break; case 'v': verbose = true; break; @@ -1470,8 +1582,11 @@ main(int argc, char **argv) { } } - - return (cmocka_run_group_tests(tests, NULL, NULL)); + if (selected[0].name != NULL) { + return (cmocka_run_group_tests(selected, NULL, NULL)); + } else { + return (cmocka_run_group_tests(tests, NULL, NULL)); + } } #else /* HAVE_CMOCKA */ @@ -1484,4 +1599,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/taskpool_test.c b/lib/isc/tests/taskpool_test.c index 3ea37282..5b97a0d7 100644 --- a/lib/isc/tests/taskpool_test.c +++ b/lib/isc/tests/taskpool_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -28,7 +26,6 @@ #include <isc/taskpool.h> #include <isc/util.h> - #include "isctest.h" static int @@ -60,7 +57,7 @@ create_pool(void **state) { UNUSED(state); - result = isc_taskpool_create(taskmgr, mctx, 8, 2, &pool); + result = isc_taskpool_create(taskmgr, test_mctx, 8, 2, &pool); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_taskpool_size(pool), 8); @@ -76,7 +73,7 @@ expand_pool(void **state) { UNUSED(state); - result = isc_taskpool_create(taskmgr, mctx, 10, 2, &pool1); + result = isc_taskpool_create(taskmgr, test_mctx, 10, 2, &pool1); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_taskpool_size(pool1), 10); @@ -121,7 +118,7 @@ get_tasks(void **state) { UNUSED(state); - result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool); + result = isc_taskpool_create(taskmgr, test_mctx, 2, 2, &pool); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_taskpool_size(pool), 2); @@ -152,7 +149,7 @@ set_privilege(void **state) { UNUSED(state); - result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool); + result = isc_taskpool_create(taskmgr, test_mctx, 2, 2, &pool); assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(isc_taskpool_size(pool), 2); @@ -187,14 +184,11 @@ set_privilege(void **state) { int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create_pool, - _setup, _teardown), - cmocka_unit_test_setup_teardown(expand_pool, - _setup, _teardown), - cmocka_unit_test_setup_teardown(get_tasks, - _setup, _teardown), - cmocka_unit_test_setup_teardown(set_privilege, - _setup, _teardown), + cmocka_unit_test_setup_teardown(create_pool, _setup, _teardown), + cmocka_unit_test_setup_teardown(expand_pool, _setup, _teardown), + cmocka_unit_test_setup_teardown(get_tasks, _setup, _teardown), + cmocka_unit_test_setup_teardown(set_privilege, _setup, + _teardown), }; return (cmocka_run_group_tests(tests, NULL, NULL)); @@ -210,4 +204,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/time_test.c b/lib/isc/tests/time_test.c index 50afbc44..1bc03917 100644 --- a/lib/isc/tests/time_test.c +++ b/lib/isc/tests/time_test.c @@ -3,20 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -24,8 +22,8 @@ #define UNIT_TESTING #include <cmocka.h> -#include <isc/time.h> #include <isc/result.h> +#include <isc/time.h> #include <isc/util.h> /* parse http time stamp */ @@ -37,7 +35,7 @@ isc_time_parsehttptimestamp_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -56,7 +54,7 @@ isc_time_formatISO8601_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -92,7 +90,7 @@ isc_time_formatISO8601ms_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -120,6 +118,43 @@ isc_time_formatISO8601ms_test(void **state) { assert_string_equal(buf, "2015-12-13T09:46:40.123Z"); } +/* print UTC in ISO8601 with microseconds */ +static void +isc_time_formatISO8601us_test(void **state) { + isc_result_t result; + isc_time_t t; + char buf[64]; + + UNUSED(state); + + setenv("TZ", "America/Los_Angeles", 1); + result = isc_time_now(&t); + assert_int_equal(result, ISC_R_SUCCESS); + + /* check formatting: yyyy-mm-ddThh:mm:ss.ssssssZ */ + memset(buf, 'X', sizeof(buf)); + isc_time_formatISO8601us(&t, buf, sizeof(buf)); + assert_int_equal(strlen(buf), 27); + assert_int_equal(buf[4], '-'); + assert_int_equal(buf[7], '-'); + assert_int_equal(buf[10], 'T'); + assert_int_equal(buf[13], ':'); + assert_int_equal(buf[16], ':'); + assert_int_equal(buf[19], '.'); + assert_int_equal(buf[26], 'Z'); + + /* check time conversion correctness */ + memset(buf, 'X', sizeof(buf)); + isc_time_settoepoch(&t); + isc_time_formatISO8601us(&t, buf, sizeof(buf)); + assert_string_equal(buf, "1970-01-01T00:00:00.000000Z"); + + memset(buf, 'X', sizeof(buf)); + isc_time_set(&t, 1450000000, 123456000); + isc_time_formatISO8601us(&t, buf, sizeof(buf)); + assert_string_equal(buf, "2015-12-13T09:46:40.123456Z"); +} + /* print local time in ISO8601 */ static void isc_time_formatISO8601L_test(void **state) { @@ -129,7 +164,7 @@ isc_time_formatISO8601L_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -164,7 +199,7 @@ isc_time_formatISO8601Lms_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -191,6 +226,42 @@ isc_time_formatISO8601Lms_test(void **state) { assert_string_equal(buf, "2015-12-13T01:46:40.123"); } +/* print local time in ISO8601 with microseconds */ +static void +isc_time_formatISO8601Lus_test(void **state) { + isc_result_t result; + isc_time_t t; + char buf[64]; + + UNUSED(state); + + setenv("TZ", "America/Los_Angeles", 1); + result = isc_time_now(&t); + assert_int_equal(result, ISC_R_SUCCESS); + + /* check formatting: yyyy-mm-ddThh:mm:ss.ssssss */ + memset(buf, 'X', sizeof(buf)); + isc_time_formatISO8601Lus(&t, buf, sizeof(buf)); + assert_int_equal(strlen(buf), 26); + assert_int_equal(buf[4], '-'); + assert_int_equal(buf[7], '-'); + assert_int_equal(buf[10], 'T'); + assert_int_equal(buf[13], ':'); + assert_int_equal(buf[16], ':'); + assert_int_equal(buf[19], '.'); + + /* check time conversion correctness */ + memset(buf, 'X', sizeof(buf)); + isc_time_settoepoch(&t); + isc_time_formatISO8601Lus(&t, buf, sizeof(buf)); + assert_string_equal(buf, "1969-12-31T16:00:00.000000"); + + memset(buf, 'X', sizeof(buf)); + isc_time_set(&t, 1450000000, 123456000); + isc_time_formatISO8601Lus(&t, buf, sizeof(buf)); + assert_string_equal(buf, "2015-12-13T01:46:40.123456"); +} + /* print UTC time as yyyymmddhhmmsssss */ static void isc_time_formatshorttimestamp_test(void **state) { @@ -200,7 +271,7 @@ isc_time_formatshorttimestamp_test(void **state) { UNUSED(state); - setenv("TZ", "PST8PDT", 1); + setenv("TZ", "America/Los_Angeles", 1); result = isc_time_now(&t); assert_int_equal(result, ISC_R_SUCCESS); @@ -227,8 +298,10 @@ main(void) { cmocka_unit_test(isc_time_parsehttptimestamp_test), cmocka_unit_test(isc_time_formatISO8601_test), cmocka_unit_test(isc_time_formatISO8601ms_test), + cmocka_unit_test(isc_time_formatISO8601us_test), cmocka_unit_test(isc_time_formatISO8601L_test), cmocka_unit_test(isc_time_formatISO8601Lms_test), + cmocka_unit_test(isc_time_formatISO8601Lus_test), cmocka_unit_test(isc_time_formatshorttimestamp_test), }; @@ -245,4 +318,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/tests/timer_test.c b/lib/isc/tests/timer_test.c index 1415a3fa..d29241fe 100644 --- a/lib/isc/tests/timer_test.c +++ b/lib/isc/tests/timer_test.c @@ -3,20 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #if HAVE_CMOCKA +#include <inttypes.h> +#include <sched.h> /* IWYU pragma: keep */ +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> - #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -24,8 +23,9 @@ #define UNIT_TESTING #include <cmocka.h> -#include <isc/condition.h> +#include <isc/atomic.h> #include <isc/commandline.h> +#include <isc/condition.h> #include <isc/mem.h> #include <isc/platform.h> #include <isc/print.h> @@ -34,22 +34,25 @@ #include <isc/timer.h> #include <isc/util.h> +#include "../timer.c" #include "isctest.h" /* Set to true (or use -v option) for verbose output */ static bool verbose = false; -#define FUDGE_SECONDS 0 /* in absence of clock_getres() */ -#define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */ +#define FUDGE_SECONDS 0 /* in absence of clock_getres() */ +#define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */ static isc_timer_t *timer = NULL; static isc_condition_t cv; static isc_mutex_t mx; static isc_time_t endtime; +static isc_mutex_t lasttime_mx; static isc_time_t lasttime; static int seconds; static int nanoseconds; -static int eventcnt; +static atomic_int_fast32_t eventcnt; +static atomic_uint_fast32_t errcnt; static int nevents; static int @@ -62,6 +65,8 @@ _setup(void **state) { result = isc_test_begin(NULL, true, 2); assert_int_equal(result, ISC_R_SUCCESS); + atomic_init(&errcnt, ISC_R_SUCCESS); + return (0); } @@ -98,14 +103,14 @@ shutdown(isc_task_t *task, isc_event_t *event) { static void setup_test(isc_timertype_t timertype, isc_time_t *expires, isc_interval_t *interval, - void (*action)(isc_task_t *, isc_event_t *)) -{ + void (*action)(isc_task_t *, isc_event_t *)) { isc_result_t result; isc_task_t *task = NULL; isc_time_settoepoch(&endtime); - eventcnt = 0; + atomic_init(&eventcnt, 0); isc_mutex_init(&mx); + isc_mutex_init(&lasttime_mx); isc_condition_init(&cv); @@ -117,27 +122,57 @@ setup_test(isc_timertype_t timertype, isc_time_t *expires, result = isc_task_onshutdown(task, shutdown, NULL); assert_int_equal(result, ISC_R_SUCCESS); + isc_mutex_lock(&lasttime_mx); result = isc_time_now(&lasttime); + isc_mutex_unlock(&lasttime_mx); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_timer_create(timermgr, timertype, expires, interval, - task, action, (void *)timertype, - &timer); + result = isc_timer_create(timermgr, timertype, expires, interval, task, + action, (void *)timertype, &timer); assert_int_equal(result, ISC_R_SUCCESS); /* * Wait for shutdown processing to complete. */ - while (eventcnt != nevents) { + while (atomic_load(&eventcnt) != nevents) { result = isc_condition_wait(&cv, &mx); assert_int_equal(result, ISC_R_SUCCESS); } UNLOCK(&mx); + assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS); + isc_task_detach(&task); isc_mutex_destroy(&mx); - (void) isc_condition_destroy(&cv); + (void)isc_condition_destroy(&cv); +} + +static void +set_global_error(isc_result_t result) { + (void)atomic_compare_exchange_strong( + &errcnt, &(uint_fast32_t){ ISC_R_SUCCESS }, result); +} + +static void +subthread_assert_true(bool expected) { + if (!expected) { + set_global_error(ISC_R_UNEXPECTED); + } +} + +static void +subthread_assert_int_equal(int observed, int expected) { + if (observed != expected) { + set_global_error(ISC_R_UNEXPECTED); + } +} + +static void +subthread_assert_result_equal(isc_result_t result, isc_result_t expected) { + if (result != expected) { + set_global_error(result); + } } static void @@ -150,14 +185,14 @@ ticktock(isc_task_t *task, isc_event_t *event) { isc_interval_t interval; isc_eventtype_t expected_event_type; - ++eventcnt; + int tick = atomic_fetch_add(&eventcnt, 1); if (verbose) { - print_message("# tick %d\n", eventcnt); + print_message("# tick %d\n", tick); } expected_event_type = ISC_TIMEREVENT_LIFE; - if ((isc_timertype_t) event->ev_arg == isc_timertype_ticker) { + if ((uintptr_t)event->ev_arg == isc_timertype_ticker) { expected_event_type = ISC_TIMEREVENT_TICK; } @@ -167,26 +202,33 @@ ticktock(isc_task_t *task, isc_event_t *event) { } result = isc_time_now(&now); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, seconds, nanoseconds); + isc_mutex_lock(&lasttime_mx); result = isc_time_add(&lasttime, &interval, &base); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mutex_unlock(&lasttime_mx); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS); result = isc_time_add(&base, &interval, &ulim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); result = isc_time_subtract(&base, &interval, &llim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); - assert_true(isc_time_compare(&llim, &now) <= 0); - assert_true(isc_time_compare(&ulim, &now) >= 0); - lasttime = now; + subthread_assert_true(isc_time_compare(&llim, &now) <= 0); + subthread_assert_true(isc_time_compare(&ulim, &now) >= 0); - if (eventcnt == nevents) { + isc_interval_set(&interval, 0, 0); + isc_mutex_lock(&lasttime_mx); + result = isc_time_add(&now, &interval, &lasttime); + isc_mutex_unlock(&lasttime_mx); + subthread_assert_result_equal(result, ISC_R_SUCCESS); + + if (atomic_load(&eventcnt) == nevents) { result = isc_time_now(&endtime); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_timer_detach(&timer); isc_task_shutdown(task); } @@ -247,31 +289,37 @@ test_idle(isc_task_t *task, isc_event_t *event) { isc_time_t llim; isc_interval_t interval; - ++eventcnt; + int tick = atomic_fetch_add(&eventcnt, 1); if (verbose) { - print_message("# tick %d\n", eventcnt); + print_message("# tick %d\n", tick); } result = isc_time_now(&now); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, seconds, nanoseconds); + isc_mutex_lock(&lasttime_mx); result = isc_time_add(&lasttime, &interval, &base); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mutex_unlock(&lasttime_mx); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS); result = isc_time_add(&base, &interval, &ulim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); result = isc_time_subtract(&base, &interval, &llim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); + + subthread_assert_true(isc_time_compare(&llim, &now) <= 0); + subthread_assert_true(isc_time_compare(&ulim, &now) >= 0); - assert_true(isc_time_compare(&llim, &now) <= 0); - assert_true(isc_time_compare(&ulim, &now) >= 0); - lasttime = now; + isc_interval_set(&interval, 0, 0); + isc_mutex_lock(&lasttime_mx); + isc_time_add(&now, &interval, &lasttime); + isc_mutex_unlock(&lasttime_mx); - assert_int_equal(event->ev_type, ISC_TIMEREVENT_IDLE); + subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_IDLE); isc_timer_detach(&timer); isc_task_shutdown(task); @@ -311,10 +359,10 @@ test_reset(isc_task_t *task, isc_event_t *event) { isc_time_t expires; isc_interval_t interval; - ++eventcnt; + int tick = atomic_fetch_add(&eventcnt, 1); if (verbose) { - print_message("# tick %d\n", eventcnt); + print_message("# tick %d\n", tick); } /* @@ -322,39 +370,46 @@ test_reset(isc_task_t *task, isc_event_t *event) { */ result = isc_time_now(&now); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, seconds, nanoseconds); + isc_mutex_lock(&lasttime_mx); result = isc_time_add(&lasttime, &interval, &base); - assert_int_equal(result, ISC_R_SUCCESS); + isc_mutex_unlock(&lasttime_mx); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS); result = isc_time_add(&base, &interval, &ulim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); result = isc_time_subtract(&base, &interval, &llim); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); + + subthread_assert_true(isc_time_compare(&llim, &now) <= 0); + subthread_assert_true(isc_time_compare(&ulim, &now) >= 0); - assert_true(isc_time_compare(&llim, &now) <= 0); - assert_true(isc_time_compare(&ulim, &now) >= 0); - lasttime = now; + isc_interval_set(&interval, 0, 0); + isc_mutex_lock(&lasttime_mx); + isc_time_add(&now, &interval, &lasttime); + isc_mutex_unlock(&lasttime_mx); - if (eventcnt < 3) { - assert_int_equal(event->ev_type, ISC_TIMEREVENT_TICK); + int _eventcnt = atomic_load(&eventcnt); - if (eventcnt == 2) { + if (_eventcnt < 3) { + subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_TICK); + + if (_eventcnt == 2) { isc_interval_set(&interval, seconds, nanoseconds); result = isc_time_nowplusinterval(&expires, &interval); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, 0, 0); result = isc_timer_reset(timer, isc_timertype_once, - &expires, &interval, - false); - assert_int_equal(result, ISC_R_SUCCESS); + &expires, &interval, false); + subthread_assert_result_equal(result, ISC_R_SUCCESS); } } else { - assert_int_equal(event->ev_type, ISC_TIMEREVENT_LIFE); + subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_LIFE); isc_timer_detach(&timer); isc_task_shutdown(task); @@ -401,8 +456,8 @@ start_event(isc_task_t *task, isc_event_t *event) { } LOCK(&mx); - while (! startflag) { - (void) isc_condition_wait(&cv, &mx); + while (!startflag) { + (void)isc_condition_wait(&cv, &mx); } UNLOCK(&mx); @@ -417,21 +472,21 @@ tick_event(isc_task_t *task, isc_event_t *event) { UNUSED(task); - ++eventcnt; + int tick = atomic_fetch_add(&eventcnt, 1); if (verbose) { - print_message("# tick_event %d\n", eventcnt); + print_message("# tick_event %d\n", tick); } /* * On the first tick, purge all remaining tick events * and then shut down the task. */ - if (eventcnt == 1) { + if (tick == 0) { isc_time_settoepoch(&expires); isc_interval_set(&interval, seconds, 0); result = isc_timer_reset(tickertimer, isc_timertype_ticker, &expires, &interval, true); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); isc_task_shutdown(task); } @@ -454,7 +509,7 @@ once_event(isc_task_t *task, isc_event_t *event) { startflag = 1; result = isc_condition_broadcast(&cv); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); UNLOCK(&mx); isc_event_free(&event); @@ -479,7 +534,7 @@ shutdown_purge(isc_task_t *task, isc_event_t *event) { shutdownflag = 1; result = isc_condition_signal(&cv); - assert_int_equal(result, ISC_R_SUCCESS); + subthread_assert_result_equal(result, ISC_R_SUCCESS); UNLOCK(&mx); isc_event_free(&event); @@ -497,7 +552,7 @@ purge(void **state) { startflag = 0; shutdownflag = 0; - eventcnt = 0; + atomic_init(&eventcnt, 0); seconds = 1; nanoseconds = 0; @@ -516,7 +571,7 @@ purge(void **state) { LOCK(&mx); - event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1, + event = isc_event_allocate(test_mctx, (void *)1, (isc_eventtype_t)1, start_event, NULL, sizeof(*event)); assert_non_null(event); isc_task_send(task1, &event); @@ -525,9 +580,9 @@ purge(void **state) { isc_interval_set(&interval, seconds, 0); tickertimer = NULL; - result = isc_timer_create(timermgr, isc_timertype_ticker, - &expires, &interval, task1, - tick_event, NULL, &tickertimer); + result = isc_timer_create(timermgr, isc_timertype_ticker, &expires, + &interval, task1, tick_event, NULL, + &tickertimer); assert_int_equal(result, ISC_R_SUCCESS); oncetimer = NULL; @@ -537,22 +592,24 @@ purge(void **state) { assert_int_equal(result, ISC_R_SUCCESS); isc_interval_set(&interval, 0, 0); - result = isc_timer_create(timermgr, isc_timertype_once, - &expires, &interval, task2, - once_event, NULL, &oncetimer); + result = isc_timer_create(timermgr, isc_timertype_once, &expires, + &interval, task2, once_event, NULL, + &oncetimer); assert_int_equal(result, ISC_R_SUCCESS); /* * Wait for shutdown processing to complete. */ - while (! shutdownflag) { + while (!shutdownflag) { result = isc_condition_wait(&cv, &mx); assert_int_equal(result, ISC_R_SUCCESS); } UNLOCK(&mx); - assert_int_equal(eventcnt, 1); + assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS); + + assert_int_equal(atomic_load(&eventcnt), 1); isc_timer_detach(&tickertimer); isc_timer_detach(&oncetimer); @@ -564,11 +621,9 @@ purge(void **state) { int main(int argc, char **argv) { const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(ticker, _setup, _teardown), - cmocka_unit_test_setup_teardown(once_life, _setup, _teardown), - cmocka_unit_test_setup_teardown(once_idle, _setup, _teardown), - cmocka_unit_test_setup_teardown(reset, _setup, _teardown), - cmocka_unit_test_setup_teardown(purge, _setup, _teardown), + cmocka_unit_test(ticker), cmocka_unit_test(once_life), + cmocka_unit_test(once_idle), cmocka_unit_test(reset), + cmocka_unit_test(purge), }; int c; @@ -582,7 +637,7 @@ main(int argc, char **argv) { } } - return (cmocka_run_group_tests(tests, NULL, NULL)); + return (cmocka_run_group_tests(tests, _setup, _teardown)); } #else /* HAVE_CMOCKA */ @@ -595,4 +650,4 @@ main(void) { return (0); } -#endif +#endif /* if HAVE_CMOCKA */ diff --git a/lib/isc/timer.c b/lib/isc/timer.c index bd8a1c4e..95981cc2 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdbool.h> #include <isc/app.h> @@ -25,6 +22,7 @@ #include <isc/once.h> #include <isc/platform.h> #include <isc/print.h> +#include <isc/refcount.h> #include <isc/task.h> #include <isc/thread.h> #include <isc/time.h> @@ -33,18 +31,20 @@ #ifdef OPENSSL_LEAKS #include <openssl/err.h> -#endif +#endif /* ifdef OPENSSL_LEAKS */ #ifdef ISC_TIMER_TRACE -#define XTRACE(s) fprintf(stderr, "%s\n", (s)) -#define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t)) -#define XTRACETIME(s, d) fprintf(stderr, "%s %u.%09u\n", (s), \ - (d).seconds, (d).nanoseconds) -#define XTRACETIME2(s, d, n) fprintf(stderr, "%s %u.%09u %u.%09u\n", (s), \ - (d).seconds, (d).nanoseconds, (n).seconds, (n).nanoseconds) -#define XTRACETIMER(s, t, d) fprintf(stderr, "%s %p %u.%09u\n", (s), (t), \ - (d).seconds, (d).nanoseconds) -#else +#define XTRACE(s) fprintf(stderr, "%s\n", (s)) +#define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t)) +#define XTRACETIME(s, d) \ + fprintf(stderr, "%s %u.%09u\n", (s), (d).seconds, (d).nanoseconds) +#define XTRACETIME2(s, d, n) \ + fprintf(stderr, "%s %u.%09u %u.%09u\n", (s), (d).seconds, \ + (d).nanoseconds, (n).seconds, (n).nanoseconds) +#define XTRACETIMER(s, t, d) \ + fprintf(stderr, "%s %p %u.%09u\n", (s), (t), (d).seconds, \ + (d).nanoseconds) +#else /* ifdef ISC_TIMER_TRACE */ #define XTRACE(s) #define XTRACEID(s, t) #define XTRACETIME(s, d) @@ -52,48 +52,48 @@ #define XTRACETIMER(s, t, d) #endif /* ISC_TIMER_TRACE */ -#define TIMER_MAGIC ISC_MAGIC('T', 'I', 'M', 'R') -#define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC) +#define TIMER_MAGIC ISC_MAGIC('T', 'I', 'M', 'R') +#define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC) typedef struct isc__timer isc__timer_t; typedef struct isc__timermgr isc__timermgr_t; struct isc__timer { /*! Not locked. */ - isc_timer_t common; - isc__timermgr_t * manager; - isc_mutex_t lock; + isc_timer_t common; + isc__timermgr_t *manager; + isc_mutex_t lock; + isc_refcount_t references; /*! Locked by timer lock. */ - unsigned int references; - isc_time_t idle; + isc_time_t idle; /*! Locked by manager lock. */ - isc_timertype_t type; - isc_time_t expires; - isc_interval_t interval; - isc_task_t * task; - isc_taskaction_t action; - void * arg; - unsigned int index; - isc_time_t due; - LINK(isc__timer_t) link; + isc_timertype_t type; + isc_time_t expires; + isc_interval_t interval; + isc_task_t *task; + isc_taskaction_t action; + void *arg; + unsigned int index; + isc_time_t due; + LINK(isc__timer_t) link; }; -#define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC) +#define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M') +#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC) struct isc__timermgr { /* Not locked. */ - isc_timermgr_t common; - isc_mem_t * mctx; - isc_mutex_t lock; + isc_timermgr_t common; + isc_mem_t *mctx; + isc_mutex_t lock; /* Locked by manager lock. */ - bool done; - LIST(isc__timer_t) timers; - unsigned int nscheduled; - isc_time_t due; - isc_condition_t wakeup; - isc_thread_t thread; - isc_heap_t * heap; + bool done; + LIST(isc__timer_t) timers; + unsigned int nscheduled; + isc_time_t due; + isc_condition_t wakeup; + isc_thread_t thread; + isc_heap_t *heap; }; void @@ -119,20 +119,25 @@ schedule(isc__timer_t *timer, isc_time_t *now, bool signal_ok) { */ if (timer->type != isc_timertype_once) { result = isc_time_add(now, &timer->interval, &due); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } if (timer->type == isc_timertype_limited && isc_time_compare(&timer->expires, &due) < 0) + { due = timer->expires; + } } else { - if (isc_time_isepoch(&timer->idle)) + if (isc_time_isepoch(&timer->idle)) { due = timer->expires; - else if (isc_time_isepoch(&timer->expires)) + } else if (isc_time_isepoch(&timer->expires)) { due = timer->idle; - else if (isc_time_compare(&timer->idle, &timer->expires) < 0) + } else if (isc_time_compare(&timer->idle, &timer->expires) < 0) + { due = timer->idle; - else + } else { due = timer->expires; + } } /* @@ -194,8 +199,9 @@ deschedule(isc__timer_t *timer) { manager = timer->manager; if (timer->index > 0) { - if (timer->index == 1) + if (timer->index == 1) { need_wakeup = true; + } isc_heap_delete(manager->heap, timer->index); timer->index = 0; INSIST(manager->nscheduled > 0); @@ -217,11 +223,8 @@ destroy(isc__timer_t *timer) { LOCK(&manager->lock); - (void)isc_task_purgerange(timer->task, - timer, - ISC_TIMEREVENT_FIRSTEVENT, - ISC_TIMEREVENT_LASTEVENT, - NULL); + (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT, + ISC_TIMEREVENT_LASTEVENT, NULL); deschedule(timer); UNLINK(manager->timers, timer, link); @@ -238,9 +241,12 @@ isc_result_t isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, - isc_timer_t **timerp) -{ - isc__timermgr_t *manager = (isc__timermgr_t *)manager0; + isc_timer_t **timerp) { + REQUIRE(VALID_MANAGER(manager0)); + REQUIRE(task != NULL); + REQUIRE(action != NULL); + + isc__timermgr_t *manager; isc__timer_t *timer; isc_result_t result; isc_time_t now; @@ -252,14 +258,13 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, * called with 'arg' as the arg value. The new timer is returned * in 'timerp'. */ - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - if (expires == NULL) + manager = (isc__timermgr_t *)manager0; + if (expires == NULL) { expires = isc_time_epoch; - if (interval == NULL) + } + if (interval == NULL) { interval = isc_interval_zero; + } REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(timerp != NULL && *timerp == NULL); @@ -280,13 +285,10 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, isc_time_settoepoch(&now); } - timer = isc_mem_get(manager->mctx, sizeof(*timer)); - if (timer == NULL) - return (ISC_R_NOMEMORY); timer->manager = manager; - timer->references = 1; + isc_refcount_init(&timer->references, 1); if (type == isc_timertype_once && !isc_interval_iszero(interval)) { result = isc_time_add(&now, interval, &timer->idle); @@ -294,8 +296,9 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } - } else + } else { isc_time_settoepoch(&timer->idle); + } timer->type = type; timer->expires = *expires; @@ -327,10 +330,11 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, * there are no external references to it yet. */ - if (type != isc_timertype_inactive) + if (type != isc_timertype_inactive) { result = schedule(timer, &now, true); - else + } else { result = ISC_R_SUCCESS; + } if (result == ISC_R_SUCCESS) { *timerp = (isc_timer_t *)timer; APPEND(manager->timers, timer, link); @@ -352,10 +356,9 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type, isc_result_t isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type, - const isc_time_t *expires, const isc_interval_t *interval, - bool purge) -{ - isc__timer_t *timer = (isc__timer_t *)timer0; + const isc_time_t *expires, const isc_interval_t *interval, + bool purge) { + isc__timer_t *timer; isc_time_t now; isc__timermgr_t *manager; isc_result_t result; @@ -366,14 +369,17 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type, * are purged from its task's event queue. */ - REQUIRE(VALID_TIMER(timer)); + REQUIRE(VALID_TIMER(timer0)); + timer = (isc__timer_t *)timer0; manager = timer->manager; REQUIRE(VALID_MANAGER(manager)); - if (expires == NULL) + if (expires == NULL) { expires = isc_time_epoch; - if (interval == NULL) + } + if (interval == NULL) { interval = isc_interval_zero; + } REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(type != isc_timertype_limited || @@ -396,12 +402,11 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type, LOCK(&manager->lock); LOCK(&timer->lock); - if (purge) - (void)isc_task_purgerange(timer->task, - timer, + if (purge) { + (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT, - ISC_TIMEREVENT_LASTEVENT, - NULL); + ISC_TIMEREVENT_LASTEVENT, NULL); + } timer->type = type; timer->expires = *expires; timer->interval = *interval; @@ -416,8 +421,9 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type, if (type == isc_timertype_inactive) { deschedule(timer); result = ISC_R_SUCCESS; - } else + } else { result = schedule(timer, &now, true); + } } UNLOCK(&timer->lock); @@ -428,10 +434,11 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type, isc_timertype_t isc_timer_gettype(isc_timer_t *timer0) { - isc__timer_t *timer = (isc__timer_t *)timer0; + isc__timer_t *timer; isc_timertype_t t; - REQUIRE(VALID_TIMER(timer)); + REQUIRE(VALID_TIMER(timer0)); + timer = (isc__timer_t *)timer0; LOCK(&timer->lock); t = timer->type; @@ -442,7 +449,7 @@ isc_timer_gettype(isc_timer_t *timer0) { isc_result_t isc_timer_touch(isc_timer_t *timer0) { - isc__timer_t *timer = (isc__timer_t *)timer0; + isc__timer_t *timer; isc_result_t result; isc_time_t now; @@ -450,7 +457,8 @@ isc_timer_touch(isc_timer_t *timer0) { * Set the last-touched time of 'timer' to the current time. */ - REQUIRE(VALID_TIMER(timer)); + REQUIRE(VALID_TIMER(timer0)); + timer = (isc__timer_t *)timer0; LOCK(&timer->lock); @@ -473,18 +481,16 @@ isc_timer_touch(isc_timer_t *timer0) { void isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) { - isc__timer_t *timer = (isc__timer_t *)timer0; + isc__timer_t *timer; /* * Attach *timerp to timer. */ - REQUIRE(VALID_TIMER(timer)); + REQUIRE(VALID_TIMER(timer0)); + timer = (isc__timer_t *)timer0; REQUIRE(timerp != NULL && *timerp == NULL); - - LOCK(&timer->lock); - timer->references++; - UNLOCK(&timer->lock); + isc_refcount_increment(&timer->references); *timerp = (isc_timer_t *)timer; } @@ -492,7 +498,6 @@ isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) { void isc_timer_detach(isc_timer_t **timerp) { isc__timer_t *timer; - bool free_timer = false; /* * Detach *timerp from its timer. @@ -502,15 +507,9 @@ isc_timer_detach(isc_timer_t **timerp) { timer = (isc__timer_t *)*timerp; REQUIRE(VALID_TIMER(timer)); - LOCK(&timer->lock); - REQUIRE(timer->references > 0); - timer->references--; - if (timer->references == 0) - free_timer = true; - UNLOCK(&timer->lock); - - if (free_timer) + if (isc_refcount_decrement(&timer->references) == 1) { destroy(timer); + } *timerp = NULL; } @@ -549,8 +548,8 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { need_schedule = true; } } else if (!isc_time_isepoch(&timer->expires) && - isc_time_compare(now, - &timer->expires) >= 0) { + isc_time_compare(now, &timer->expires) >= 0) + { type = ISC_TIMEREVENT_LIFE; post_event = true; need_schedule = false; @@ -559,8 +558,7 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { LOCK(&timer->lock); if (!isc_time_isepoch(&timer->idle) && - isc_time_compare(now, - &timer->idle) >= 0) { + isc_time_compare(now, &timer->idle) >= 0) { idle = true; } UNLOCK(&timer->lock); @@ -584,20 +582,21 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { /* * XXX We could preallocate this event. */ - event = (isc_timerevent_t *)isc_event_allocate(manager->mctx, - timer, - type, - timer->action, - timer->arg, - sizeof(*event)); + event = (isc_timerevent_t *)isc_event_allocate( + manager->mctx, timer, type, + timer->action, timer->arg, + sizeof(*event)); if (event != NULL) { event->due = timer->due; isc_task_send(timer->task, ISC_EVENT_PTR(&event)); - } else - UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", - "couldn't allocate event"); + } else { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "%s", + "couldn't allocate " + "event"); + } } timer->index = 0; @@ -606,11 +605,13 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { if (need_schedule) { result = schedule(timer, now, false); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %u", - "couldn't schedule timer", + "couldn't schedule " + "timer", result); + } } } else { manager->due = timer->due; @@ -620,10 +621,10 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { } static isc_threadresult_t -#ifdef _WIN32 /* XXXDCL */ -WINAPI -#endif -run(void *uap) { +#ifdef _WIN32 /* XXXDCL */ + WINAPI +#endif /* ifdef _WIN32 */ + run(void *uap) { isc__timermgr_t *manager = uap; isc_time_t now; isc_result_t result; @@ -638,7 +639,8 @@ run(void *uap) { if (manager->nscheduled > 0) { XTRACETIME2("waituntil", manager->due, now); - result = WAITUNTIL(&manager->wakeup, &manager->lock, &manager->due); + result = WAITUNTIL(&manager->wakeup, &manager->lock, + &manager->due); INSIST(result == ISC_R_SUCCESS || result == ISC_R_TIMEDOUT); } else { @@ -651,7 +653,7 @@ run(void *uap) { #ifdef OPENSSL_LEAKS ERR_remove_state(0); -#endif +#endif /* ifdef OPENSSL_LEAKS */ return ((isc_threadresult_t)0); } @@ -665,8 +667,9 @@ sooner(void *v1, void *v2) { REQUIRE(VALID_TIMER(t1)); REQUIRE(VALID_TIMER(t2)); - if (isc_time_compare(&t1->due, &t2->due) < 0) + if (isc_time_compare(&t1->due, &t2->due) < 0) { return (true); + } return (false); } @@ -674,8 +677,8 @@ static void set_index(void *what, unsigned int index) { isc__timer_t *timer; + REQUIRE(VALID_TIMER(what)); timer = what; - REQUIRE(VALID_TIMER(timer)); timer->index = index; } @@ -692,8 +695,6 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { REQUIRE(managerp != NULL && *managerp == NULL); manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); manager->common.impmagic = TIMER_MANAGER_MAGIC; manager->common.magic = ISCAPI_TIMERMGR_MAGIC; @@ -712,17 +713,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc_mutex_init(&manager->lock); isc_mem_attach(mctx, &manager->mctx); isc_condition_init(&manager->wakeup); - if (isc_thread_create(run, manager, &manager->thread) != - ISC_R_SUCCESS) { - isc_mem_detach(&manager->mctx); - (void)isc_condition_destroy(&manager->wakeup); - isc_mutex_destroy(&manager->lock); - isc_heap_destroy(&manager->heap); - isc_mem_put(mctx, manager, sizeof(*manager)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", - "isc_thread_create() failed"); - return (ISC_R_UNEXPECTED); - } + isc_thread_create(run, manager, &manager->thread); isc_thread_setname(manager->thread, "isc-timer"); *managerp = (isc_timermgr_t *)manager; @@ -732,9 +723,10 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { void isc_timermgr_poke(isc_timermgr_t *manager0) { - isc__timermgr_t *manager = (isc__timermgr_t *)manager0; + isc__timermgr_t *manager; - REQUIRE(VALID_MANAGER(manager)); + REQUIRE(VALID_MANAGER(manager0)); + manager = (isc__timermgr_t *)manager0; SIGNAL(&manager->wakeup); } @@ -742,7 +734,6 @@ isc_timermgr_poke(isc_timermgr_t *manager0) { void isc_timermgr_destroy(isc_timermgr_t **managerp) { isc__timermgr_t *manager; - isc_mem_t *mctx; /* * Destroy a timer manager. @@ -765,9 +756,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { /* * Wait for thread to exit. */ - if (isc_thread_join(manager->thread, NULL) != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", - "isc_thread_join() failed"); + isc_thread_join(manager->thread, NULL); /* * Clean up. @@ -777,24 +766,16 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_heap_destroy(&manager->heap); manager->common.impmagic = 0; manager->common.magic = 0; - mctx = manager->mctx; - isc_mem_put(mctx, manager, sizeof(*manager)); - isc_mem_detach(&mctx); + isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager)); *managerp = NULL; - } isc_result_t -isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - isc_timermgr_t **managerp) -{ +isc_timermgr_createinctx(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc_result_t result; result = isc_timermgr_create(mctx, managerp); - if (result == ISC_R_SUCCESS) - isc_appctx_settimermgr(actx, *managerp); - return (result); } diff --git a/lib/isc/timer_p.h b/lib/isc/timer_p.h index 9a376751..ac11582e 100644 --- a/lib/isc/timer_p.h +++ b/lib/isc/timer_p.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. diff --git a/lib/isc/tm.c b/lib/isc/tm.c index 338157ad..5309b146 100644 --- a/lib/isc/tm.c +++ b/lib/isc/tm.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -37,13 +37,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <config.h> - +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> -#include <ctype.h> #include <isc/tm.h> #include <isc/util.h> @@ -59,32 +57,30 @@ * We do not implement alternate representations. However, we always * check whether a given modifier is allowed for a certain conversion. */ -#define ALT_E 0x01 -#define ALT_O 0x02 -#define LEGAL_ALT(x) { if ((alt_format & ~(x)) != 0) return (0); } +#define ALT_E 0x01 +#define ALT_O 0x02 +#define LEGAL_ALT(x) \ + { \ + if ((alt_format & ~(x)) != 0) \ + return ((0)); \ + } #ifndef TM_YEAR_BASE #define TM_YEAR_BASE 1900 -#endif +#endif /* ifndef TM_YEAR_BASE */ -static const char *day[7] = { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday" -}; +static const char *day[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" }; static const char *abday[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char *mon[12] = { - "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" -}; -static const char *abmon[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; -static const char *am_pm[2] = { - "AM", "PM" + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" }; +static const char *abmon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static const char *am_pm[2] = { "AM", "PM" }; static int conv_num(const char **buf, int *dest, int llim, int ulim) { @@ -93,18 +89,20 @@ conv_num(const char **buf, int *dest, int llim, int ulim) { /* The limit also determines the number of valid digits. */ int rulim = ulim; - if (**buf < '0' || **buf > '9') + if (**buf < '0' || **buf > '9') { return (0); + } do { result *= 10; result += *(*buf)++ - '0'; rulim /= 10; - } while ((result * 10 <= ulim) && - rulim && **buf >= '0' && **buf <= '9'); + } while ((result * 10 <= ulim) && rulim && **buf >= '0' && + **buf <= '9'); - if (result < llim || result > ulim) + if (result < llim || result > ulim) { return (0); + } *dest = result; return (1); @@ -116,22 +114,21 @@ isc_tm_timegm(struct tm *tm) { int i, yday = 0, leapday; int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; - leapday = ((((tm->tm_year + 1900 ) % 4) == 0 && - ((tm->tm_year + 1900 ) % 100) != 0) || - ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0; + leapday = ((((tm->tm_year + 1900) % 4) == 0 && + ((tm->tm_year + 1900) % 100) != 0) || + ((tm->tm_year + 1900) % 400) == 0) + ? 1 + : 0; mdays[1] += leapday; yday = tm->tm_mday - 1; - for (i = 1; i <= tm->tm_mon; i++) + for (i = 1; i <= tm->tm_mon; i++) { yday += mdays[i - 1]; - ret = tm->tm_sec + - (60 * tm->tm_min) + - (3600 * tm->tm_hour) + - (86400 * (yday + - ((tm->tm_year - 70) * 365) + - ((tm->tm_year - 69) / 4) - - ((tm->tm_year - 1) / 100) + - ((tm->tm_year + 299) / 400))); + } + ret = tm->tm_sec + (60 * tm->tm_min) + (3600 * tm->tm_hour) + + (86400 * + (yday + ((tm->tm_year - 70) * 365) + ((tm->tm_year - 69) / 4) - + ((tm->tm_year - 1) / 100) + ((tm->tm_year + 299) / 400))); return (ret); } @@ -155,35 +152,38 @@ isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm) { alt_format = 0; /* Eat up white-space. */ - if (isspace((unsigned char) c)) { - while (isspace((unsigned char) *bp)) + if (isspace((unsigned char)c)) { + while (isspace((unsigned char)*bp)) { bp++; + } fmt++; continue; } - if ((c = *fmt++) != '%') + if ((c = *fmt++) != '%') { goto literal; + } - -again: switch (c = *fmt++) { - case '%': /* "%%" is converted to "%". */ -literal: - if (c != *bp++) + again: + switch (c = *fmt++) { + case '%': /* "%%" is converted to "%". */ + literal: + if (c != *bp++) { return (0); + } break; /* * "Alternative" modifiers. Just set the appropriate flag * and start over again. */ - case 'E': /* "%E?" alternative conversion modifier. */ + case 'E': /* "%E?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_E; goto again; - case 'O': /* "%O?" alternative conversion modifier. */ + case 'O': /* "%O?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_O; goto again; @@ -191,102 +191,116 @@ literal: /* * "Complex" conversion rules, implemented through recursion. */ - case 'c': /* Date and time, using the locale's format. */ + case 'c': /* Date and time, using the locale's format. */ LEGAL_ALT(ALT_E); - if (!(bp = isc_tm_strptime(bp, "%x %X", tm))) + if (!(bp = isc_tm_strptime(bp, "%x %X", tm))) { return (0); + } break; - case 'D': /* The date as "%m/%d/%y". */ + case 'D': /* The date as "%m/%d/%y". */ LEGAL_ALT(0); - if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) + if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) { return (0); + } break; - case 'R': /* The time as "%H:%M". */ + case 'R': /* The time as "%H:%M". */ LEGAL_ALT(0); - if (!(bp = isc_tm_strptime(bp, "%H:%M", tm))) + if (!(bp = isc_tm_strptime(bp, "%H:%M", tm))) { return (0); + } break; - case 'r': /* The time in 12-hour clock representation. */ + case 'r': /* The time in 12-hour clock representation. */ LEGAL_ALT(0); - if (!(bp = isc_tm_strptime(bp, "%I:%M:%S %p", tm))) + if (!(bp = isc_tm_strptime(bp, "%I:%M:%S %p", tm))) { return (0); + } break; - case 'T': /* The time as "%H:%M:%S". */ + case 'T': /* The time as "%H:%M:%S". */ LEGAL_ALT(0); - if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) + if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) { return (0); + } break; - case 'X': /* The time, using the locale's format. */ + case 'X': /* The time, using the locale's format. */ LEGAL_ALT(ALT_E); - if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) + if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) { return (0); + } break; - case 'x': /* The date, using the locale's format. */ + case 'x': /* The date, using the locale's format. */ LEGAL_ALT(ALT_E); - if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) + if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) { return (0); + } break; /* * "Elementary" conversion rules. */ - case 'A': /* The day of week, using the locale's form. */ + case 'A': /* The day of week, using the locale's form. */ case 'a': LEGAL_ALT(0); for (i = 0; i < 7; i++) { /* Full name. */ len = strlen(day[i]); - if (strncasecmp(day[i], bp, len) == 0) + if (strncasecmp(day[i], bp, len) == 0) { break; + } /* Abbreviated name. */ len = strlen(abday[i]); - if (strncasecmp(abday[i], bp, len) == 0) + if (strncasecmp(abday[i], bp, len) == 0) { break; + } } /* Nothing matched. */ - if (i == 7) + if (i == 7) { return (0); + } tm->tm_wday = i; bp += len; break; - case 'B': /* The month, using the locale's form. */ + case 'B': /* The month, using the locale's form. */ case 'b': case 'h': LEGAL_ALT(0); for (i = 0; i < 12; i++) { /* Full name. */ len = strlen(mon[i]); - if (strncasecmp(mon[i], bp, len) == 0) + if (strncasecmp(mon[i], bp, len) == 0) { break; + } /* Abbreviated name. */ len = strlen(abmon[i]); - if (strncasecmp(abmon[i], bp, len) == 0) + if (strncasecmp(abmon[i], bp, len) == 0) { break; + } } /* Nothing matched. */ - if (i == 12) + if (i == 12) { return (0); + } tm->tm_mon = i; bp += len; break; - case 'C': /* The century number. */ + case 'C': /* The century number. */ LEGAL_ALT(ALT_E); - if (!(conv_num(&bp, &i, 0, 99))) + if (!(conv_num(&bp, &i, 0, 99))) { return (0); + } if (split_year) { tm->tm_year = (tm->tm_year % 100) + (i * 100); @@ -296,67 +310,77 @@ literal: } break; - case 'd': /* The day of month. */ + case 'd': /* The day of month. */ case 'e': LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_mday, 1, 31))) + if (!(conv_num(&bp, &tm->tm_mday, 1, 31))) { return (0); + } break; - case 'k': /* The hour (24-hour clock representation). */ + case 'k': /* The hour (24-hour clock representation). */ LEGAL_ALT(0); - /* FALLTHROUGH */ + /* FALLTHROUGH */ case 'H': LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_hour, 0, 23))) + if (!(conv_num(&bp, &tm->tm_hour, 0, 23))) { return (0); + } break; - case 'l': /* The hour (12-hour clock representation). */ + case 'l': /* The hour (12-hour clock representation). */ LEGAL_ALT(0); - /* FALLTHROUGH */ + /* FALLTHROUGH */ case 'I': LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_hour, 1, 12))) + if (!(conv_num(&bp, &tm->tm_hour, 1, 12))) { return (0); - if (tm->tm_hour == 12) + } + if (tm->tm_hour == 12) { tm->tm_hour = 0; + } break; - case 'j': /* The day of year. */ + case 'j': /* The day of year. */ LEGAL_ALT(0); - if (!(conv_num(&bp, &i, 1, 366))) + if (!(conv_num(&bp, &i, 1, 366))) { return (0); + } tm->tm_yday = i - 1; break; - case 'M': /* The minute. */ + case 'M': /* The minute. */ LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_min, 0, 59))) + if (!(conv_num(&bp, &tm->tm_min, 0, 59))) { return (0); + } break; - case 'm': /* The month. */ + case 'm': /* The month. */ LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &i, 1, 12))) + if (!(conv_num(&bp, &i, 1, 12))) { return (0); + } tm->tm_mon = i - 1; break; - case 'p': /* The locale's equivalent of AM/PM. */ + case 'p': /* The locale's equivalent of AM/PM. */ LEGAL_ALT(0); /* AM? */ if (strcasecmp(am_pm[0], bp) == 0) { - if (tm->tm_hour > 11) + if (tm->tm_hour > 11) { return (0); + } bp += strlen(am_pm[0]); break; } /* PM? */ - else if (strcasecmp(am_pm[1], bp) == 0) { - if (tm->tm_hour > 11) + else if (strcasecmp(am_pm[1], bp) == 0) + { + if (tm->tm_hour > 11) { return (0); + } tm->tm_hour += 12; bp += strlen(am_pm[1]); @@ -366,14 +390,15 @@ literal: /* Nothing matched. */ return (0); - case 'S': /* The seconds. */ + case 'S': /* The seconds. */ LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_sec, 0, 61))) + if (!(conv_num(&bp, &tm->tm_sec, 0, 61))) { return (0); + } break; - case 'U': /* The week of year, beginning on sunday. */ - case 'W': /* The week of year, beginning on monday. */ + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ LEGAL_ALT(ALT_O); /* * XXX This is bogus, as we can not assume any valid @@ -381,56 +406,59 @@ literal: * point to calculate a real value, so just check the * range for now. */ - if (!(conv_num(&bp, &i, 0, 53))) + if (!(conv_num(&bp, &i, 0, 53))) { return (0); - break; + } + break; - case 'w': /* The day of week, beginning on sunday. */ + case 'w': /* The day of week, beginning on sunday. */ LEGAL_ALT(ALT_O); - if (!(conv_num(&bp, &tm->tm_wday, 0, 6))) + if (!(conv_num(&bp, &tm->tm_wday, 0, 6))) { return (0); + } break; - case 'Y': /* The year. */ + case 'Y': /* The year. */ LEGAL_ALT(ALT_E); - if (!(conv_num(&bp, &i, 0, 9999))) + if (!(conv_num(&bp, &i, 0, 9999))) { return (0); + } tm->tm_year = i - TM_YEAR_BASE; break; - case 'y': /* The year within 100 years of the epoch. */ + case 'y': /* The year within 100 years of the epoch. */ LEGAL_ALT(ALT_E | ALT_O); - if (!(conv_num(&bp, &i, 0, 99))) + if (!(conv_num(&bp, &i, 0, 99))) { return (0); + } if (split_year) { tm->tm_year = ((tm->tm_year / 100) * 100) + i; break; } split_year = 1; - if (i <= 68) + if (i <= 68) { tm->tm_year = i + 2000 - TM_YEAR_BASE; - else + } else { tm->tm_year = i + 1900 - TM_YEAR_BASE; + } break; /* * Miscellaneous conversions. */ - case 'n': /* Any kind of white-space. */ + case 'n': /* Any kind of white-space. */ case 't': LEGAL_ALT(0); - while (isspace((unsigned char) *bp)) + while (isspace((unsigned char)*bp)) { bp++; + } break; - - default: /* Unknown/unsupported conversion. */ + default: /* Unknown/unsupported conversion. */ return (0); } - - } /* LINTED functional specification */ diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in index be05fc05..5fd4f65f 100644 --- a/lib/isc/unix/Makefile.in +++ b/lib/isc/unix/Makefile.in @@ -15,14 +15,17 @@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../pthreads/include \ -I../include \ -I${srcdir}/../include \ - -I${srcdir}/.. @OPENSSL_INCLUDES@ + -I${srcdir}/.. \ + ${OPENSSL_CFLAGS} \ + ${JSON_C_CFLAGS} \ + ${LIBXML2_CFLAGS} CDEFINES = CWARNINGS = # Alphabetically OBJS = pk11_api.@O@ \ - app.@O@ dir.@O@ errno.@O@ errno2result.@O@ \ + dir.@O@ errno.@O@ errno2result.@O@ \ file.@O@ fsaccess.@O@ interfaceiter.@O@ \ meminfo.@O@ \ net.@O@ os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \ @@ -30,7 +33,7 @@ OBJS = pk11_api.@O@ \ # Alphabetically SRCS = pk11_api.c \ - app.c dir.c errno.c errno2result.c \ + dir.c errno.c errno2result.c \ file.c fsaccess.c interfaceiter.c meminfo.c \ net.c os.c resource.c socket.c stdio.c stdtime.c \ syslog.c time.c diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c deleted file mode 100644 index 6b5756cf..00000000 --- a/lib/isc/unix/app.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include <config.h> - -#include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */ -#include <sys/types.h> - -#include <stdbool.h> -#include <stddef.h> -#include <inttypes.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <sys/time.h> -#ifdef HAVE_EPOLL -#include <sys/epoll.h> -#endif - -#include <isc/platform.h> -#include <isc/app.h> -#include <isc/condition.h> -#include <isc/mem.h> -#include <isc/mutex.h> -#include <isc/event.h> -#include <isc/platform.h> -#include <isc/strerr.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/time.h> -#include <isc/util.h> - -#include <pthread.h> - -/*% - * For BIND9 internal applications built with threads, we use a single app - * context and let multiple worker, I/O, timer threads do actual jobs. - * For other cases (including BIND9 built without threads) an app context acts - * as an event loop dispatching various events. - */ -static pthread_t blockedthread; -static bool is_running; - -/* - * The application context of this module. This implementation actually - * doesn't use it. (This may change in the future). - */ -#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') -#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) - -typedef struct isc__appctx { - isc_appctx_t common; - isc_mem_t *mctx; - isc_mutex_t lock; - isc_eventlist_t on_run; - bool shutdown_requested; - bool running; - - /*! - * We assume that 'want_shutdown' can be read and written atomically. - */ - bool want_shutdown; - /* - * We assume that 'want_reload' can be read and written atomically. - */ - bool want_reload; - - bool blocked; - - isc_taskmgr_t *taskmgr; - isc_socketmgr_t *socketmgr; - isc_timermgr_t *timermgr; - isc_mutex_t readylock; - isc_condition_t ready; -} isc__appctx_t; - -static isc__appctx_t isc_g_appctx; - -#ifndef HAVE_SIGWAIT -static void -exit_action(int arg) { - UNUSED(arg); - isc_g_appctx.want_shutdown = true; -} - -static void -reload_action(int arg) { - UNUSED(arg); - isc_g_appctx.want_reload = true; -} -#endif - -static isc_result_t -handle_signal(int sig, void (*handler)(int)) { - struct sigaction sa; - char strbuf[ISC_STRERRORSIZE]; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handler; - - if (sigfillset(&sa.sa_mask) != 0 || - sigaction(sig, &sa, NULL) < 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "handle_signal() %d setup: %s", - sig, strbuf); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_ctxstart(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - isc_result_t result; - int presult; - sigset_t sset; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_APPCTX(ctx)); - - /* - * Start an ISC library application. - */ - - isc_mutex_init(&ctx->readylock); - - isc_condition_init(&ctx->ready); - - isc_mutex_init(&ctx->lock); - - ISC_LIST_INIT(ctx->on_run); - - ctx->shutdown_requested = false; - ctx->running = false; - ctx->want_shutdown = false; - ctx->want_reload = false; - ctx->blocked = false; - -#ifndef HAVE_SIGWAIT - /* - * Install do-nothing handlers for SIGINT and SIGTERM. - * - * We install them now because BSDI 3.1 won't block - * the default actions, regardless of what we do with - * pthread_sigmask(). - */ - result = handle_signal(SIGINT, exit_action); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = handle_signal(SIGTERM, exit_action); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Always ignore SIGPIPE. - */ - result = handle_signal(SIGPIPE, SIG_IGN); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * On Solaris 2, delivery of a signal whose action is SIG_IGN - * will not cause sigwait() to return. We may have inherited - * unexpected actions for SIGHUP, SIGINT, and SIGTERM from our parent - * process (e.g, Solaris cron). Set an action of SIG_DFL to make - * sure sigwait() works as expected. Only do this for SIGTERM and - * SIGINT if we don't have sigwait(), since a different handler is - * installed above. - */ - result = handle_signal(SIGHUP, SIG_DFL); - if (result != ISC_R_SUCCESS) - goto cleanup; - -#ifdef HAVE_SIGWAIT - result = handle_signal(SIGTERM, SIG_DFL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = handle_signal(SIGINT, SIG_DFL); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Block SIGHUP, SIGINT, SIGTERM. - * - * If isc_app_start() is called from the main thread before any other - * threads have been created, then the pthread_sigmask() call below - * will result in all threads having SIGHUP, SIGINT and SIGTERM - * blocked by default, ensuring that only the thread that calls - * sigwait() for them will get those signals. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() sigsetops: %s", strbuf); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - presult = pthread_sigmask(SIG_BLOCK, &sset, NULL); - if (presult != 0) { - strerror_r(presult, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() pthread_sigmask: %s", - strbuf); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - return (ISC_R_SUCCESS); - - cleanup: - (void)isc_condition_destroy(&ctx->ready); - (void)isc_mutex_destroy(&ctx->readylock); - return (result); -} - -isc_result_t -isc_app_start(void) { - isc_g_appctx.common.impmagic = APPCTX_MAGIC; - isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC; - isc_g_appctx.mctx = NULL; - /* The remaining members will be initialized in ctxstart() */ - - return (isc_app_ctxstart((isc_appctx_t *)&isc_g_appctx)); -} - -isc_result_t -isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, - void *arg) -{ - return (isc_app_ctxonrun((isc_appctx_t *)&isc_g_appctx, mctx, - task, action, arg)); -} - -isc_result_t -isc_app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task, - isc_taskaction_t action, void *arg) -{ - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - isc_event_t *event; - isc_task_t *cloned_task = NULL; - isc_result_t result; - - LOCK(&ctx->lock); - - if (ctx->running) { - result = ISC_R_ALREADYRUNNING; - goto unlock; - } - - /* - * Note that we store the task to which we're going to send the event - * in the event's "sender" field. - */ - isc_task_attach(task, &cloned_task); - event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, - action, arg, sizeof(*event)); - if (event == NULL) { - isc_task_detach(&cloned_task); - result = ISC_R_NOMEMORY; - goto unlock; - } - - ISC_LIST_APPEND(ctx->on_run, event, ev_link); - - result = ISC_R_SUCCESS; - - unlock: - UNLOCK(&ctx->lock); - - return (result); -} - -isc_result_t -isc_app_ctxrun(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - int result; - isc_event_t *event, *next_event; - isc_task_t *task; - sigset_t sset; - char strbuf[ISC_STRERRORSIZE]; -#ifdef HAVE_SIGWAIT - int sig; -#endif /* HAVE_SIGWAIT */ - - REQUIRE(VALID_APPCTX(ctx)); - - LOCK(&ctx->lock); - - if (!ctx->running) { - ctx->running = true; - - /* - * Post any on-run events (in FIFO order). - */ - for (event = ISC_LIST_HEAD(ctx->on_run); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(ctx->on_run, event, ev_link); - task = event->ev_sender; - event->ev_sender = NULL; - isc_task_sendanddetach(&task, &event); - } - - } - - UNLOCK(&ctx->lock); - - /* - * BIND9 internal tools using multiple contexts do not - * rely on signal. - */ - if (isc_bind9 && ctx != &isc_g_appctx) - return (ISC_R_SUCCESS); - - /* - * There is no danger if isc_app_shutdown() is called before we - * wait for signals. Signals are blocked, so any such signal will - * simply be made pending and we will get it when we call - * sigwait(). - */ - while (!ctx->want_shutdown) { -#ifdef HAVE_SIGWAIT - if (isc_bind9) { - /* - * BIND9 internal; single context: - * Wait for SIGHUP, SIGINT, or SIGTERM. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } - - result = sigwait(&sset, &sig); - if (result == 0) { - if (sig == SIGINT || sig == SIGTERM) - ctx->want_shutdown = true; - else if (sig == SIGHUP) - ctx->want_reload = true; - } - - } else { - /* - * External, or BIND9 using multiple contexts: - * wait until woken up. - */ - LOCK(&ctx->readylock); - if (ctx->want_shutdown) { - /* shutdown() won the race. */ - UNLOCK(&ctx->readylock); - break; - } - if (!ctx->want_reload) - WAIT(&ctx->ready, &ctx->readylock); - UNLOCK(&ctx->readylock); - } -#else /* Don't have sigwait(). */ - if (isc_bind9) { - /* - * BIND9 internal; single context: - * Install a signal handler for SIGHUP, then wait for - * all signals. - */ - result = handle_signal(SIGHUP, reload_action); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - if (sigemptyset(&sset) != 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } -#ifdef HAVE_GPERFTOOLS_PROFILER - if (sigaddset(&sset, SIGALRM) != 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } -#endif - (void)sigsuspend(&sset); - } else { - /* - * External, or BIND9 using multiple contexts: - * wait until woken up. - */ - LOCK(&ctx->readylock); - if (ctx->want_shutdown) { - /* shutdown() won the race. */ - UNLOCK(&ctx->readylock); - break; - } - if (!ctx->want_reload) - WAIT(&ctx->ready, &ctx->readylock); - UNLOCK(&ctx->readylock); - } -#endif /* HAVE_SIGWAIT */ - - if (ctx->want_reload) { - ctx->want_reload = false; - return (ISC_R_RELOAD); - } - - if (ctx->want_shutdown && ctx->blocked) - exit(1); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_run(void) { - isc_result_t result; - - is_running = true; - result = isc_app_ctxrun((isc_appctx_t *)&isc_g_appctx); - is_running = false; - - return (result); -} - -bool -isc_app_isrunning() { - return (is_running); -} - -isc_result_t -isc_app_ctxshutdown(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - bool want_kill = true; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_APPCTX(ctx)); - - LOCK(&ctx->lock); - - REQUIRE(ctx->running); - - if (ctx->shutdown_requested) - want_kill = false; - else - ctx->shutdown_requested = true; - - UNLOCK(&ctx->lock); - - if (want_kill) { - if (isc_bind9 && ctx != &isc_g_appctx) - /* BIND9 internal, but using multiple contexts */ - ctx->want_shutdown = true; - else { - if (isc_bind9) { - /* BIND9 internal, single context */ - if (kill(getpid(), SIGTERM) < 0) { - strerror_r(errno, - strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_shutdown() " - "kill: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - } - else { - /* External, multiple contexts */ - LOCK(&ctx->readylock); - ctx->want_shutdown = true; - UNLOCK(&ctx->readylock); - SIGNAL(&ctx->ready); - } - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_shutdown(void) { - return (isc_app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); -} - -isc_result_t -isc_app_ctxsuspend(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - bool want_kill = true; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_APPCTX(ctx)); - - LOCK(&ctx->lock); - - REQUIRE(ctx->running); - - /* - * Don't send the reload signal if we're shutting down. - */ - if (ctx->shutdown_requested) - want_kill = false; - - UNLOCK(&ctx->lock); - - if (want_kill) { - if (isc_bind9 && ctx != &isc_g_appctx) - /* BIND9 internal, but using multiple contexts */ - ctx->want_reload = true; - else { - ctx->want_reload = true; - if (isc_bind9) { - /* BIND9 internal, single context */ - if (kill(getpid(), SIGHUP) < 0) { - strerror_r(errno, - strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_reload() " - "kill: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - } - else { - /* External, multiple contexts */ - LOCK(&ctx->readylock); - ctx->want_reload = true; - UNLOCK(&ctx->readylock); - SIGNAL(&ctx->ready); - } - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_reload(void) { - return (isc_app_ctxsuspend((isc_appctx_t *)&isc_g_appctx)); -} - -void -isc_app_ctxfinish(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - isc_mutex_destroy(&ctx->lock); -} - -void -isc_app_finish(void) { - isc_app_ctxfinish((isc_appctx_t *)&isc_g_appctx); -} - -void -isc_app_block(void) { - sigset_t sset; - REQUIRE(isc_g_appctx.running); - REQUIRE(!isc_g_appctx.blocked); - - isc_g_appctx.blocked = true; - blockedthread = pthread_self(); - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0); -} - -void -isc_app_unblock(void) { - sigset_t sset; - - REQUIRE(isc_g_appctx.running); - REQUIRE(isc_g_appctx.blocked); - - isc_g_appctx.blocked = false; - - REQUIRE(blockedthread == pthread_self()); - - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); -} - -isc_result_t -isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { - isc__appctx_t *ctx; - - REQUIRE(mctx != NULL); - REQUIRE(ctxp != NULL && *ctxp == NULL); - - ctx = isc_mem_get(mctx, sizeof(*ctx)); - if (ctx == NULL) - return (ISC_R_NOMEMORY); - - ctx->common.impmagic = APPCTX_MAGIC; - ctx->common.magic = ISCAPI_APPCTX_MAGIC; - - ctx->mctx = NULL; - isc_mem_attach(mctx, &ctx->mctx); - - ctx->taskmgr = NULL; - ctx->socketmgr = NULL; - ctx->timermgr = NULL; - - *ctxp = (isc_appctx_t *)ctx; - - return (ISC_R_SUCCESS); -} - -void -isc_appctx_destroy(isc_appctx_t **ctxp) { - isc__appctx_t *ctx; - - REQUIRE(ctxp != NULL); - ctx = (isc__appctx_t *)*ctxp; - REQUIRE(VALID_APPCTX(ctx)); - - isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); - - *ctxp = NULL; -} - -void -isc_appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->taskmgr = taskmgr; -} - -void -isc_appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->socketmgr = socketmgr; -} - -void -isc_appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->timermgr = timermgr; -} diff --git a/lib/isc/unix/dir.c b/lib/isc/unix/dir.c index 93298ed5..29e4bb79 100644 --- a/lib/isc/unix/dir.c +++ b/lib/isc/unix/dir.c @@ -3,22 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> - #include <ctype.h> #include <errno.h> +#include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> #include <isc/dir.h> @@ -30,8 +26,8 @@ #include "errno2result.h" -#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') -#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) +#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') +#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) void isc_dir_init(isc_dir_t *dir) { @@ -71,8 +67,9 @@ isc_dir_open(isc_dir_t *dir, const char *dirname) { * Append path separator, if needed, and "*". */ p = dir->dirname + strlen(dir->dirname); - if (dir->dirname < p && *(p - 1) != '/') + if (dir->dirname < p && *(p - 1) != '/') { *p++ = '/'; + } *p++ = '*'; *p = '\0'; @@ -90,7 +87,7 @@ isc_dir_open(isc_dir_t *dir, const char *dirname) { /*! * \brief Return previously retrieved file or get next one. - + * * Unix's dirent has * separate open and read functions, but the Win32 and DOS interfaces open * the dir stream and reads the first file in one operation. @@ -106,14 +103,16 @@ isc_dir_read(isc_dir_t *dir) { */ entry = readdir(dir->handle); - if (entry == NULL) + if (entry == NULL) { return (ISC_R_NOMORE); + } /* * Make sure that the space for the name is long enough. */ - if (sizeof(dir->entry.name) <= strlen(entry->d_name)) + if (sizeof(dir->entry.name) <= strlen(entry->d_name)) { return (ISC_R_UNEXPECTED); + } strlcpy(dir->entry.name, entry->d_name, sizeof(dir->entry.name)); @@ -130,10 +129,10 @@ isc_dir_read(isc_dir_t *dir) { */ void isc_dir_close(isc_dir_t *dir) { - REQUIRE(VALID_DIR(dir) && dir->handle != NULL); + REQUIRE(VALID_DIR(dir) && dir->handle != NULL); - (void)closedir(dir->handle); - dir->handle = NULL; + (void)closedir(dir->handle); + dir->handle = NULL; } /*! @@ -156,8 +155,9 @@ isc_dir_chdir(const char *dirname) { REQUIRE(dirname != NULL); - if (chdir(dirname) < 0) + if (chdir(dirname) < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); } @@ -166,7 +166,7 @@ isc_result_t isc_dir_chroot(const char *dirname) { #ifdef HAVE_CHROOT void *tmp; -#endif +#endif /* ifdef HAVE_CHROOT */ REQUIRE(dirname != NULL); @@ -178,16 +178,18 @@ isc_dir_chroot(const char *dirname) { * Do not report errors if it fails, we do not need any result now. */ tmp = getprotobyname("udp"); - if (tmp != NULL) - (void) getservbyname("domain", "udp"); + if (tmp != NULL) { + (void)getservbyname("domain", "udp"); + } - if (chroot(dirname) < 0 || chdir("/") < 0) + if (chroot(dirname) < 0 || chdir("/") < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); -#else +#else /* ifdef HAVE_CHROOT */ return (ISC_R_NOTIMPLEMENTED); -#endif +#endif /* ifdef HAVE_CHROOT */ } isc_result_t @@ -211,25 +213,28 @@ isc_dir_createunique(char *templet) { */ for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet; x--, pid /= 10) + { *x = pid % 10 + '0'; + } - x++; /* Set x to start of ex-Xs. */ + x++; /* Set x to start of ex-Xs. */ do { i = mkdir(templet, 0700); - if (i == 0 || errno != EEXIST) + if (i == 0 || errno != EEXIST) { break; + } /* * The BSD algorithm. */ p = x; while (*p != '\0') { - if (isdigit(*p & 0xff)) + if (isdigit(*p & 0xff)) { *p = 'a'; - else if (*p != 'z') + } else if (*p != 'z') { ++*p; - else { + } else { /* * Reset character and move to next. */ @@ -251,10 +256,11 @@ isc_dir_createunique(char *templet) { } } while (1); - if (i == -1) + if (i == -1) { result = isc__errno2result(errno); - else + } else { result = ISC_R_SUCCESS; + } return (result); } diff --git a/lib/isc/unix/errno.c b/lib/isc/unix/errno.c index a2445f3e..7d52944e 100644 --- a/lib/isc/unix/errno.c +++ b/lib/isc/unix/errno.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,6 @@ /*! \file */ -#include <config.h> - #include <isc/errno.h> #include <isc/util.h> diff --git a/lib/isc/unix/errno2result.c b/lib/isc/unix/errno2result.c index 35689e47..b7866f4b 100644 --- a/lib/isc/unix/errno2result.c +++ b/lib/isc/unix/errno2result.c @@ -3,17 +3,15 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - +#include "errno2result.h" #include <stdbool.h> #include <isc/platform.h> @@ -22,8 +20,6 @@ #include <isc/string.h> #include <isc/util.h> -#include "errno2result.h" - /*% * Convert a POSIX errno value into an isc_result_t. The * list of supported errno values is not complete; new users @@ -31,15 +27,14 @@ * not already there. */ isc_result_t -isc___errno2result(int posixerrno, bool dolog, - const char *file, unsigned int line) -{ +isc___errno2result(int posixerrno, bool dolog, const char *file, + unsigned int line) { char strbuf[ISC_STRERRORSIZE]; switch (posixerrno) { case ENOTDIR: case ELOOP: - case EINVAL: /* XXX sometimes this is not for files */ + case EINVAL: /* XXX sometimes this is not for files */ case ENAMETOOLONG: case EBADF: return (ISC_R_INVALIDFILE); @@ -60,57 +55,57 @@ isc___errno2result(int posixerrno, bool dolog, #ifdef EDQUOT case EDQUOT: return (ISC_R_DISCQUOTA); -#endif +#endif /* ifdef EDQUOT */ case ENOSPC: return (ISC_R_DISCFULL); #ifdef EOVERFLOW case EOVERFLOW: return (ISC_R_RANGE); -#endif +#endif /* ifdef EOVERFLOW */ case EPIPE: #ifdef ECONNRESET case ECONNRESET: -#endif +#endif /* ifdef ECONNRESET */ #ifdef ECONNABORTED case ECONNABORTED: -#endif +#endif /* ifdef ECONNABORTED */ return (ISC_R_CONNECTIONRESET); #ifdef ENOTCONN case ENOTCONN: return (ISC_R_NOTCONNECTED); -#endif +#endif /* ifdef ENOTCONN */ #ifdef ETIMEDOUT case ETIMEDOUT: return (ISC_R_TIMEDOUT); -#endif +#endif /* ifdef ETIMEDOUT */ #ifdef ENOBUFS case ENOBUFS: return (ISC_R_NORESOURCES); -#endif +#endif /* ifdef ENOBUFS */ #ifdef EAFNOSUPPORT case EAFNOSUPPORT: return (ISC_R_FAMILYNOSUPPORT); -#endif +#endif /* ifdef EAFNOSUPPORT */ #ifdef ENETDOWN case ENETDOWN: return (ISC_R_NETDOWN); -#endif +#endif /* ifdef ENETDOWN */ #ifdef EHOSTDOWN case EHOSTDOWN: return (ISC_R_HOSTDOWN); -#endif +#endif /* ifdef EHOSTDOWN */ #ifdef ENETUNREACH case ENETUNREACH: return (ISC_R_NETUNREACH); -#endif +#endif /* ifdef ENETUNREACH */ #ifdef EHOSTUNREACH case EHOSTUNREACH: return (ISC_R_HOSTUNREACH); -#endif +#endif /* ifdef EHOSTUNREACH */ #ifdef EADDRINUSE case EADDRINUSE: return (ISC_R_ADDRINUSE); -#endif +#endif /* ifdef EADDRINUSE */ case EADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case ECONNREFUSED: @@ -118,7 +113,8 @@ isc___errno2result(int posixerrno, bool dolog, default: if (dolog) { strerror_r(posixerrno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(file, line, "unable to convert errno " + UNEXPECTED_ERROR(file, line, + "unable to convert errno " "to isc_result: %d: %s", posixerrno, strbuf); } diff --git a/lib/isc/unix/errno2result.h b/lib/isc/unix/errno2result.h index 7733ab33..6a7942c5 100644 --- a/lib/isc/unix/errno2result.h +++ b/lib/isc/unix/errno2result.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -16,7 +16,7 @@ /* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */ -#include <errno.h> /* Provides errno. */ +#include <errno.h> /* Provides errno. */ #include <stdbool.h> #include <isc/lang.h> @@ -27,8 +27,8 @@ ISC_LANG_BEGINDECLS #define isc__errno2result(x) isc___errno2result(x, true, __FILE__, __LINE__) isc_result_t -isc___errno2result(int posixerrno, bool dolog, - const char *file, unsigned int line); +isc___errno2result(int posixerrno, bool dolog, const char *file, + unsigned int line); ISC_LANG_ENDDECLS diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c index 3b0c5632..b3cf4553 100644 --- a/lib/isc/unix/file.c +++ b/lib/isc/unix/file.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -38,33 +38,29 @@ * SUCH DAMAGE. */ - /*! \file */ -#include <config.h> - #include <errno.h> #include <fcntl.h> -#include <limits.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <stdlib.h> -#include <time.h> /* Required for utimes on some platforms. */ -#include <unistd.h> /* Required for mkstemp on NetBSD. */ - - #include <sys/stat.h> #include <sys/time.h> +#include <time.h> /* Required for utimes on some platforms. */ +#include <unistd.h> /* Required for mkstemp on NetBSD. */ #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> -#endif +#endif /* ifdef HAVE_SYS_MMAN_H */ #include <isc/dir.h> #include <isc/file.h> #include <isc/log.h> #include <isc/md.h> #include <isc/mem.h> +#include <isc/platform.h> #include <isc/print.h> #include <isc/random.h> #include <isc/string.h> @@ -88,8 +84,9 @@ file_stats(const char *file, struct stat *stats) { REQUIRE(file != NULL); REQUIRE(stats != NULL); - if (stat(file, stats) != 0) + if (stat(file, stats) != 0) { result = isc__errno2result(errno); + } return (result); } @@ -100,8 +97,9 @@ fd_stats(int fd, struct stat *stats) { REQUIRE(stats != NULL); - if (fstat(fd, stats) != 0) + if (fstat(fd, stats) != 0) { result = isc__errno2result(errno); + } return (result); } @@ -115,8 +113,9 @@ isc_file_getsizefd(int fd, off_t *size) { result = fd_stats(fd, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *size = stats.st_size; + } return (result); } @@ -129,8 +128,9 @@ isc_file_mode(const char *file, mode_t *modep) { REQUIRE(modep != NULL); result = file_stats(file, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *modep = (stats.st_mode & 07777); + } return (result); } @@ -145,12 +145,13 @@ isc_file_getmodtime(const char *file, isc_time_t *modtime) { result = file_stats(file, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { #if defined(HAVE_STAT_NSEC) isc_time_set(modtime, stats.st_mtime, stats.st_mtim.tv_nsec); -#else +#else /* if defined(HAVE_STAT_NSEC) */ isc_time_set(modtime, stats.st_mtime, 0); -#endif +#endif /* if defined(HAVE_STAT_NSEC) */ + } return (result); } @@ -165,8 +166,9 @@ isc_file_getsize(const char *file, off_t *size) { result = file_stats(file, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *size = stats.st_size; + } return (result); } @@ -193,8 +195,9 @@ isc_file_settime(const char *file, isc_time_t *when) { * Here is the real check for the high bit being set. */ if ((times[0].tv_sec & - (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0) + (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0) { return (ISC_R_RANGE); + } /* * isc_time_nanoseconds guarantees a value that divided by 1000 will @@ -203,8 +206,9 @@ isc_file_settime(const char *file, isc_time_t *when) { times[0].tv_usec = times[1].tv_usec = (int32_t)(isc_time_nanoseconds(when) / 1000); - if (utimes(file, times) < 0) + if (utimes(file, times) < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); } @@ -219,33 +223,36 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen) { isc_result_t isc_file_template(const char *path, const char *templet, char *buf, - size_t buflen) -{ + size_t buflen) { const char *s; REQUIRE(templet != NULL); REQUIRE(buf != NULL); - if (path == NULL) + if (path == NULL) { path = ""; + } s = strrchr(templet, '/'); - if (s != NULL) + if (s != NULL) { templet = s + 1; + } s = strrchr(path, '/'); if (s != NULL) { size_t prefixlen = s - path + 1; - if ((prefixlen + strlen(templet) + 1) > buflen) + if ((prefixlen + strlen(templet) + 1) > buflen) { return (ISC_R_NOSPACE); + } /* Copy 'prefixlen' bytes and NUL terminate. */ strlcpy(buf, path, ISC_MIN(prefixlen + 1, buflen)); strlcat(buf, templet, buflen); } else { - if ((strlen(templet) + 1) > buflen) + if ((strlen(templet) + 1) > buflen) { return (ISC_R_NOSPACE); + } strlcpy(buf, templet, buflen); } @@ -253,8 +260,8 @@ isc_file_template(const char *path, const char *templet, char *buf, return (ISC_R_SUCCESS); } -static const char alphnum[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +static const char alphnum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" + "wxyz0123456789"; isc_result_t isc_file_renameunique(const char *file, char *templet) { @@ -265,10 +272,12 @@ isc_file_renameunique(const char *file, char *templet) { REQUIRE(templet != NULL); cp = templet; - while (*cp != '\0') + while (*cp != '\0') { cp++; - if (cp == templet) + } + if (cp == templet) { return (ISC_R_FAILURE); + } x = cp--; while (cp >= templet && *cp == 'X') { @@ -276,36 +285,40 @@ isc_file_renameunique(const char *file, char *templet) { x = cp--; } while (link(file, templet) == -1) { - if (errno != EEXIST) + if (errno != EEXIST) { return (isc__errno2result(errno)); + } for (cp = x;;) { const char *t; - if (*cp == '\0') + if (*cp == '\0') { return (ISC_R_FAILURE); + } t = strchr(alphnum, *cp); - if (t == NULL || *++t == '\0') + if (t == NULL || *++t == '\0') { *cp++ = alphnum[0]; - else { + } else { *cp = *t; break; } } } - if (unlink(file) < 0) - if (errno != ENOENT) + if (unlink(file) < 0) { + if (errno != ENOENT) { return (isc__errno2result(errno)); + } + } return (ISC_R_SUCCESS); } isc_result_t isc_file_openunique(char *templet, FILE **fp) { - int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + int mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_openuniqueprivate(char *templet, FILE **fp) { - int mode = S_IWUSR|S_IRUSR; + int mode = S_IWUSR | S_IRUSR; return (isc_file_openuniquemode(templet, mode, fp)); } @@ -321,10 +334,12 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { REQUIRE(fp != NULL && *fp == NULL); cp = templet; - while (*cp != '\0') + while (*cp != '\0') { cp++; - if (cp == templet) + } + if (cp == templet) { return (ISC_R_FAILURE); + } x = cp--; while (cp >= templet && *cp == 'X') { @@ -332,18 +347,19 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { x = cp--; } - - while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) { - if (errno != EEXIST) + while ((fd = open(templet, O_RDWR | O_CREAT | O_EXCL, mode)) == -1) { + if (errno != EEXIST) { return (isc__errno2result(errno)); + } for (cp = x;;) { char *t; - if (*cp == '\0') + if (*cp == '\0') { return (ISC_R_FAILURE); + } t = strchr(alphnum, *cp); - if (t == NULL || *++t == '\0') + if (t == NULL || *++t == '\0') { *cp++ = alphnum[0]; - else { + } else { *cp = *t; break; } @@ -358,21 +374,22 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { "remove '%s': failed", templet); } (void)close(fd); - } else + } else { *fp = f; + } return (result); } isc_result_t isc_file_bopenunique(char *templet, FILE **fp) { - int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + int mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_bopenuniqueprivate(char *templet, FILE **fp) { - int mode = S_IWUSR|S_IRUSR; + int mode = S_IWUSR | S_IRUSR; return (isc_file_openuniquemode(templet, mode, fp)); } @@ -388,10 +405,11 @@ isc_file_remove(const char *filename) { REQUIRE(filename != NULL); r = unlink(filename); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -402,10 +420,11 @@ isc_file_rename(const char *oldname, const char *newname) { REQUIRE(newname != NULL); r = rename(oldname, newname); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } bool @@ -423,15 +442,17 @@ isc_file_isplainfile(const char *filename) { * This function returns success if filename is a plain file. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((stat(filename, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((stat(filename, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISREG(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISREG(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } isc_result_t @@ -440,15 +461,17 @@ isc_file_isplainfilefd(int fd) { * This function returns success if filename is a plain file. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((fstat(fd, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((fstat(fd, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISREG(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISREG(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } isc_result_t @@ -458,18 +481,19 @@ isc_file_isdirectory(const char *filename) { * directory. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((stat(filename, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((stat(filename, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISDIR(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISDIR(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } - bool isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); @@ -485,10 +509,12 @@ isc_file_iscurrentdir(const char *filename) { bool isc_file_ischdiridempotent(const char *filename) { REQUIRE(filename != NULL); - if (isc_file_isabsolute(filename)) + if (isc_file_isabsolute(filename)) { return (true); - if (isc_file_iscurrentdir(filename)) + } + if (isc_file_iscurrentdir(filename)) { return (true); + } return (false); } @@ -499,8 +525,9 @@ isc_file_basename(const char *filename) { REQUIRE(filename != NULL); s = strrchr(filename, '/'); - if (s == NULL) + if (s == NULL) { return (filename); + } return (s + 1); } @@ -516,8 +543,9 @@ isc_file_progname(const char *filename, char *buf, size_t buflen) { base = isc_file_basename(filename); len = strlen(base) + 1; - if (len > buflen) + if (len > buflen) { return (ISC_R_NOSPACE); + } memmove(buf, base, len); return (ISC_R_SUCCESS); @@ -560,10 +588,12 @@ isc_result_t isc_file_absolutepath(const char *filename, char *path, size_t pathlen) { isc_result_t result; result = dir_current(path, pathlen); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); - if (strlen(path) + strlen(filename) + 1 > pathlen) + } + if (strlen(path) + strlen(filename) + 1 > pathlen) { return (ISC_R_NOSPACE); + } strlcat(path, filename, pathlen); return (ISC_R_SUCCESS); } @@ -572,8 +602,9 @@ isc_result_t isc_file_truncate(const char *filename, isc_offset_t size) { isc_result_t result = ISC_R_SUCCESS; - if (truncate(filename, size) < 0) + if (truncate(filename, size) < 0) { result = isc__errno2result(errno); + } return (result); } @@ -590,17 +621,20 @@ isc_file_safecreate(const char *filename, FILE **fp) { result = file_stats(filename, &sb); if (result == ISC_R_SUCCESS) { - if ((sb.st_mode & S_IFREG) == 0) + if ((sb.st_mode & S_IFREG) == 0) { return (ISC_R_INVALIDFILE); + } flags = O_WRONLY | O_TRUNC; } else if (result == ISC_R_FILENOTFOUND) { flags = O_WRONLY | O_CREAT | O_EXCL; - } else + } else { return (result); + } fd = open(filename, flags, S_IRUSR | S_IWUSR); - if (fd == -1) + if (fd == -1) { return (isc__errno2result(errno)); + } f = fdopen(fd, "w"); if (f == NULL) { @@ -615,13 +649,13 @@ isc_file_safecreate(const char *filename, FILE **fp) { isc_result_t isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, - char const **bname) -{ + char const **bname) { char *dir; const char *file, *slash; - if (path == NULL) + if (path == NULL) { return (ISC_R_INVALIDFILE); + } slash = strrchr(path, '/'); @@ -631,15 +665,15 @@ isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, } else if (slash != NULL) { file = ++slash; dir = isc_mem_allocate(mctx, slash - path); - if (dir != NULL) - strlcpy(dir, path, slash - path); + strlcpy(dir, path, slash - path); } else { file = path; dir = isc_mem_strdup(mctx, "."); } - if (dir == NULL) + if (dir == NULL) { return (ISC_R_NOMEMORY); + } if (*file == '\0') { isc_mem_free(mctx, dir); @@ -653,12 +687,11 @@ isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, } void * -isc_file_mmap(void *addr, size_t len, int prot, - int flags, int fd, off_t offset) -{ +isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, + off_t offset) { #ifdef HAVE_MMAP return (mmap(addr, len, prot, flags, fd, offset)); -#else +#else /* ifdef HAVE_MMAP */ void *buf; ssize_t ret; off_t end; @@ -669,44 +702,42 @@ isc_file_mmap(void *addr, size_t len, int prot, end = lseek(fd, 0, SEEK_END); lseek(fd, offset, SEEK_SET); - if (end - offset < (off_t) len) + if (end - offset < (off_t)len) { len = end - offset; + } buf = malloc(len); - if (buf == NULL) + if (buf == NULL) { return (NULL); + } ret = read(fd, buf, len); - if (ret != (ssize_t) len) { + if (ret != (ssize_t)len) { free(buf); buf = NULL; } return (buf); -#endif +#endif /* ifdef HAVE_MMAP */ } int isc_file_munmap(void *addr, size_t len) { #ifdef HAVE_MMAP return (munmap(addr, len)); -#else +#else /* ifdef HAVE_MMAP */ UNUSED(len); free(addr); return (0); -#endif +#endif /* ifdef HAVE_MMAP */ } #define DISALLOW "\\/ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif static isc_result_t -digest2hex(unsigned char *digest, unsigned int digestlen, - char *hash, size_t hashlen) -{ +digest2hex(unsigned char *digest, unsigned int digestlen, char *hash, + size_t hashlen) { unsigned int i; int ret; for (i = 0; i < digestlen; i++) { @@ -721,8 +752,7 @@ digest2hex(unsigned char *digest, unsigned int digestlen, isc_result_t isc_file_sanitize(const char *dir, const char *base, const char *ext, - char *path, size_t length) -{ + char *path, size_t length) { char buf[PATH_MAX]; unsigned char digest[ISC_MAX_MD_SIZE]; unsigned int digestlen; @@ -739,20 +769,24 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, * allow room for a full sha256 hash (64 chars * plus null terminator) */ - if (l < 65U) + if (l < 65U) { l = 65; + } - if (dir != NULL) + if (dir != NULL) { l += strlen(dir) + 1; - if (ext != NULL) + } + if (ext != NULL) { l += strlen(ext) + 1; + } - if (l > length || l > (unsigned)PATH_MAX) + if (l > length || l > (unsigned)PATH_MAX) { return (ISC_R_NOSPACE); + } /* Check whether the full-length SHA256 hash filename exists */ - err = isc_md(ISC_MD_SHA256, (const unsigned char *)base, - strlen(base), digest, &digestlen); + err = isc_md(ISC_MD_SHA256, (const unsigned char *)base, strlen(base), + digest, &digestlen); if (err != ISC_R_SUCCESS) { return (err); } @@ -762,9 +796,9 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, return (err); } - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - hash, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", hash, ext != NULL ? "." : "", + ext != NULL ? ext : ""); if (isc_file_exists(buf)) { strlcpy(path, buf, length); return (ISC_R_SUCCESS); @@ -772,9 +806,9 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, /* Check for a truncated SHA256 hash filename */ hash[16] = '\0'; - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - hash, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", hash, ext != NULL ? "." : "", + ext != NULL ? ext : ""); if (isc_file_exists(buf)) { strlcpy(path, buf, length); return (ISC_R_SUCCESS); @@ -790,14 +824,14 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, return (ISC_R_SUCCESS); } - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - base, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", base, ext != NULL ? "." : "", + ext != NULL ? ext : ""); strlcpy(path, buf, length); return (ISC_R_SUCCESS); } bool isc_file_isdirwritable(const char *path) { - return (access(path, W_OK|X_OK) == 0); + return (access(path, W_OK | X_OK) == 0); } diff --git a/lib/isc/unix/fsaccess.c b/lib/isc/unix/fsaccess.c index 8209250b..c6fed58f 100644 --- a/lib/isc/unix/fsaccess.c +++ b/lib/isc/unix/fsaccess.c @@ -3,20 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> - #include <errno.h> #include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> #include "errno2result.h" @@ -34,54 +30,56 @@ isc_fsaccess_set(const char *path, isc_fsaccess_t access) { isc_fsaccess_t bits; isc_result_t result; - if (stat(path, &statb) != 0) + if (stat(path, &statb) != 0) { return (isc__errno2result(errno)); + } - if ((statb.st_mode & S_IFDIR) != 0) + if ((statb.st_mode & S_IFDIR) != 0) { is_dir = true; - else if ((statb.st_mode & S_IFREG) == 0) + } else if ((statb.st_mode & S_IFREG) == 0) { return (ISC_R_INVALIDFILE); + } result = check_bad_bits(access, is_dir); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } /* * Done with checking bad bits. Set mode_t. */ mode = 0; -#define SET_AND_CLEAR1(modebit) \ +#define SET_AND_CLEAR1(modebit) \ if ((access & bits) != 0) { \ - mode |= modebit; \ - access &= ~bits; \ + mode |= modebit; \ + access &= ~bits; \ } #define SET_AND_CLEAR(user, group, other) \ - SET_AND_CLEAR1(user); \ - bits <<= STEP; \ - SET_AND_CLEAR1(group); \ - bits <<= STEP; \ + SET_AND_CLEAR1(user); \ + bits <<= STEP; \ + SET_AND_CLEAR1(group); \ + bits <<= STEP; \ SET_AND_CLEAR1(other); bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); - bits = ISC_FSACCESS_WRITE | - ISC_FSACCESS_CREATECHILD | + bits = ISC_FSACCESS_WRITE | ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_DELETECHILD; SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); - bits = ISC_FSACCESS_EXECUTE | - ISC_FSACCESS_ACCESSCHILD; + bits = ISC_FSACCESS_EXECUTE | ISC_FSACCESS_ACCESSCHILD; SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH); INSIST(access == 0); - if (chmod(path, mode) < 0) + if (chmod(path, mode) < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); } diff --git a/lib/isc/unix/ifiter_getifaddrs.c b/lib/isc/unix/ifiter_getifaddrs.c index 28f9edf9..58d609af 100644 --- a/lib/isc/unix/ifiter_getifaddrs.c +++ b/lib/isc/unix/ifiter_getifaddrs.c @@ -3,49 +3,46 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - /*! \file * \brief * Obtain the list of network interfaces using the getifaddrs(3) library. */ -#include <stdbool.h> - #include <ifaddrs.h> +#include <stdbool.h> #include <isc/strerr.h> /*% Iterator Magic */ -#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G') +#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G') /*% Valid Iterator */ -#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) +#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) #ifdef __linux static bool seenv6 = false; -#endif +#endif /* ifdef __linux */ /*% Iterator structure */ struct isc_interfaceiter { - unsigned int magic; /*%< Magic number. */ - isc_mem_t *mctx; - void *buf; /*%< (unused) */ - unsigned int bufsize; /*%< (always 0) */ - struct ifaddrs *ifaddrs; /*%< List of ifaddrs */ - struct ifaddrs *pos; /*%< Ptr to current ifaddr */ - isc_interface_t current; /*%< Current interface data. */ - isc_result_t result; /*%< Last result code. */ -#ifdef __linux - FILE * proc; - char entry[ISC_IF_INET6_SZ]; - isc_result_t valid; -#endif + unsigned int magic; /*%< Magic number. */ + isc_mem_t *mctx; + void *buf; /*%< (unused) */ + unsigned int bufsize; /*%< (always 0) */ + struct ifaddrs *ifaddrs; /*%< List of ifaddrs */ + struct ifaddrs *pos; /*%< Ptr to current ifaddr */ + isc_interface_t current; /*%< Current interface data. */ + isc_result_t result; /*%< Last result code. */ +#ifdef __linux + FILE *proc; + char entry[ISC_IF_INET6_SZ]; + isc_result_t valid; +#endif /* ifdef __linux */ }; isc_result_t @@ -59,8 +56,6 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); - if (iter == NULL) - return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = NULL; @@ -71,12 +66,13 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { * Only open "/proc/net/if_inet6" if we have never seen a IPv6 * address returned by getifaddrs(). */ - if (!seenv6) + if (!seenv6) { iter->proc = fopen("/proc/net/if_inet6", "r"); - else + } else { iter->proc = NULL; + } iter->valid = ISC_R_FAILURE; -#endif +#endif /* ifdef __linux */ if (getifaddrs(&iter->ifaddrs) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); @@ -98,13 +94,15 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { *iterp = iter; return (ISC_R_SUCCESS); - failure: +failure: #ifdef __linux - if (iter->proc != NULL) + if (iter->proc != NULL) { fclose(iter->proc); -#endif - if (iter->ifaddrs != NULL) /* just in case */ + } +#endif /* ifdef __linux */ + if (iter->ifaddrs != NULL) { /* just in case */ freeifaddrs(iter->ifaddrs); + } isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } @@ -127,57 +125,68 @@ internal_current(isc_interfaceiter_t *iter) { ifa = iter->pos; #ifdef __linux - if (iter->pos == NULL) + if (iter->pos == NULL) { return (linux_if_inet6_current(iter)); -#endif + } +#endif /* ifdef __linux */ INSIST(ifa != NULL); INSIST(ifa->ifa_name != NULL); - if (ifa->ifa_addr == NULL) + if (ifa->ifa_addr == NULL) { return (ISC_R_IGNORE); + } family = ifa->ifa_addr->sa_family; - if (family != AF_INET && family != AF_INET6) + if (family != AF_INET && family != AF_INET6) { return (ISC_R_IGNORE); + } #ifdef __linux - if (family == AF_INET6) + if (family == AF_INET6) { seenv6 = true; -#endif + } +#endif /* ifdef __linux */ memset(&iter->current, 0, sizeof(iter->current)); namelen = strlen(ifa->ifa_name); - if (namelen > sizeof(iter->current.name) - 1) + if (namelen > sizeof(iter->current.name) - 1) { namelen = sizeof(iter->current.name) - 1; + } memset(iter->current.name, 0, sizeof(iter->current.name)); memmove(iter->current.name, ifa->ifa_name, namelen); iter->current.flags = 0; - if ((ifa->ifa_flags & IFF_UP) != 0) + if ((ifa->ifa_flags & IFF_UP) != 0) { iter->current.flags |= INTERFACE_F_UP; + } - if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0) + if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0) { iter->current.flags |= INTERFACE_F_POINTTOPOINT; + } - if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) + if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) { iter->current.flags |= INTERFACE_F_LOOPBACK; + } iter->current.af = family; get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name); - if (ifa->ifa_netmask != NULL) + if (ifa->ifa_netmask != NULL) { get_addr(family, &iter->current.netmask, ifa->ifa_netmask, ifa->ifa_name); + } if (ifa->ifa_dstaddr != NULL && (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) + { get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr, ifa->ifa_name); + } return (ISC_R_SUCCESS); } @@ -191,14 +200,15 @@ internal_current(isc_interfaceiter_t *iter) { */ static isc_result_t internal_next(isc_interfaceiter_t *iter) { - - if (iter->pos != NULL) + if (iter->pos != NULL) { iter->pos = iter->pos->ifa_next; + } if (iter->pos == NULL) { #ifdef __linux - if (!seenv6) + if (!seenv6) { return (linux_if_inet6_next(iter)); -#endif + } +#endif /* ifdef __linux */ return (ISC_R_NOMORE); } @@ -207,22 +217,22 @@ internal_next(isc_interfaceiter_t *iter) { static void internal_destroy(isc_interfaceiter_t *iter) { - #ifdef __linux - if (iter->proc != NULL) + if (iter->proc != NULL) { fclose(iter->proc); + } iter->proc = NULL; -#endif - if (iter->ifaddrs) +#endif /* ifdef __linux */ + if (iter->ifaddrs) { freeifaddrs(iter->ifaddrs); + } iter->ifaddrs = NULL; } -static -void internal_first(isc_interfaceiter_t *iter) { - +static void +internal_first(isc_interfaceiter_t *iter) { #ifdef __linux linux_if_inet6_first(iter); -#endif +#endif /* ifdef __linux */ iter->pos = iter->ifaddrs; } diff --git a/lib/isc/unix/include/.clang-format b/lib/isc/unix/include/.clang-format new file mode 120000 index 00000000..e919bbad --- /dev/null +++ b/lib/isc/unix/include/.clang-format @@ -0,0 +1 @@ +../../../../.clang-format.headers
\ No newline at end of file diff --git a/lib/isc/unix/include/Makefile.in b/lib/isc/unix/include/Makefile.in index 2cbf021b..d33c0fcb 100644 --- a/lib/isc/unix/include/Makefile.in +++ b/lib/isc/unix/include/Makefile.in @@ -11,7 +11,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -SUBDIRS = isc pkcs11 +SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ diff --git a/lib/isc/unix/include/isc/Makefile.in b/lib/isc/unix/include/isc/Makefile.in index 2e3d3b7f..91387c74 100644 --- a/lib/isc/unix/include/isc/Makefile.in +++ b/lib/isc/unix/include/isc/Makefile.in @@ -13,7 +13,7 @@ top_srcdir = @top_srcdir@ VERSION=@BIND9_VERSION@ -HEADERS = dir.h net.h netdb.h offset.h stat.h \ +HEADERS = align.h dir.h net.h netdb.h offset.h stat.h \ stdatomic.h stdtime.h syslog.h time.h SUBDIRS = diff --git a/lib/isc/unix/include/isc/align.h b/lib/isc/unix/include/isc/align.h new file mode 100644 index 00000000..d9e04723 --- /dev/null +++ b/lib/isc/unix/include/isc/align.h @@ -0,0 +1,18 @@ +/* + * 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 + +#ifdef HAVE_STDALIGN_H +#include <stdalign.h> +#else /* ifdef HAVE_STDALIGN_H */ +#define alignas(x) __attribute__((__aligned__(x))) +#endif /* ifdef HAVE_STDALIGN_H */ diff --git a/lib/isc/unix/include/isc/dir.h b/lib/isc/unix/include/isc/dir.h index 5a147b89..f42ebe69 100644 --- a/lib/isc/unix/include/isc/dir.h +++ b/lib/isc/unix/include/isc/dir.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -14,32 +14,26 @@ /*! \file */ -#include <sys/types.h> /* Required on some systems. */ #include <dirent.h> #include <isc/lang.h> +#include <isc/platform.h> #include <isc/result.h> -#ifndef NAME_MAX -#define NAME_MAX 256 -#endif - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif +#include <sys/types.h> /* Required on some systems. */ /*% Directory Entry */ typedef struct isc_direntry { - char name[NAME_MAX]; - unsigned int length; + char name[NAME_MAX]; + unsigned int length; } isc_direntry_t; /*% Directory */ typedef struct isc_dir { - unsigned int magic; - char dirname[PATH_MAX]; - isc_direntry_t entry; - DIR * handle; + unsigned int magic; + char dirname[PATH_MAX]; + isc_direntry_t entry; + DIR * handle; } isc_dir_t; ISC_LANG_BEGINDECLS diff --git a/lib/isc/unix/include/isc/net.h b/lib/isc/unix/include/isc/net.h index 1f37c6d7..96bedf63 100644 --- a/lib/isc/unix/include/isc/net.h +++ b/lib/isc/unix/include/isc/net.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NET_H #define ISC_NET_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file * \brief @@ -65,98 +64,119 @@ /*** *** Imports. ***/ -#include <isc/platform.h> - #include <inttypes.h> -#include <sys/types.h> -#include <sys/socket.h> /* Contractual promise. */ - -#include <net/if.h> - -#include <netinet/in.h> /* Contractual promise. */ -#include <arpa/inet.h> /* Contractual promise. */ - #include <isc/lang.h> +#include <isc/platform.h> #include <isc/types.h> +#include <arpa/inet.h> /* Contractual promise. */ +#include <net/if.h> +#include <netinet/in.h> /* Contractual promise. */ +#include <sys/socket.h> /* Contractual promise. */ +#include <sys/types.h> + #ifndef IN6ADDR_LOOPBACK_INIT #ifdef s6_addr /*% IPv6 address loopback init */ -#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } -#else -#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } -#endif -#endif +#define IN6ADDR_LOOPBACK_INIT \ + { \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ + } \ + } \ + } +#else /* ifdef s6_addr */ +#define IN6ADDR_LOOPBACK_INIT \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ + } \ + } +#endif /* ifdef s6_addr */ +#endif /* ifndef IN6ADDR_LOOPBACK_INIT */ #ifndef IN6ADDR_V4MAPPED_INIT #ifdef s6_addr /*% IPv6 v4mapped prefix init */ -#define IN6ADDR_V4MAPPED_INIT { { { 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 } } } -#else -#define IN6ADDR_V4MAPPED_INIT { { 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 } } -#endif -#endif +#define IN6ADDR_V4MAPPED_INIT \ + { \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, \ + 0, 0, 0 \ + } \ + } \ + } +#else /* ifdef s6_addr */ +#define IN6ADDR_V4MAPPED_INIT \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0 \ + } \ + } +#endif /* ifdef s6_addr */ +#endif /* ifndef IN6ADDR_V4MAPPED_INIT */ #ifndef IN6_IS_ADDR_V4MAPPED /*% Is IPv6 address V4 mapped? */ -#define IN6_IS_ADDR_V4MAPPED(x) \ - (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ - (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) -#endif +#define IN6_IS_ADDR_V4MAPPED(x) \ + (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ + (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) +#endif /* ifndef IN6_IS_ADDR_V4MAPPED */ #ifndef IN6_IS_ADDR_V4COMPAT /*% Is IPv6 address V4 compatible? */ -#define IN6_IS_ADDR_V4COMPAT(x) \ - (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ - ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ - (x)->s6_addr[14] != 0 || \ +#define IN6_IS_ADDR_V4COMPAT(x) \ + (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ + ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ + (x)->s6_addr[14] != 0 || \ ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) -#endif +#endif /* ifndef IN6_IS_ADDR_V4COMPAT */ #ifndef IN6_IS_ADDR_MULTICAST /*% Is IPv6 address multicast? */ -#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) -#endif +#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) +#endif /* ifndef IN6_IS_ADDR_MULTICAST */ #ifndef IN6_IS_ADDR_LINKLOCAL /*% Is IPv6 address linklocal? */ #define IN6_IS_ADDR_LINKLOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) -#endif +#endif /* ifndef IN6_IS_ADDR_LINKLOCAL */ #ifndef IN6_IS_ADDR_SITELOCAL /*% is IPv6 address sitelocal? */ #define IN6_IS_ADDR_SITELOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) -#endif - +#endif /* ifndef IN6_IS_ADDR_SITELOCAL */ #ifndef IN6_IS_ADDR_LOOPBACK /*% is IPv6 address loopback? */ #define IN6_IS_ADDR_LOOPBACK(x) \ (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) -#endif +#endif /* ifndef IN6_IS_ADDR_LOOPBACK */ #ifndef AF_INET6 /*% IPv6 */ #define AF_INET6 99 -#endif +#endif /* ifndef AF_INET6 */ #ifndef PF_INET6 /*% IPv6 */ #define PF_INET6 AF_INET6 -#endif +#endif /* ifndef PF_INET6 */ #ifndef INADDR_ANY /*% inaddr any */ #define INADDR_ANY 0x00000000UL -#endif +#endif /* ifndef INADDR_ANY */ #ifndef INADDR_LOOPBACK /*% inaddr loopback */ #define INADDR_LOOPBACK 0x7f000001UL -#endif +#endif /* ifndef INADDR_LOOPBACK */ #ifndef MSG_TRUNC /*% @@ -165,19 +185,17 @@ * faking code in socket.c. */ #define ISC_PLATFORM_RECVOVERFLOW -#endif +#endif /* ifndef MSG_TRUNC */ /*% IP address. */ -#define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x))) +#define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x))) /*% Is IP address multicast? */ #define ISC_IPADDR_ISMULTICAST(i) \ - (((uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xe0000000)) + (((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xe0000000)) #define ISC_IPADDR_ISEXPERIMENTAL(i) \ - (((uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xf0000000)) + (((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xf0000000)) /*** *** Functions. @@ -254,13 +272,13 @@ isc_net_probeunix(void); * Returns whether UNIX domain sockets are supported. */ -#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ -#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ -#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ -#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ -#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ -#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ -#define ISC_NET_DSCPALL 0x3f /* All valid flags */ +#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ +#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ +#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ +#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ +#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ +#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ +#define ISC_NET_DSCPALL 0x3f /* All valid flags */ unsigned int isc_net_probedscp(void); @@ -268,7 +286,6 @@ isc_net_probedscp(void); * Probe the level of DSCP support. */ - isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); /*%< diff --git a/lib/isc/unix/include/isc/netdb.h b/lib/isc/unix/include/isc/netdb.h index 5aaa9f62..2e56d67d 100644 --- a/lib/isc/unix/include/isc/netdb.h +++ b/lib/isc/unix/include/isc/netdb.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NETDB_H #define ISC_NETDB_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /*! \file * \brief @@ -43,8 +42,8 @@ *** Imports. ***/ -#include <isc/net.h> - #include <netdb.h> +#include <isc/net.h> + #endif /* ISC_NETDB_H */ diff --git a/lib/isc/unix/include/isc/offset.h b/lib/isc/unix/include/isc/offset.h index cf57292a..973459ae 100644 --- a/lib/isc/unix/include/isc/offset.h +++ b/lib/isc/unix/include/isc/offset.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_OFFSET_H #define ISC_OFFSET_H 1 @@ -17,9 +16,10 @@ * \brief * File offsets are operating-system dependent. */ -#include <limits.h> /* Required for CHAR_BIT. */ +#include <limits.h> /* Required for CHAR_BIT. */ +#include <stddef.h> /* For Linux Standard Base. */ + #include <sys/types.h> -#include <stddef.h> /* For Linux Standard Base. */ typedef off_t isc_offset_t; diff --git a/lib/isc/unix/include/isc/stat.h b/lib/isc/unix/include/isc/stat.h index 24c4ce5e..dca04426 100644 --- a/lib/isc/unix/include/isc/stat.h +++ b/lib/isc/unix/include/isc/stat.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STAT_H #define ISC_STAT_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /* * Portable <sys/stat.h> support. @@ -40,7 +39,7 @@ *** Imports. ***/ -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> #endif /* ISC_STAT_H */ diff --git a/lib/isc/unix/include/isc/stdatomic.h b/lib/isc/unix/include/isc/stdatomic.h index 532d1188..f6a87fb2 100644 --- a/lib/isc/unix/include/isc/stdatomic.h +++ b/lib/isc/unix/include/isc/stdatomic.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,23 +13,27 @@ #include <inttypes.h> #include <stdbool.h> +#include <stddef.h> +#if HAVE_UCHAR_H +#include <uchar.h> +#endif /* HAVE_UCHAR_H */ #if !defined(__has_feature) #define __has_feature(x) 0 -#endif +#endif /* if !defined(__has_feature) */ #if !defined(__has_extension) #define __has_extension(x) __has_feature(x) -#endif +#endif /* if !defined(__has_extension) */ #if !defined(__GNUC_PREREQ__) #if defined(__GNUC__) && defined(__GNUC_MINOR__) -#define __GNUC_PREREQ__(maj, min) \ +#define __GNUC_PREREQ__(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else +#else /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ #define __GNUC_PREREQ__(maj, min) 0 -#endif -#endif +#endif /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ +#endif /* if !defined(__GNUC_PREREQ__) */ #if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) #if __has_extension(c_atomic) || __has_extension(cxx_atomic) @@ -38,28 +42,29 @@ #define __GNUC_ATOMICS #elif !defined(__GNUC__) #error "isc/stdatomic.h does not support your compiler" -#endif -#endif +#endif /* if __has_extension(c_atomic) || __has_extension(cxx_atomic) */ +#endif /* if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) */ + +#define ATOMIC_VAR_INIT(x) x #ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 -#endif +#define __ATOMIC_RELAXED 0 +#endif /* ifndef __ATOMIC_RELAXED */ #ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 -#endif +#define __ATOMIC_CONSUME 1 +#endif /* ifndef __ATOMIC_CONSUME */ #ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 -#endif +#define __ATOMIC_ACQUIRE 2 +#endif /* ifndef __ATOMIC_ACQUIRE */ #ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 -#endif +#define __ATOMIC_RELEASE 3 +#endif /* ifndef __ATOMIC_RELEASE */ #ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 -#endif +#define __ATOMIC_ACQ_REL 4 +#endif /* ifndef __ATOMIC_ACQ_REL */ #ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 -#endif - +#define __ATOMIC_SEQ_CST 5 +#endif /* ifndef __ATOMIC_SEQ_CST */ enum memory_order { memory_order_relaxed = __ATOMIC_RELAXED, @@ -72,81 +77,148 @@ enum memory_order { typedef enum memory_order memory_order; -typedef int_fast32_t atomic_int_fast32_t; -typedef uint_fast32_t atomic_uint_fast32_t; -typedef int_fast64_t atomic_int_fast64_t; -typedef uint_fast64_t atomic_uint_fast64_t; -typedef bool atomic_bool; +#ifndef HAVE_UCHAR_H +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +#endif /* HAVE_UCHAR_H */ + +typedef bool atomic_bool; +typedef char atomic_char; +typedef signed char atomic_schar; +typedef unsigned char atomic_uchar; +typedef short atomic_short; +typedef unsigned short atomic_ushort; +typedef int atomic_int; +typedef unsigned int atomic_uint; +typedef long atomic_long; +typedef unsigned long atomic_ulong; +typedef long long atomic_llong; +typedef unsigned long long atomic_ullong; +typedef char16_t atomic_char16_t; +typedef char32_t atomic_char32_t; +typedef wchar_t atomic_wchar_t; +typedef int_least8_t atomic_int_least8_t; +typedef uint_least8_t atomic_uint_least8_t; +typedef int_least16_t atomic_int_least16_t; +typedef uint_least16_t atomic_uint_least16_t; +typedef int_least32_t atomic_int_least32_t; +typedef uint_least32_t atomic_uint_least32_t; +typedef int_least64_t atomic_int_least64_t; +typedef uint_least64_t atomic_uint_least64_t; +typedef int_fast8_t atomic_int_fast8_t; +typedef uint_fast8_t atomic_uint_fast8_t; +typedef int_fast16_t atomic_int_fast16_t; +typedef uint_fast16_t atomic_uint_fast16_t; +typedef int_fast32_t atomic_int_fast32_t; +typedef uint_fast32_t atomic_uint_fast32_t; +typedef int_fast64_t atomic_int_fast64_t; +typedef uint_fast64_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef uintptr_t atomic_uintptr_t; +typedef size_t atomic_size_t; +typedef ptrdiff_t atomic_ptrdiff_t; +typedef intmax_t atomic_intmax_t; +typedef uintmax_t atomic_uintmax_t; #if defined(__CLANG_ATOMICS) /* __c11_atomic builtins */ -#define atomic_init(obj, desired) \ - __c11_atomic_init(obj, desired) -#define atomic_load_explicit(obj, order) \ - __c11_atomic_load(obj, order) -#define atomic_store_explicit(obj, desired, order) \ +#define atomic_init(obj, desired) __c11_atomic_init(obj, desired) +#define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order) +#define atomic_store_explicit(obj, desired, order) \ __c11_atomic_store(obj, desired, order) -#define atomic_fetch_add_explicit(obj, arg, order) \ +#define atomic_fetch_add_explicit(obj, arg, order) \ __c11_atomic_fetch_add(obj, arg, order) -#define atomic_fetch_sub_explicit(obj, arg, order) \ +#define atomic_fetch_sub_explicit(obj, arg, order) \ __c11_atomic_fetch_sub(obj, arg, order) -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ - __c11_atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ - __c11_atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) +#define atomic_fetch_and_explicit(obj, arg, order) \ + __c11_atomic_fetch_and(obj, arg, order) +#define atomic_fetch_or_explicit(obj, arg, order) \ + __c11_atomic_fetch_or(obj, arg, order) +#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) \ + __c11_atomic_compare_exchange_strong_explicit(obj, expected, desired, \ + succ, fail) +#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ + fail) \ + __c11_atomic_compare_exchange_weak_explicit(obj, expected, desired, \ + succ, fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __c11_atomic_exchange_explicit(obj, expected, order) #elif defined(__GNUC_ATOMICS) /* __atomic builtins */ -#define atomic_init(obj, desired) \ - (*obj = desired) -#define atomic_load_explicit(obj, order) \ - __atomic_load_n(obj, order) -#define atomic_store_explicit(obj, desired, order) \ +#define atomic_init(obj, desired) (*obj = desired) +#define atomic_load_explicit(obj, order) __atomic_load_n(obj, order) +#define atomic_store_explicit(obj, desired, order) \ __atomic_store_n(obj, desired, order) -#define atomic_fetch_add_explicit(obj, arg, order) \ +#define atomic_fetch_add_explicit(obj, arg, order) \ __atomic_fetch_add(obj, arg, order) -#define atomic_fetch_sub_explicit(obj, arg, order) \ +#define atomic_fetch_sub_explicit(obj, arg, order) \ __atomic_fetch_sub(obj, arg, order) -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ +#define atomic_fetch_and_explicit(obj, arg, order) \ + __atomic_fetch_and(obj, arg, order) +#define atomic_fetch_or_explicit(obj, arg, order) \ + __atomic_fetch_or(obj, arg, order) +#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) \ __atomic_compare_exchange_n(obj, expected, desired, 0, succ, fail) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ +#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ + fail) \ __atomic_compare_exchange_n(obj, expected, desired, 1, succ, fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __atomic_exchange_n(obj, desired, order) #else /* __sync builtins */ -#define atomic_init(obj, desired) \ - (*obj = desired) -#define atomic_load_explicit(obj, order) \ - __sync_fetch_and_add(obj, 0) -#define atomic_store_explicit(obj, desired, order) \ - do { \ - __sync_synchronize(); \ - *obj = desired; \ - __sync_synchronize(); \ +#define atomic_init(obj, desired) (*obj = desired) +#define atomic_load_explicit(obj, order) __sync_fetch_and_add(obj, 0) +#define atomic_store_explicit(obj, desired, order) \ + do { \ + __sync_synchronize(); \ + *obj = desired; \ + __sync_synchronize(); \ } while (0); #define atomic_fetch_add_explicit(obj, arg, order) \ __sync_fetch_and_add(obj, arg) #define atomic_fetch_sub_explicit(obj, arg, order) \ __sync_fetch_and_sub(obj, arg, order) -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ - ({ \ - __typeof__(obj) __v; \ - _Bool __r; \ - __v = (__typeof__(obj))__sync_val_compare_and_swap(obj, \ - *(expected), \ - desired); \ - __r = ((__typeof__(obj))*(expected) == __v); \ - *(expected) = __v; \ - __r; \ +#define atomic_fetch_and_explicit(obj, arg, order) \ + __sync_fetch_and_and(obj, arg, order) +#define atomic_fetch_or_explicit(obj, arg, order) \ + __sync_fetch_and_or(obj, arg, order) +#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) \ + ({ \ + __typeof__(obj) __v; \ + _Bool __r; \ + __v = (__typeof__(obj))__sync_val_compare_and_swap( \ + obj, *(expected), desired); \ + __r = ((__typeof__(obj)) * (expected) == __v); \ + *(expected) = __v; \ + __r; \ }) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ - atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) -#endif +#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ + fail) \ + atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __sync_lock_test_and_set(obj, desired) + +#endif /* if defined(__CLANG_ATOMICS) */ -#define atomic_load(obj) \ - atomic_load_explicit(obj, memory_order_seq_cst) +#define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) #define atomic_store(obj, arg) \ atomic_store_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_add(obj, arg) \ atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_sub(obj, arg) \ atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst) -#define atomic_compare_exchange_strong(obj, expected, desired) \ - atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) -#define atomic_compare_exchange_weak(obj, expected, desired) \ - atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_fetch_and(obj, arg) \ + atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_or(obj, arg) \ + atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst) +#define atomic_compare_exchange_strong(obj, expected, desired) \ + atomic_compare_exchange_strong_explicit(obj, expected, desired, \ + memory_order_seq_cst, \ + memory_order_seq_cst) +#define atomic_compare_exchange_weak(obj, expected, desired) \ + atomic_compare_exchange_weak_explicit(obj, expected, desired, \ + memory_order_seq_cst, \ + memory_order_seq_cst) +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) diff --git a/lib/isc/unix/include/isc/stdtime.h b/lib/isc/unix/include/isc/stdtime.h index cffe39a1..52557b94 100644 --- a/lib/isc/unix/include/isc/stdtime.h +++ b/lib/isc/unix/include/isc/stdtime.h @@ -3,20 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STDTIME_H #define ISC_STDTIME_H 1 /*! \file */ -#include <isc/lang.h> #include <inttypes.h> +#include <stdlib.h> + +#include <isc/lang.h> /*% * It's public information that 'isc_stdtime_t' is an unsigned integral type. @@ -37,6 +38,20 @@ isc_stdtime_get(isc_stdtime_t *t); *\li 't' is a valid pointer. */ +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen); +/* + * Convert 't' into a null-terminated string of the form + * "Wed Jun 30 21:49:08 1993". Store the string in the 'out' + * buffer. + * + * Requires: + * + * 't' is a valid time. + * 'out' is a valid pointer. + * 'outlen' is at least 26. + */ + #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. diff --git a/lib/isc/unix/include/isc/syslog.h b/lib/isc/unix/include/isc/syslog.h index e0b8e859..f2add8b0 100644 --- a/lib/isc/unix/include/isc/syslog.h +++ b/lib/isc/unix/include/isc/syslog.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SYSLOG_H #define ISC_SYSLOG_H 1 diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h index 36177fa6..cb943201 100644 --- a/lib/isc/unix/include/isc/time.h +++ b/lib/isc/unix/include/isc/time.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_TIME_H #define ISC_TIME_H 1 @@ -37,7 +36,7 @@ struct isc_interval { unsigned int nanoseconds; }; -extern const isc_interval_t * const isc_interval_zero; +extern const isc_interval_t *const isc_interval_zero; /* * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially @@ -49,8 +48,8 @@ extern const isc_interval_t * const isc_interval_zero; ISC_LANG_BEGINDECLS void -isc_interval_set(isc_interval_t *i, - unsigned int seconds, unsigned int nanoseconds); +isc_interval_set(isc_interval_t *i, unsigned int seconds, + unsigned int nanoseconds); /*%< * Set 'i' to a value representing an interval of 'seconds' seconds and * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and @@ -84,11 +83,11 @@ isc_interval_iszero(const isc_interval_t *i); */ struct isc_time { - unsigned int seconds; - unsigned int nanoseconds; + unsigned int seconds; + unsigned int nanoseconds; }; -extern const isc_time_t * const isc_time_epoch; +extern const isc_time_t *const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); @@ -357,6 +356,20 @@ isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len); */ void +isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssss" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + +void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', @@ -385,10 +398,24 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len); */ void +isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssssZ" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + +void isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', - * using the format "yyyymmddhhmmsssss" userful for file timestamping. + * using the format "yyyymmddhhmmsssss" useful for file timestamping. * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * diff --git a/lib/isc/unix/include/pkcs11/Makefile.in b/lib/isc/unix/include/pkcs11/Makefile.in deleted file mode 100644 index 420fec13..00000000 --- a/lib/isc/unix/include/pkcs11/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# 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 http://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -HEADERS = cryptoki.h -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/pkcs11 || exit 1; \ - done - -uninstall:: - for i in ${HEADERS}; do \ - rm -f ${DESTDIR}${includedir}/pkcs11/$$i || exit 1; \ - done diff --git a/lib/isc/unix/include/pkcs11/cryptoki.h b/lib/isc/unix/include/pkcs11/cryptoki.h deleted file mode 100644 index 7dc48b0c..00000000 --- a/lib/isc/unix/include/pkcs11/cryptoki.h +++ /dev/null @@ -1,66 +0,0 @@ -/* cryptoki.h include file for PKCS #11. */ -/* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* $Revision: 1.3 $ */ - -/* - * Portions Copyright RSA Security Inc. - * - * License to copy and use this software is granted provided that it is - * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface - * (Cryptoki)" in all material mentioning or referencing this software. - - * License is also granted to make and use derivative works provided that - * such works are identified as "derived from the RSA Security Inc. PKCS #11 - * Cryptographic Token Interface (Cryptoki)" in all material mentioning or - * referencing the derived work. - - * RSA Security Inc. makes no representations concerning either the - * merchantability of this software or the suitability of this software for - * any particular purpose. It is provided "as is" without express or implied - * warranty of any kind. - */ - -/* This is a sample file containing the top level include directives - * for building Unix Cryptoki libraries and applications. - */ - -#ifndef ___CRYPTOKI_H_INC___ -#define ___CRYPTOKI_H_INC___ - -#define CK_PTR * - -#define CK_DEFINE_FUNCTION(returnType, name) \ - returnType name - -#define CK_DECLARE_FUNCTION(returnType, name) \ - returnType name - -#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - returnType (* name) - -#define CK_CALLBACK_FUNCTION(returnType, name) \ - returnType (* name) - -/* NULL is in unistd.h */ -#include <unistd.h> -#define NULL_PTR NULL - -#undef CK_PKCS11_FUNCTION_INFO - -#include <pkcs11/pkcs11.h> - -#endif /* ___CRYPTOKI_H_INC___ */ diff --git a/lib/isc/unix/interfaceiter.c b/lib/isc/unix/interfaceiter.c index 897b3bbf..ce68ad35 100644 --- a/lib/isc/unix/interfaceiter.c +++ b/lib/isc/unix/interfaceiter.c @@ -3,28 +3,25 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <sys/types.h> #include <sys/ioctl.h> +#include <sys/types.h> #ifdef HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> /* Required for ifiter_ioctl.c. */ -#endif +#include <sys/sockio.h> /* Required for ifiter_ioctl.c. */ +#endif /* ifdef HAVE_SYS_SOCKIO_H */ -#include <stdio.h> +#include <errno.h> #include <inttypes.h> +#include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <errno.h> #include <isc/interfaceiter.h> #include <isc/log.h> @@ -41,7 +38,7 @@ /* Must follow <isc/net.h>. */ #ifdef HAVE_NET_IF6_H #include <net/if6.h> -#endif +#endif /* ifdef HAVE_NET_IF6_H */ #include <net/if.h> /* Common utility functions */ @@ -57,13 +54,12 @@ static void get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, - char *ifname) -{ + char *ifname) { struct sockaddr_in6 *sa6; #if !defined(HAVE_IF_NAMETOINDEX) UNUSED(ifname); -#endif +#endif /* if !defined(HAVE_IF_NAMETOINDEX) */ /* clear any remaining value for safety */ memset(dst, 0, sizeof(*dst)); @@ -71,17 +67,16 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, dst->family = family; switch (family) { case AF_INET: - memmove(&dst->type.in, - &((struct sockaddr_in *) src)->sin_addr, + memmove(&dst->type.in, &((struct sockaddr_in *)src)->sin_addr, sizeof(struct in_addr)); break; case AF_INET6: sa6 = (struct sockaddr_in6 *)src; memmove(&dst->type.in6, &sa6->sin6_addr, sizeof(struct in6_addr)); - if (sa6->sin6_scope_id != 0) + if (sa6->sin6_scope_id != 0) { isc_netaddr_setzone(dst, sa6->sin6_scope_id); - else { + } else { /* * BSD variants embed scope zone IDs in the 128bit * address as a kernel internal form. Unfortunately, @@ -117,10 +112,10 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, */ zone = if_nametoindex(ifname); if (zone != 0) { - isc_netaddr_setzone(dst, - (uint32_t)zone); + isc_netaddr_setzone( + dst, (uint32_t)zone); } -#endif +#endif /* ifdef HAVE_IF_NAMETOINDEX */ } } } @@ -136,12 +131,16 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, */ #ifdef __linux -#define ISC_IF_INET6_SZ \ - sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n") -static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *); -static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *); -static void linux_if_inet6_first(isc_interfaceiter_t *iter); -#endif +#define ISC_IF_INET6_SZ \ + sizeof("00000000000000000000000000000001 01 80 10 80 " \ + "XXXXXXloXXXXXXXX\n") +static isc_result_t +linux_if_inet6_next(isc_interfaceiter_t *); +static isc_result_t +linux_if_inet6_current(isc_interfaceiter_t *); +static void +linux_if_inet6_first(isc_interfaceiter_t *iter); +#endif /* ifdef __linux */ #include "ifiter_getifaddrs.c" @@ -151,31 +150,35 @@ linux_if_inet6_first(isc_interfaceiter_t *iter) { if (iter->proc != NULL) { rewind(iter->proc); (void)linux_if_inet6_next(iter); - } else + } else { iter->valid = ISC_R_NOMORE; + } } static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *iter) { if (iter->proc != NULL && fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL) + { iter->valid = ISC_R_SUCCESS; - else + } else { iter->valid = ISC_R_NOMORE; + } return (iter->valid); } static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *iter) { char address[33]; - char name[IF_NAMESIZE+1]; + char name[IF_NAMESIZE + 1]; struct in6_addr addr6; unsigned int ifindex, prefix, flag3, flag4; int res; unsigned int i; - if (iter->valid != ISC_R_SUCCESS) + if (iter->valid != ISC_R_SUCCESS) { return (iter->valid); + } if (iter->proc == NULL) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, @@ -183,8 +186,8 @@ linux_if_inet6_current(isc_interfaceiter_t *iter) { return (ISC_R_FAILURE); } - res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n", - address, &ifindex, &prefix, &flag3, &flag4, name); + res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n", address, + &ifindex, &prefix, &flag3, &flag4, name); if (res != 6) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, @@ -209,8 +212,7 @@ linux_if_inet6_current(isc_interfaceiter_t *iter) { iter->current.flags = INTERFACE_F_UP; isc_netaddr_fromin6(&iter->current.address, &addr6); if (isc_netaddr_islinklocal(&iter->current.address)) { - isc_netaddr_setzone(&iter->current.address, - (uint32_t)ifindex); + isc_netaddr_setzone(&iter->current.address, (uint32_t)ifindex); } for (i = 0; i < 16; i++) { if (prefix > 8) { @@ -225,16 +227,14 @@ linux_if_inet6_current(isc_interfaceiter_t *iter) { strlcpy(iter->current.name, name, sizeof(iter->current.name)); return (ISC_R_SUCCESS); } -#endif +#endif /* ifdef __linux */ /* * The remaining code is common to the sysctl and ioctl case. */ isc_result_t -isc_interfaceiter_current(isc_interfaceiter_t *iter, - isc_interface_t *ifdata) -{ +isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata) { REQUIRE(iter->result == ISC_R_SUCCESS); memmove(ifdata, &iter->current, sizeof(*ifdata)); return (ISC_R_SUCCESS); @@ -249,11 +249,13 @@ isc_interfaceiter_first(isc_interfaceiter_t *iter) { internal_first(iter); for (;;) { result = internal_current(iter); - if (result != ISC_R_IGNORE) + if (result != ISC_R_IGNORE) { break; + } result = internal_next(iter); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { break; + } } iter->result = result; return (result); @@ -268,29 +270,31 @@ isc_interfaceiter_next(isc_interfaceiter_t *iter) { for (;;) { result = internal_next(iter); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { break; + } result = internal_current(iter); - if (result != ISC_R_IGNORE) + if (result != ISC_R_IGNORE) { break; + } } iter->result = result; return (result); } void -isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) -{ +isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; + *iterp = NULL; REQUIRE(VALID_IFITER(iter)); internal_destroy(iter); - if (iter->buf != NULL) + if (iter->buf != NULL) { isc_mem_put(iter->mctx, iter->buf, iter->bufsize); + } iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); - *iterp = NULL; } diff --git a/lib/isc/unix/meminfo.c b/lib/isc/unix/meminfo.c index ad750a70..46cb7d68 100644 --- a/lib/isc/unix/meminfo.c +++ b/lib/isc/unix/meminfo.c @@ -3,20 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - -#include <isc/meminfo.h> #include <inttypes.h> #include <unistd.h> -#ifdef HAVE_SYS_SYSCTL_H + +#include <isc/meminfo.h> +#if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) #include <sys/sysctl.h> -#endif +#endif /* if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) */ uint64_t isc_meminfo_totalphys(void) { @@ -27,14 +26,23 @@ isc_meminfo_totalphys(void) { mib[1] = HW_MEMSIZE; #elif defined(HW_PHYSMEM64) mib[1] = HW_PHYSMEM64; -#endif +#endif /* if defined(HW_MEMSIZE) */ uint64_t size = 0; size_t len = sizeof(size); - if (sysctl(mib, 2, &size, &len, NULL, 0) == 0) + if (sysctl(mib, 2, &size, &len, NULL, 0) == 0) { return (size); -#endif + } +#endif /* if defined(CTL_HW) && (defined(HW_PHYSMEM64) || defined(HW_MEMSIZE)) \ + * */ #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) - return ((size_t) (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE))); -#endif + long pages = sysconf(_SC_PHYS_PAGES); + long pagesize = sysconf(_SC_PAGESIZE); + + if (pages == -1 || pagesize == -1) { + return (0); + } + + return ((size_t)pages * pagesize); +#endif /* if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) */ return (0); } diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c index 98abab50..cc6c2b7b 100644 --- a/lib/isc/unix/net.c +++ b/lib/isc/unix/net.c @@ -3,29 +3,25 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <stdbool.h> #include <sys/types.h> -#if defined(HAVE_SYS_SYSCTL_H) +#if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) #if defined(HAVE_SYS_PARAM_H) #include <sys/param.h> -#endif +#endif /* if defined(HAVE_SYS_PARAM_H) */ #include <sys/sysctl.h> -#endif -#include <sys/uio.h> - +#endif /* if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) */ #include <errno.h> -#include <unistd.h> #include <fcntl.h> +#include <sys/uio.h> +#include <unistd.h> #include <isc/log.h> #include <isc/net.h> @@ -37,7 +33,7 @@ #ifndef socklen_t #define socklen_t unsigned int -#endif +#endif /* ifndef socklen_t */ /*% * Definitions about UDP port range specification. This is a total mess of @@ -51,10 +47,10 @@ */ #ifndef ISC_NET_PORTRANGELOW #define ISC_NET_PORTRANGELOW 1024 -#endif /* ISC_NET_PORTRANGELOW */ +#endif /* ISC_NET_PORTRANGELOW */ #ifndef ISC_NET_PORTRANGEHIGH #define ISC_NET_PORTRANGEHIGH 65535 -#endif /* ISC_NET_PORTRANGEHIGH */ +#endif /* ISC_NET_PORTRANGEHIGH */ #ifdef HAVE_SYSCTLBYNAME @@ -64,54 +60,61 @@ #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) #define USE_SYSCTL_PORTRANGE #define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst" -#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast" +#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast" #define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst" -#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast" -#endif +#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast" +#endif /* if defined(__FreeBSD__) || defined(__APPLE__) || \ + * defined(__DragonFly__) */ #ifdef __NetBSD__ #define USE_SYSCTL_PORTRANGE #define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin" -#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax" +#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax" #define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin" -#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax" -#endif +#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax" +#endif /* ifdef __NetBSD__ */ #else /* !HAVE_SYSCTLBYNAME */ #ifdef __OpenBSD__ #define USE_SYSCTL_PORTRANGE -#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \ - IPCTL_IPPORT_HIFIRSTAUTO } -#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \ - IPCTL_IPPORT_HILASTAUTO } +#define SYSCTL_V4PORTRANGE_LOW \ + { \ + CTL_NET, PF_INET, IPPROTO_IP, IPCTL_IPPORT_HIFIRSTAUTO \ + } +#define SYSCTL_V4PORTRANGE_HIGH \ + { \ + CTL_NET, PF_INET, IPPROTO_IP, IPCTL_IPPORT_HILASTAUTO \ + } /* Same for IPv6 */ #define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW -#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH -#endif +#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH +#endif /* ifdef __OpenBSD__ */ #endif /* HAVE_SYSCTLBYNAME */ -static isc_once_t once_ipv6only = ISC_ONCE_INIT; -static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; +static isc_once_t once_ipv6only = ISC_ONCE_INIT; +#ifdef __notyet__ +static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; +#endif /* ifdef __notyet__ */ #ifndef ISC_CMSG_IP_TOS #ifdef __APPLE__ -#define ISC_CMSG_IP_TOS 0 /* As of 10.8.2. */ -#else /* ! __APPLE__ */ +#define ISC_CMSG_IP_TOS 0 /* As of 10.8.2. */ +#else /* ! __APPLE__ */ #define ISC_CMSG_IP_TOS 1 #endif /* ! __APPLE__ */ #endif /* ! ISC_CMSG_IP_TOS */ -static isc_once_t once = ISC_ONCE_INIT; -static isc_once_t once_dscp = ISC_ONCE_INIT; +static isc_once_t once = ISC_ONCE_INIT; +static isc_once_t once_dscp = ISC_ONCE_INIT; -static isc_result_t ipv4_result = ISC_R_NOTFOUND; -static isc_result_t ipv6_result = ISC_R_NOTFOUND; -static isc_result_t unix_result = ISC_R_NOTFOUND; -static isc_result_t ipv6only_result = ISC_R_NOTFOUND; -static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; -static unsigned int dscp_result = 0; +static isc_result_t ipv4_result = ISC_R_NOTFOUND; +static isc_result_t ipv6_result = ISC_R_NOTFOUND; +static isc_result_t unix_result = ISC_R_NOTFOUND; +static isc_result_t ipv6only_result = ISC_R_NOTFOUND; +static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; +static unsigned int dscp_result = 0; static isc_result_t try_proto(int domain) { @@ -124,22 +127,21 @@ try_proto(int domain) { switch (errno) { #ifdef EAFNOSUPPORT case EAFNOSUPPORT: -#endif +#endif /* ifdef EAFNOSUPPORT */ #ifdef EPFNOSUPPORT case EPFNOSUPPORT: -#endif +#endif /* ifdef EPFNOSUPPORT */ #ifdef EPROTONOSUPPORT case EPROTONOSUPPORT: -#endif +#endif /* ifdef EPROTONOSUPPORT */ #ifdef EINVAL case EINVAL: -#endif +#endif /* ifdef EINVAL */ return (ISC_R_NOTFOUND); default: strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", - strbuf); + "socket() failed: %s", strbuf); return (ISC_R_UNEXPECTED); } } @@ -163,17 +165,15 @@ try_proto(int domain) { "IPv6 is not supported."); result = ISC_R_NOTFOUND; } else { - if (len == sizeof(struct sockaddr_in6)) + if (len == sizeof(struct sockaddr_in6)) { result = ISC_R_SUCCESS; - else { - isc_log_write(isc_lctx, - ISC_LOGCATEGORY_GENERAL, + } else { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "IPv6 structures in kernel and " "user space do not match."); - isc_log_write(isc_lctx, - ISC_LOGCATEGORY_GENERAL, + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "IPv6 is not supported."); @@ -193,7 +193,7 @@ initialize_action(void) { ipv6_result = try_proto(PF_INET6); #ifdef ISC_PLATFORM_HAVESYSUNH unix_result = try_proto(PF_UNIX); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ } static void @@ -224,7 +224,7 @@ try_ipv6only(void) { #ifdef IPV6_V6ONLY int s, on; char strbuf[ISC_STRERRORSIZE]; -#endif +#endif /* ifdef IPV6_V6ONLY */ isc_result_t result; result = isc_net_probeipv6(); @@ -236,13 +236,12 @@ try_ipv6only(void) { #ifndef IPV6_V6ONLY ipv6only_result = ISC_R_NOTFOUND; return; -#else +#else /* ifndef IPV6_V6ONLY */ /* check for TCP sockets */ s = socket(PF_INET6, SOCK_STREAM, 0); if (s == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; @@ -260,8 +259,7 @@ try_ipv6only(void) { s = socket(PF_INET6, SOCK_DGRAM, 0); if (s == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; @@ -283,10 +281,11 @@ close: static void initialize_ipv6only(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6only, - try_ipv6only) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&once_ipv6only, try_ipv6only) == + ISC_R_SUCCESS); } +#ifdef __notyet__ static void try_ipv6pktinfo(void) { int s, on; @@ -304,8 +303,7 @@ try_ipv6pktinfo(void) { s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6pktinfo_result = ISC_R_UNEXPECTED; return; @@ -313,9 +311,9 @@ try_ipv6pktinfo(void) { #ifdef IPV6_RECVPKTINFO optname = IPV6_RECVPKTINFO; -#else +#else /* ifdef IPV6_RECVPKTINFO */ optname = IPV6_PKTINFO; -#endif +#endif /* ifdef IPV6_RECVPKTINFO */ on = 1; if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) { ipv6pktinfo_result = ISC_R_NOTFOUND; @@ -331,9 +329,10 @@ close: static void initialize_ipv6pktinfo(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, - try_ipv6pktinfo) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, try_ipv6pktinfo) == + ISC_R_SUCCESS); } +#endif /* ifdef __notyet__ */ isc_result_t isc_net_probe_ipv6only(void) { @@ -343,7 +342,18 @@ isc_net_probe_ipv6only(void) { isc_result_t isc_net_probe_ipv6pktinfo(void) { +/* + * XXXWPK if pktinfo were supported then we could listen on :: for ipv6 and get + * the information about the destination address from pktinfo structure passed + * in recvmsg but this method is not portable and libuv doesn't support it - so + * we need to listen on all interfaces. + * We should verify that this doesn't impact performance (we already do it for + * ipv4) and either remove all the ipv6pktinfo detection code from above + * or think of fixing libuv. + */ +#ifdef __notyet__ initialize_ipv6pktinfo(); +#endif /* ifdef __notyet__ */ return (ipv6pktinfo_result); } @@ -353,7 +363,7 @@ static inline socklen_t cmsg_len(socklen_t len) { #ifdef CMSG_LEN return (CMSG_LEN(len)); -#else +#else /* ifdef CMSG_LEN */ socklen_t hdrlen; /* @@ -362,14 +372,14 @@ cmsg_len(socklen_t len) { */ hdrlen = (socklen_t)CMSG_DATA(((struct cmsghdr *)NULL)); return (hdrlen + len); -#endif +#endif /* ifdef CMSG_LEN */ } static inline socklen_t cmsg_space(socklen_t len) { #ifdef CMSG_SPACE return (CMSG_SPACE(len)); -#else +#else /* ifdef CMSG_SPACE */ struct msghdr msg; struct cmsghdr *cmsgp; /* @@ -386,11 +396,12 @@ cmsg_space(socklen_t len) { cmsgp->cmsg_len = cmsg_len(len); cmsgp = CMSG_NXTHDR(&msg, cmsgp); - if (cmsgp != NULL) + if (cmsgp != NULL) { return ((char *)cmsgp - (char *)msg.msg_control); - else + } else { return (0); -#endif + } +#endif /* ifdef CMSG_SPACE */ } /* @@ -405,20 +416,20 @@ make_nonblock(int fd) { int on = 1; ret = ioctl(fd, FIONBIO, (char *)&on); -#else +#else /* ifdef USE_FIONBIO_IOCTL */ flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK; ret = fcntl(fd, F_SETFL, flags); -#endif +#endif /* ifdef USE_FIONBIO_IOCTL */ if (ret == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, #ifdef USE_FIONBIO_IOCTL "ioctl(%d, FIONBIO, &on): %s", fd, -#else +#else /* ifdef USE_FIONBIO_IOCTL */ "fcntl(%d, F_SETFL, %d): %s", fd, flags, -#endif +#endif /* ifdef USE_FIONBIO_IOCTL */ strbuf); return (ISC_R_UNEXPECTED); @@ -438,7 +449,7 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { unsigned char b[256]; } control; struct cmsghdr *cmsgp; - int dscp = (46 << 2); /* Expedited forwarding. */ + int dscp = (46 << 2); /* Expedited forwarding. */ struct iovec iovec; char buf[1] = { 0 }; isc_result_t result; @@ -467,7 +478,7 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { msg.msg_namelen = len; msg.msg_iov = &iovec; msg.msg_iovlen = 1; - msg.msg_control = (void*)&control; + msg.msg_control = (void *)&control; msg.msg_controllen = 0; msg.msg_flags = 0; @@ -480,10 +491,10 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { cmsgp->cmsg_level = level; cmsgp->cmsg_type = type; cmsgp->cmsg_len = cmsg_len(sizeof(char)); - *(unsigned char*)CMSG_DATA(cmsgp) = dscp; + *(unsigned char *)CMSG_DATA(cmsgp) = dscp; msg.msg_controllen += cmsg_space(sizeof(char)); break; -#endif +#endif /* ifdef IP_TOS */ #ifdef IPV6_TCLASS case IPV6_TCLASS: memset(cmsgp, 0, cmsg_space(sizeof(dscp))); @@ -493,7 +504,7 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { memmove(CMSG_DATA(cmsgp), &dscp, sizeof(dscp)); msg.msg_controllen += cmsg_space(sizeof(dscp)); break; -#endif +#endif /* ifdef IPV6_TCLASS */ default: INSIST(0); ISC_UNREACHABLE(); @@ -505,10 +516,10 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { switch (errno) { #ifdef ENOPROTOOPT case ENOPROTOOPT: -#endif +#endif /* ifdef ENOPROTOOPT */ #ifdef EOPNOTSUPP case EOPNOTSUPP: -#endif +#endif /* ifdef EOPNOTSUPP */ case EINVAL: case EPERM: break; @@ -522,7 +533,8 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { "sendmsg: %s", strbuf); } else { typestr = (type == IP_TOS) ? "IP_TOS" : "IPV6_TCLASS"; - UNEXPECTED_ERROR(__FILE__, __LINE__, "probing " + UNEXPECTED_ERROR(__FILE__, __LINE__, + "probing " "sendmsg() with %s=%02x failed: %s", typestr, dscp, strbuf); } @@ -547,12 +559,13 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { msg.msg_controllen = 0; msg.msg_flags = 0; - if (recvmsg(s, &msg, 0) < 0) + if (recvmsg(s, &msg, 0) < 0) { return (false); + } return (true); } -#endif +#endif /* if ISC_CMSG_IP_TOS || defined(IPV6_TCLASS) */ static void try_dscp_v4(void) { @@ -570,9 +583,9 @@ try_dscp_v4(void) { hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; -#else +#else /* ifdef AI_NUMERICHOST */ hints.ai_flags = AI_PASSIVE; -#endif +#endif /* ifdef AI_NUMERICHOST */ n = getaddrinfo("127.0.0.1", NULL, &hints, &res0); if (n != 0 || res0 == NULL) { @@ -593,18 +606,21 @@ try_dscp_v4(void) { return; } - if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == 0) + if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == 0) { dscp_result |= ISC_NET_DSCPSETV4; + } #ifdef IP_RECVTOS on = 1; - if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) == 0) + if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) == 0) { dscp_result |= ISC_NET_DSCPRECVV4; + } #endif /* IP_RECVTOS */ #if ISC_CMSG_IP_TOS - if (cmsgsend(s, IPPROTO_IP, IP_TOS, res0)) + if (cmsgsend(s, IPPROTO_IP, IP_TOS, res0)) { dscp_result |= ISC_NET_DSCPPKTV4; + } #endif /* ISC_CMSG_IP_TOS */ freeaddrinfo(res0); @@ -629,9 +645,9 @@ try_dscp_v6(void) { hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; -#else +#else /* ifdef AI_NUMERICHOST */ hints.ai_flags = AI_PASSIVE; -#endif +#endif /* ifdef AI_NUMERICHOST */ n = getaddrinfo("::1", NULL, &hints, &res0); if (n != 0 || res0 == NULL) { @@ -651,16 +667,21 @@ try_dscp_v6(void) { return; } if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &dscp, sizeof(dscp)) == 0) + { dscp_result |= ISC_NET_DSCPSETV6; + } #ifdef IPV6_RECVTCLASS on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on)) == 0) + { dscp_result |= ISC_NET_DSCPRECVV6; + } #endif /* IPV6_RECVTCLASS */ - if (cmsgsend(s, IPPROTO_IPV6, IPV6_TCLASS, res0)) + if (cmsgsend(s, IPPROTO_IPV6, IPV6_TCLASS, res0)) { dscp_result |= ISC_NET_DSCPPKTV6; + } freeaddrinfo(res0); close(s); @@ -701,24 +722,25 @@ getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH; } portlen = sizeof(port_low); - if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, - NULL, 0) < 0) { + if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, NULL, 0) < 0) + { return (ISC_R_FAILURE); } portlen = sizeof(port_high); - if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, - NULL, 0) < 0) { + if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, NULL, 0) < 0) + { return (ISC_R_FAILURE); } - if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) + if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) { return (ISC_R_RANGE); + } *low = (in_port_t)port_low; *high = (in_port_t)port_high; return (ISC_R_SUCCESS); } -#else /* !HAVE_SYSCTLBYNAME */ +#else /* !HAVE_SYSCTLBYNAME */ static isc_result_t getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW; @@ -749,11 +771,12 @@ getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { return (ISC_R_FAILURE); } - if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) + if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) { return (ISC_R_RANGE); + } - *low = (in_port_t) port_low; - *high = (in_port_t) port_high; + *low = (in_port_t)port_low; + *high = (in_port_t)port_high; return (ISC_R_SUCCESS); } @@ -765,7 +788,7 @@ isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { int result = ISC_R_FAILURE; #if !defined(USE_SYSCTL_PORTRANGE) && defined(__linux) FILE *fp; -#endif +#endif /* if !defined(USE_SYSCTL_PORTRANGE) && defined(__linux) */ REQUIRE(low != NULL && high != NULL); @@ -791,42 +814,46 @@ isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { } fclose(fp); } -#else +#else /* if defined(USE_SYSCTL_PORTRANGE) */ UNUSED(af); -#endif +#endif /* if defined(USE_SYSCTL_PORTRANGE) */ if (result != ISC_R_SUCCESS) { *low = ISC_NET_PORTRANGELOW; *high = ISC_NET_PORTRANGEHIGH; } - return (ISC_R_SUCCESS); /* we currently never fail in this function */ + return (ISC_R_SUCCESS); /* we currently never fail in this function */ } void isc_net_disableipv4(void) { initialize(); - if (ipv4_result == ISC_R_SUCCESS) + if (ipv4_result == ISC_R_SUCCESS) { ipv4_result = ISC_R_DISABLED; + } } void isc_net_disableipv6(void) { initialize(); - if (ipv6_result == ISC_R_SUCCESS) + if (ipv6_result == ISC_R_SUCCESS) { ipv6_result = ISC_R_DISABLED; + } } void isc_net_enableipv4(void) { initialize(); - if (ipv4_result == ISC_R_DISABLED) + if (ipv4_result == ISC_R_DISABLED) { ipv4_result = ISC_R_SUCCESS; + } } void isc_net_enableipv6(void) { initialize(); - if (ipv6_result == ISC_R_DISABLED) + if (ipv6_result == ISC_R_DISABLED) { ipv6_result = ISC_R_SUCCESS; + } } diff --git a/lib/isc/unix/os.c b/lib/isc/unix/os.c index 79409cff..5ba4481d 100644 --- a/lib/isc/unix/os.c +++ b/lib/isc/unix/os.c @@ -3,18 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <isc/os.h> - #ifdef HAVE_SYSCONF #include <unistd.h> @@ -22,19 +18,19 @@ static inline long sysconf_ncpus(void) { #if defined(_SC_NPROCESSORS_ONLN) - return sysconf((_SC_NPROCESSORS_ONLN)); + return (sysconf((_SC_NPROCESSORS_ONLN))); #elif defined(_SC_NPROC_ONLN) - return sysconf((_SC_NPROC_ONLN)); -#else + return (sysconf((_SC_NPROC_ONLN))); +#else /* if defined(_SC_NPROCESSORS_ONLN) */ return (0); -#endif +#endif /* if defined(_SC_NPROCESSORS_ONLN) */ } #endif /* HAVE_SYSCONF */ #if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) -#include <sys/types.h> /* for FreeBSD */ -#include <sys/param.h> /* for NetBSD */ +#include <sys/param.h> /* for NetBSD */ #include <sys/sysctl.h> +#include <sys/types.h> /* for FreeBSD */ static int sysctl_ncpus(void) { @@ -42,12 +38,13 @@ sysctl_ncpus(void) { size_t len; len = sizeof(ncpu); - result = sysctlbyname("hw.ncpu", &ncpu, &len , 0, 0); - if (result != -1) + result = sysctlbyname("hw.ncpu", &ncpu, &len, 0, 0); + if (result != -1) { return (ncpu); + } return (0); } -#endif +#endif /* if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) */ unsigned int isc_os_ncpus(void) { @@ -55,13 +52,15 @@ isc_os_ncpus(void) { #if defined(HAVE_SYSCONF) ncpus = sysconf_ncpus(); -#endif +#endif /* if defined(HAVE_SYSCONF) */ #if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) - if (ncpus <= 0) + if (ncpus <= 0) { ncpus = sysctl_ncpus(); -#endif - if (ncpus <= 0) + } +#endif /* if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) */ + if (ncpus <= 0) { ncpus = 1; + } return ((unsigned int)ncpus); } diff --git a/lib/isc/unix/pk11_api.c b/lib/isc/unix/pk11_api.c index bbc55afe..400e0e5c 100644 --- a/lib/isc/unix/pk11_api.c +++ b/lib/isc/unix/pk11_api.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - -#include <string.h> #include <dlfcn.h> +#include <string.h> #include <isc/log.h> #include <isc/mem.h> @@ -25,12 +22,11 @@ #include <isc/thread.h> #include <isc/util.h> -#include <pkcs11/cryptoki.h> #include <pkcs11/pkcs11.h> #define KEEP_PKCS11_NAMES -#include <pk11/pk11.h> #include <pk11/internal.h> +#include <pk11/pk11.h> static void *hPK11 = NULL; static char loaderrmsg[1024]; @@ -39,24 +35,27 @@ CK_RV pkcs_C_Initialize(CK_VOID_PTR pReserved) { CK_C_Initialize sym; - if (hPK11 != NULL) - return (CKR_LIBRARY_ALREADY_INITIALIZED); + if (hPK11 != NULL) { + return (CKR_CRYPTOKI_ALREADY_INITIALIZED); + } hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); if (hPK11 == NULL) { snprintf(loaderrmsg, sizeof(loaderrmsg), - "dlopen(\"%s\") failed: %s\n", - pk11_get_lib_name(), dlerror()); - return (CKR_LIBRARY_FAILED_TO_LOAD); + "dlopen(\"%s\") failed: %s\n", pk11_get_lib_name(), + dlerror()); + return (CKR_LIBRARY_LOAD_FAILED); } sym = (CK_C_Initialize)dlsym(hPK11, "C_Initialize"); - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(pReserved); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(pReserved)); } -char *pk11_get_load_error_message(void) { +char * +pk11_get_load_error_message(void) { return (loaderrmsg); } @@ -65,34 +64,38 @@ pkcs_C_Finalize(CK_VOID_PTR pReserved) { CK_C_Finalize sym; CK_RV rv; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } sym = (CK_C_Finalize)dlsym(hPK11, "C_Finalize"); - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } rv = (*sym)(pReserved); - if ((rv == CKR_OK) && (dlclose(hPK11) != 0)) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if ((rv == CKR_OK) && (dlclose(hPK11) != 0)) { + return (CKR_LIBRARY_LOAD_FAILED); + } hPK11 = NULL; return (rv); } CK_RV pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, - CK_ULONG_PTR pulCount) -{ + CK_ULONG_PTR pulCount) { static CK_C_GetSlotList sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetSlotList)dlsym(hPK11, "C_GetSlotList"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(tokenPresent, pSlotList, pulCount); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(tokenPresent, pSlotList, pulCount)); } CK_RV @@ -100,62 +103,64 @@ pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { static CK_C_GetTokenInfo sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetTokenInfo)dlsym(hPK11, "C_GetTokenInfo"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, pInfo); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(slotID, pInfo)); } CK_RV pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) -{ + CK_MECHANISM_INFO_PTR pInfo) { static CK_C_GetMechanismInfo sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; - sym = (CK_C_GetMechanismInfo)dlsym(hPK11, - "C_GetMechanismInfo"); + sym = (CK_C_GetMechanismInfo)dlsym(hPK11, "C_GetMechanismInfo"); + } + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, type, pInfo); + return ((*sym)(slotID, type, pInfo)); } CK_RV -pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, - CK_VOID_PTR pApplication, - CK_RV (*Notify) (CK_SESSION_HANDLE hSession, - CK_NOTIFICATION event, - CK_VOID_PTR pApplication), - CK_SESSION_HANDLE_PTR phSession) -{ +pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, + CK_RV (*Notify)(CK_SESSION_HANDLE hSession, + CK_NOTIFICATION event, + CK_VOID_PTR pApplication), + CK_SESSION_HANDLE_PTR phSession) { static CK_C_OpenSession sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); + } if (hPK11 == NULL) { snprintf(loaderrmsg, sizeof(loaderrmsg), - "dlopen(\"%s\") failed: %s\n", - pk11_get_lib_name(), dlerror()); - return (CKR_LIBRARY_FAILED_TO_LOAD); + "dlopen(\"%s\") failed: %s\n", pk11_get_lib_name(), + dlerror()); + return (CKR_LIBRARY_LOAD_FAILED); } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_OpenSession)dlsym(hPK11, "C_OpenSession"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, flags, pApplication, Notify, phSession); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(slotID, flags, pApplication, Notify, phSession)); } CK_RV @@ -163,33 +168,36 @@ pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) { static CK_C_CloseSession sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_CloseSession)dlsym(hPK11, "C_CloseSession"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession)); } CK_RV pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, - CK_CHAR_PTR pPin, CK_ULONG usPinLen) -{ + CK_CHAR_PTR pPin, CK_ULONG usPinLen) { static CK_C_Login sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Login)dlsym(hPK11, "C_Login"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, userType, pPin, usPinLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, userType, pPin, usPinLen)); } CK_RV @@ -197,33 +205,36 @@ pkcs_C_Logout(CK_SESSION_HANDLE hSession) { static CK_C_Logout sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Logout)dlsym(hPK11, "C_Logout"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession)); } CK_RV pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) -{ + CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) { static CK_C_CreateObject sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_CreateObject)dlsym(hPK11, "C_CreateObject"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pTemplate, usCount, phObject); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pTemplate, usCount, phObject)); } CK_RV @@ -231,145 +242,153 @@ pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { static CK_C_DestroyObject sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DestroyObject)dlsym(hPK11, "C_DestroyObject"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, hObject)); } CK_RV pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) -{ + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_GetAttributeValue sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; - sym = (CK_C_GetAttributeValue)dlsym(hPK11, - "C_GetAttributeValue"); + sym = (CK_C_GetAttributeValue)dlsym(hPK11, "C_" + "GetAttributeValue"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject, pTemplate, usCount); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, hObject, pTemplate, usCount)); } CK_RV pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) -{ + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_SetAttributeValue sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; - sym = (CK_C_SetAttributeValue)dlsym(hPK11, - "C_SetAttributeValue"); + sym = (CK_C_SetAttributeValue)dlsym(hPK11, "C_" + "SetAttributeValue"); + } + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject, pTemplate, usCount); + return ((*sym)(hSession, hObject, pTemplate, usCount)); } CK_RV pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount) -{ + CK_ULONG usCount) { static CK_C_FindObjectsInit sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_FindObjectsInit)dlsym(hPK11, "C_FindObjectsInit"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pTemplate, usCount); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pTemplate, usCount)); } CK_RV pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, - CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) -{ + CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) { static CK_C_FindObjects sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_FindObjects)dlsym(hPK11, "C_FindObjects"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount)); } CK_RV -pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) -{ +pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { static CK_C_FindObjectsFinal sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; - sym = (CK_C_FindObjectsFinal)dlsym(hPK11, - "C_FindObjectsFinal"); + sym = (CK_C_FindObjectsFinal)dlsym(hPK11, "C_FindObjectsFinal"); + } + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + return ((*sym)(hSession)); } CK_RV pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ + CK_OBJECT_HANDLE hKey) { static CK_C_EncryptInit sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_EncryptInit)dlsym(hPK11, "C_EncryptInit"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, - CK_ULONG_PTR pulEncryptedDataLen) -{ + CK_ULONG_PTR pulEncryptedDataLen) { static CK_C_Encrypt sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Encrypt)dlsym(hPK11, "C_Encrypt"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, - pEncryptedData, pulEncryptedDataLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pData, ulDataLen, pEncryptedData, + pulEncryptedDataLen)); } CK_RV @@ -377,305 +396,311 @@ pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { static CK_C_DigestInit sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestInit)dlsym(hPK11, "C_DigestInit"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism)); } CK_RV pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ + CK_ULONG ulPartLen) { static CK_C_DigestUpdate sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestUpdate)dlsym(hPK11, "C_DigestUpdate"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ + CK_ULONG_PTR pulDigestLen) { static CK_C_DigestFinal sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestFinal)dlsym(hPK11, "C_DigestFinal"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pDigest, pulDigestLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pDigest, pulDigestLen)); } CK_RV pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ + CK_OBJECT_HANDLE hKey) { static CK_C_SignInit sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignInit)dlsym(hPK11, "C_SignInit"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV -pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ +pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_Sign sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Sign)dlsym(hPK11, "C_Sign"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, pSignature, pulSignatureLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pData, ulDataLen, pSignature, + pulSignatureLen)); } CK_RV pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ + CK_ULONG ulPartLen) { static CK_C_SignUpdate sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignUpdate)dlsym(hPK11, "C_SignUpdate"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ + CK_ULONG_PTR pulSignatureLen) { static CK_C_SignFinal sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignFinal)dlsym(hPK11, "C_SignFinal"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSignature, pulSignatureLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pSignature, pulSignatureLen)); } CK_RV pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ + CK_OBJECT_HANDLE hKey) { static CK_C_VerifyInit sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyInit)dlsym(hPK11, "C_VerifyInit"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV -pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ +pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_Verify sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Verify)dlsym(hPK11, "C_Verify"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen)); } CK_RV pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ + CK_ULONG ulPartLen) { static CK_C_VerifyUpdate sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyUpdate)dlsym(hPK11, "C_VerifyUpdate"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ + CK_ULONG ulSignatureLen) { static CK_C_VerifyFinal sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyFinal)dlsym(hPK11, "C_VerifyFinal"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSignature, ulSignatureLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pSignature, ulSignatureLen)); } CK_RV pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey) -{ + CK_OBJECT_HANDLE_PTR phKey) { static CK_C_GenerateKey sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateKey)dlsym(hPK11, "C_GenerateKey"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, pTemplate, ulCount, phKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, pTemplate, ulCount, phKey)); } CK_RV -pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, +pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, - CK_OBJECT_HANDLE_PTR phPublicKey) -{ + CK_OBJECT_HANDLE_PTR phPublicKey) { static CK_C_GenerateKeyPair sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateKeyPair)dlsym(hPK11, "C_GenerateKeyPair"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, - pMechanism, - pPublicKeyTemplate, - usPublicKeyAttributeCount, - pPrivateKeyTemplate, - usPrivateKeyAttributeCount, - phPrivateKey, - phPublicKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, pPublicKeyTemplate, + usPublicKeyAttributeCount, pPrivateKeyTemplate, + usPrivateKeyAttributeCount, phPrivateKey, phPublicKey)); } CK_RV pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) -{ + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_DeriveKey sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DeriveKey)dlsym(hPK11, "C_DeriveKey"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, - pMechanism, - hBaseKey, - pTemplate, - ulAttributeCount, - phKey); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pMechanism, hBaseKey, pTemplate, + ulAttributeCount, phKey)); } CK_RV pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, - CK_ULONG ulSeedLen) -{ + CK_ULONG ulSeedLen) { static CK_C_SeedRandom sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SeedRandom)dlsym(hPK11, "C_SeedRandom"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSeed, ulSeedLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, pSeed, ulSeedLen)); } CK_RV pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, - CK_ULONG ulRandomLen) -{ + CK_ULONG ulRandomLen) { static CK_C_GenerateRandom sym = NULL; static void *pPK11 = NULL; - if (hPK11 == NULL) - return (CKR_LIBRARY_FAILED_TO_LOAD); + if (hPK11 == NULL) { + return (CKR_LIBRARY_LOAD_FAILED); + } if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateRandom)dlsym(hPK11, "C_GenerateRandom"); } - if (sym == NULL) - return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, RandomData, ulRandomLen); + if (sym == NULL) { + return (CKR_FUNCTION_NOT_SUPPORTED); + } + return ((*sym)(hSession, RandomData, ulRandomLen)); } diff --git a/lib/isc/unix/resource.c b/lib/isc/unix/resource.c index b3567ef9..71143b77 100644 --- a/lib/isc/unix/resource.c +++ b/lib/isc/unix/resource.c @@ -3,21 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <inttypes.h> #include <stdbool.h> - -#include <sys/types.h> -#include <sys/time.h> /* Required on some systems for <sys/resource.h>. */ #include <sys/resource.h> +#include <sys/time.h> /* Required on some systems for <sys/resource.h>. */ +#include <sys/types.h> #include <isc/platform.h> #include <isc/resource.h> @@ -25,8 +21,8 @@ #include <isc/util.h> #ifdef __linux__ -#include <linux/fs.h> /* To get the large NR_OPEN. */ -#endif +#include <linux/fs.h> /* To get the large NR_OPEN. */ +#endif /* ifdef __linux__ */ #include "errno2result.h" @@ -50,30 +46,30 @@ resource2rlim(isc_resource_t resource, int *rlim_resource) { case isc_resource_lockedmemory: #ifdef RLIMIT_MEMLOCK *rlim_resource = RLIMIT_MEMLOCK; -#else +#else /* ifdef RLIMIT_MEMLOCK */ result = ISC_R_NOTIMPLEMENTED; -#endif +#endif /* ifdef RLIMIT_MEMLOCK */ break; case isc_resource_openfiles: #ifdef RLIMIT_NOFILE *rlim_resource = RLIMIT_NOFILE; -#else +#else /* ifdef RLIMIT_NOFILE */ result = ISC_R_NOTIMPLEMENTED; -#endif +#endif /* ifdef RLIMIT_NOFILE */ break; case isc_resource_processes: #ifdef RLIMIT_NPROC *rlim_resource = RLIMIT_NPROC; -#else +#else /* ifdef RLIMIT_NPROC */ result = ISC_R_NOTIMPLEMENTED; -#endif +#endif /* ifdef RLIMIT_NPROC */ break; case isc_resource_residentsize: #ifdef RLIMIT_RSS *rlim_resource = RLIMIT_RSS; -#else +#else /* ifdef RLIMIT_RSS */ result = ISC_R_NOTIMPLEMENTED; -#endif +#endif /* ifdef RLIMIT_RSS */ break; case isc_resource_stacksize: *rlim_resource = RLIMIT_STACK; @@ -102,13 +98,13 @@ isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { isc_result_t result; result = resource2rlim(resource, &unixresource); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } - if (value == ISC_RESOURCE_UNLIMITED) + if (value == ISC_RESOURCE_UNLIMITED) { rlim_value = RLIM_INFINITY; - - else { + } else { /* * isc_resourcevalue_t was chosen as an unsigned 64 bit * integer so that it could contain the maximum range of @@ -117,17 +113,17 @@ isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { * rlim_t is not overflowed. */ isc_resourcevalue_t rlim_max; - bool rlim_t_is_signed = - (((double)(rlim_t)-1) < 0); + bool rlim_t_is_signed = (((double)(rlim_t)-1) < 0); - if (rlim_t_is_signed) - rlim_max = ~((rlim_t)1 << - (sizeof(rlim_t) * 8 - 1)); - else + if (rlim_t_is_signed) { + rlim_max = ~((rlim_t)1 << (sizeof(rlim_t) * 8 - 1)); + } else { rlim_max = (rlim_t)-1; + } - if (value > rlim_max) + if (value > rlim_max) { value = rlim_max; + } rlim_value = value; } @@ -135,8 +131,9 @@ isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { rl.rlim_cur = rl.rlim_max = rlim_value; unixresult = setrlimit(unixresource, &rl); - if (unixresult == 0) + if (unixresult == 0) { return (ISC_R_SUCCESS); + } #if defined(OPEN_MAX) && defined(__APPLE__) /* @@ -148,13 +145,14 @@ isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { rl.rlim_cur = OPEN_MAX; unixresult = setrlimit(unixresource, &rl); - if (unixresult == 0) + if (unixresult == 0) { return (ISC_R_SUCCESS); + } } #elif defined(__linux__) #ifndef NR_OPEN -#define NR_OPEN (1024*1024) -#endif +#define NR_OPEN (1024 * 1024) +#endif /* ifndef NR_OPEN */ /* * Some Linux kernels don't accept RLIM_INFINIT; the maximum @@ -163,16 +161,18 @@ isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { rl.rlim_cur = rl.rlim_max = NR_OPEN; unixresult = setrlimit(unixresource, &rl); - if (unixresult == 0) + if (unixresult == 0) { return (ISC_R_SUCCESS); + } } -#endif +#endif /* if defined(OPEN_MAX) && defined(__APPLE__) */ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { if (getrlimit(unixresource, &rl) == 0) { rl.rlim_cur = rl.rlim_max; unixresult = setrlimit(unixresource, &rl); - if (unixresult == 0) + if (unixresult == 0) { return (ISC_R_SUCCESS); + } } } return (isc__errno2result(errno)); diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 78c41fce..1a699d69 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,25 +11,23 @@ /*! \file */ -#include <config.h> - #include <inttypes.h> #include <stdbool.h> - #include <sys/param.h> -#include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> -#ifdef HAVE_SYS_SYSCTL_H +#include <sys/types.h> +#if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) #include <sys/sysctl.h> -#endif +#endif /* if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux__) */ #include <sys/time.h> #include <sys/uio.h> #if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) #include <linux/netlink.h> #include <linux/rtnetlink.h> -#endif +#endif /* if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) \ + */ #include <errno.h> #include <fcntl.h> @@ -41,7 +39,6 @@ #include <isc/buffer.h> #include <isc/condition.h> #include <isc/formatcheck.h> -#include <isc/json.h> #include <isc/list.h> #include <isc/log.h> #include <isc/mem.h> @@ -60,34 +57,38 @@ #include <isc/task.h> #include <isc/thread.h> #include <isc/util.h> -#include <isc/xml.h> #ifdef ISC_PLATFORM_HAVESYSUNH #include <sys/un.h> -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ #ifdef HAVE_KQUEUE #include <sys/event.h> -#endif +#endif /* ifdef HAVE_KQUEUE */ #ifdef HAVE_EPOLL_CREATE1 #include <sys/epoll.h> -#endif +#endif /* ifdef HAVE_EPOLL_CREATE1 */ #if defined(HAVE_SYS_DEVPOLL_H) #include <sys/devpoll.h> #elif defined(HAVE_DEVPOLL_H) #include <devpoll.h> -#endif +#endif /* if defined(HAVE_SYS_DEVPOLL_H) */ #include <netinet/tcp.h> #include "errno2result.h" -#if defined(SO_BSDCOMPAT) && defined(__linux__) -#include <sys/utsname.h> -#endif - #ifdef ENABLE_TCP_FASTOPEN #include <netinet/tcp.h> -#endif +#endif /* ifdef ENABLE_TCP_FASTOPEN */ + +#ifdef HAVE_JSON_C +#include <json_object.h> +#endif /* HAVE_JSON_C */ + +#ifdef HAVE_LIBXML2 +#include <libxml/xmlwriter.h> +#define ISC_XMLCHAR (const xmlChar *) +#endif /* HAVE_LIBXML2 */ /*% * Choose the most preferable multiplex method. @@ -99,12 +100,11 @@ #elif defined(HAVE_SYS_DEVPOLL_H) || defined(HAVE_DEVPOLL_H) #define USE_DEVPOLL typedef struct { - unsigned int want_read : 1, - want_write : 1; + unsigned int want_read : 1, want_write : 1; } pollinfo_t; -#else +#else /* if defined(HAVE_KQUEUE) */ #define USE_SELECT -#endif /* HAVE_KQUEUE */ +#endif /* HAVE_KQUEUE */ /* * Set by the -T dscp option on the command line. If set to a value @@ -136,13 +136,13 @@ int isc_dscp_check_value = -1; #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) #ifdef TUNE_LARGE #define ISC_SOCKET_MAXSOCKETS 21000 -#else +#else /* ifdef TUNE_LARGE */ #define ISC_SOCKET_MAXSOCKETS 4096 #endif /* TUNE_LARGE */ #elif defined(USE_SELECT) #define ISC_SOCKET_MAXSOCKETS FD_SETSIZE -#endif /* USE_KQUEUE... */ -#endif /* ISC_SOCKET_MAXSOCKETS */ +#endif /* USE_KQUEUE... */ +#endif /* ISC_SOCKET_MAXSOCKETS */ #ifdef USE_SELECT /*% @@ -151,8 +151,8 @@ int isc_dscp_check_value = -1; */ #ifdef __APPLE__ #define _DARWIN_UNLIMITED_SELECT -#endif /* __APPLE__ */ -#endif /* USE_SELECT */ +#endif /* __APPLE__ */ +#endif /* USE_SELECT */ #ifdef ISC_SOCKET_USE_POLLWATCH /*% @@ -180,16 +180,17 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; #ifndef ISC_SOCKET_POLLWATCH_TIMEOUT #define ISC_SOCKET_POLLWATCH_TIMEOUT 10 -#endif /* ISC_SOCKET_POLLWATCH_TIMEOUT */ -#endif /* ISC_SOCKET_USE_POLLWATCH */ +#endif /* ISC_SOCKET_POLLWATCH_TIMEOUT */ +#endif /* ISC_SOCKET_USE_POLLWATCH */ /*% * Per-FD lock buckets, we shuffle them around a bit as FDs come in herds. */ -#define FDLOCK_BITS 10 -#define FDLOCK_COUNT (1<<FDLOCK_BITS) -#define FDLOCK_ID(fd) (((fd)%(FDLOCK_COUNT)>>(FDLOCK_BITS/2)) |\ - (((fd)<<(FDLOCK_BITS/2))%(FDLOCK_COUNT))) +#define FDLOCK_BITS 10 +#define FDLOCK_COUNT (1 << FDLOCK_BITS) +#define FDLOCK_ID(fd) \ + (((fd) % (FDLOCK_COUNT) >> (FDLOCK_BITS / 2)) | \ + (((fd) << (FDLOCK_BITS / 2)) % (FDLOCK_COUNT))) /*% * Maximum number of events communicated with the kernel. There should normally @@ -198,12 +199,13 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) #ifndef ISC_SOCKET_MAXEVENTS #ifdef TUNE_LARGE -#define ISC_SOCKET_MAXEVENTS 2048 -#else -#define ISC_SOCKET_MAXEVENTS 64 +#define ISC_SOCKET_MAXEVENTS 2048 +#else /* ifdef TUNE_LARGE */ +#define ISC_SOCKET_MAXEVENTS 64 #endif /* TUNE_LARGE */ -#endif -#endif +#endif /* ifndef ISC_SOCKET_MAXEVENTS */ +#endif /* if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) \ + * */ /*% * Some systems define the socket length argument as an int, some as size_t, @@ -211,7 +213,7 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; */ #ifndef socklen_t #define socklen_t unsigned int -#endif +#endif /* ifndef socklen_t */ /*% * Define what the possible "soft" errors can be. These are non-fatal returns @@ -221,11 +223,9 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; * from recv() but will have errno==0. This is broken, but we have to * work around it here. */ -#define SOFT_ERROR(e) ((e) == EAGAIN || \ - (e) == EWOULDBLOCK || \ - (e) == ENOBUFS || \ - (e) == EINTR || \ - (e) == 0) +#define SOFT_ERROR(e) \ + ((e) == EAGAIN || (e) == EWOULDBLOCK || (e) == ENOBUFS || \ + (e) == EINTR || (e) == 0) #define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x) @@ -236,22 +236,22 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; * DLVL(50) -- Event tracing, including receiving/sending completion events. * DLVL(20) -- Socket creation/destruction. */ -#define TRACE_LEVEL 90 -#define CORRECTNESS_LEVEL 70 -#define IOEVENT_LEVEL 60 -#define EVENT_LEVEL 50 -#define CREATION_LEVEL 20 - -#define TRACE DLVL(TRACE_LEVEL) -#define CORRECTNESS DLVL(CORRECTNESS_LEVEL) -#define IOEVENT DLVL(IOEVENT_LEVEL) -#define EVENT DLVL(EVENT_LEVEL) -#define CREATION DLVL(CREATION_LEVEL) +#define TRACE_LEVEL 90 +#define CORRECTNESS_LEVEL 70 +#define IOEVENT_LEVEL 60 +#define EVENT_LEVEL 50 +#define CREATION_LEVEL 20 + +#define TRACE DLVL(TRACE_LEVEL) +#define CORRECTNESS DLVL(CORRECTNESS_LEVEL) +#define IOEVENT DLVL(IOEVENT_LEVEL) +#define EVENT DLVL(EVENT_LEVEL) +#define CREATION DLVL(CREATION_LEVEL) typedef isc_event_t intev_t; -#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') -#define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC) +#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') +#define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC) /*! * IPv6 control information. If the socket is an IPv6 socket we want @@ -259,8 +259,8 @@ typedef isc_event_t intev_t; * set them on outgoing packets. */ #ifndef USE_CMSG -#define USE_CMSG 1 -#endif +#define USE_CMSG 1 +#endif /* ifndef USE_CMSG */ /*% * NetBSD and FreeBSD can timestamp packets. XXXMLG Should we have @@ -269,25 +269,17 @@ typedef isc_event_t intev_t; */ #ifdef SO_TIMESTAMP #ifndef USE_CMSG -#define USE_CMSG 1 -#endif +#define USE_CMSG 1 +#endif /* ifndef USE_CMSG */ +#endif /* ifdef SO_TIMESTAMP */ + +#if defined(SO_RCVBUF) && defined(ISC_RECV_BUFFER_SIZE) +#define SET_RCVBUF #endif -/*% - * The size to raise the receive buffer to (from BIND 8). - */ -#ifdef TUNE_LARGE -#ifdef sun -#define RCVBUFSIZE (1*1024*1024) -#define SNDBUFSIZE (1*1024*1024) -#else -#define RCVBUFSIZE (16*1024*1024) -#define SNDBUFSIZE (16*1024*1024) +#if defined(SO_SNDBUF) && defined(ISC_SEND_BUFFER_SIZE) +#define SET_SNDBUF #endif -#else -#define RCVBUFSIZE (32*1024) -#define SNDBUFSIZE (32*1024) -#endif /* TUNE_LARGE */ /*% * Instead of calculating the cmsgbuf lengths every time we take @@ -297,27 +289,32 @@ typedef isc_event_t intev_t; */ #if defined(USE_CMSG) #define CMSG_SP_IN6PKT 40 -#else +#else /* if defined(USE_CMSG) */ #define CMSG_SP_IN6PKT 0 -#endif +#endif /* if defined(USE_CMSG) */ #if defined(USE_CMSG) && defined(SO_TIMESTAMP) #define CMSG_SP_TIMESTAMP 32 -#else +#else /* if defined(USE_CMSG) && defined(SO_TIMESTAMP) */ #define CMSG_SP_TIMESTAMP 0 -#endif +#endif /* if defined(USE_CMSG) && defined(SO_TIMESTAMP) */ #if defined(USE_CMSG) && (defined(IPV6_TCLASS) || defined(IP_TOS)) #define CMSG_SP_TCTOS 24 -#else +#else /* if defined(USE_CMSG) && (defined(IPV6_TCLASS) || defined(IP_TOS)) */ #define CMSG_SP_TCTOS 0 -#endif +#endif /* if defined(USE_CMSG) && (defined(IPV6_TCLASS) || defined(IP_TOS)) */ #define CMSG_SP_INT 24 /* Align cmsg buffers to be safe on SPARC etc. */ -#define RECVCMSGBUFLEN ISC_ALIGN(2*(CMSG_SP_IN6PKT + CMSG_SP_TIMESTAMP + CMSG_SP_TCTOS)+1, sizeof(void*)) -#define SENDCMSGBUFLEN ISC_ALIGN(2*(CMSG_SP_IN6PKT + CMSG_SP_INT + CMSG_SP_TCTOS)+1, sizeof(void*)) +#define RECVCMSGBUFLEN \ + ISC_ALIGN(2 * (CMSG_SP_IN6PKT + CMSG_SP_TIMESTAMP + CMSG_SP_TCTOS) + \ + 1, \ + sizeof(void *)) +#define SENDCMSGBUFLEN \ + ISC_ALIGN(2 * (CMSG_SP_IN6PKT + CMSG_SP_INT + CMSG_SP_TCTOS) + 1, \ + sizeof(void *)) /*% * The number of times a send operation is repeated if the result is EINTR. @@ -332,162 +329,171 @@ typedef struct isc__socketthread isc__socketthread_t; struct isc__socket { /* Not locked. */ - isc_socket_t common; - isc__socketmgr_t *manager; - isc_mutex_t lock; - isc_sockettype_t type; - const isc_statscounter_t *statsindex; - isc_refcount_t references; + isc_socket_t common; + isc__socketmgr_t *manager; + isc_mutex_t lock; + isc_sockettype_t type; + const isc_statscounter_t *statsindex; + isc_refcount_t references; /* Locked by socket lock. */ - ISC_LINK(isc__socket_t) link; - int fd; - int pf; - int threadid; - char name[16]; - void * tag; - - ISC_LIST(isc_socketevent_t) send_list; - ISC_LIST(isc_socketevent_t) recv_list; - ISC_LIST(isc_socket_newconnev_t) accept_list; - ISC_LIST(isc_socket_connev_t) connect_list; - - isc_sockaddr_t peer_address; /* remote address */ - - unsigned int listener : 1, /* listener socket */ - connected : 1, - connecting : 1, /* connect pending */ - bound : 1, /* bound to local addr */ - dupped : 1, - active : 1, /* currently active */ - pktdscp : 1; /* per packet dscp */ + ISC_LINK(isc__socket_t) link; + int fd; + int pf; + int threadid; + char name[16]; + void *tag; + + ISC_LIST(isc_socketevent_t) send_list; + ISC_LIST(isc_socketevent_t) recv_list; + ISC_LIST(isc_socket_newconnev_t) accept_list; + ISC_LIST(isc_socket_connev_t) connect_list; + + isc_sockaddr_t peer_address; /* remote address */ + + unsigned int listener : 1, /* listener socket */ + connected : 1, connecting : 1, /* connect pending + * */ + bound : 1, /* bound to local addr */ + dupped : 1, active : 1, /* currently active */ + pktdscp : 1; /* per packet dscp */ #ifdef ISC_PLATFORM_RECVOVERFLOW - unsigned char overflow; /* used for MSG_TRUNC fake */ -#endif + unsigned char overflow; /* used for MSG_TRUNC fake */ +#endif /* ifdef ISC_PLATFORM_RECVOVERFLOW */ - unsigned int dscp; + unsigned int dscp; }; -#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) +#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') +#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) struct isc__socketmgr { /* Not locked. */ - isc_socketmgr_t common; - isc_mem_t *mctx; - isc_mutex_t lock; - isc_stats_t *stats; - int nthreads; - isc__socketthread_t *threads; - unsigned int maxsocks; + isc_socketmgr_t common; + isc_mem_t *mctx; + isc_mutex_t lock; + isc_stats_t *stats; + int nthreads; + isc__socketthread_t *threads; + unsigned int maxsocks; /* Locked by manager lock. */ - ISC_LIST(isc__socket_t) socklist; - int reserved; /* unlocked */ - isc_condition_t shutdown_ok; - int maxudp; + ISC_LIST(isc__socket_t) socklist; + int reserved; /* unlocked */ + isc_condition_t shutdown_ok; + size_t maxudp; }; struct isc__socketthread { - isc__socketmgr_t * manager; - int threadid; - isc_thread_t thread; - int pipe_fds[2]; - isc_mutex_t *fdlock; + isc__socketmgr_t *manager; + int threadid; + isc_thread_t thread; + int pipe_fds[2]; + isc_mutex_t *fdlock; /* Locked by fdlock. */ - isc__socket_t **fds; - int *fdstate; + isc__socket_t **fds; + int *fdstate; #ifdef USE_KQUEUE - int kqueue_fd; - int nevents; - struct kevent *events; -#endif /* USE_KQUEUE */ + int kqueue_fd; + int nevents; + struct kevent *events; +#endif /* USE_KQUEUE */ #ifdef USE_EPOLL - int epoll_fd; - int nevents; - struct epoll_event *events; - uint32_t *epoll_events; -#endif /* USE_EPOLL */ + int epoll_fd; + int nevents; + struct epoll_event *events; + uint32_t *epoll_events; +#endif /* USE_EPOLL */ #ifdef USE_DEVPOLL - int devpoll_fd; - isc_resourcevalue_t open_max; - unsigned int calls; - int nevents; - struct pollfd *events; - pollinfo_t *fdpollinfo; -#endif /* USE_DEVPOLL */ + int devpoll_fd; + isc_resourcevalue_t open_max; + unsigned int calls; + int nevents; + struct pollfd *events; + pollinfo_t *fdpollinfo; +#endif /* USE_DEVPOLL */ #ifdef USE_SELECT - int fd_bufsize; - fd_set *read_fds; - fd_set *read_fds_copy; - fd_set *write_fds; - fd_set *write_fds_copy; - int maxfd; -#endif /* USE_SELECT */ + int fd_bufsize; + fd_set *read_fds; + fd_set *read_fds_copy; + fd_set *write_fds; + fd_set *write_fds_copy; + int maxfd; +#endif /* USE_SELECT */ }; - -#define CLOSED 0 /* this one must be zero */ -#define MANAGED 1 -#define CLOSE_PENDING 2 +#define CLOSED 0 /* this one must be zero */ +#define MANAGED 1 +#define CLOSE_PENDING 2 /* * send() and recv() iovec counts */ -#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) +#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) #ifdef ISC_PLATFORM_RECVOVERFLOW -# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER + 1) -#else -# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) -#endif +#define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER + 1) +#else /* ifdef ISC_PLATFORM_RECVOVERFLOW */ +#define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) +#endif /* ifdef ISC_PLATFORM_RECVOVERFLOW */ -static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, - isc_sockettype_t type, - isc_socket_t **socketp, - isc_socket_t *dup_socket); -static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **); -static void send_senddone_event(isc__socket_t *, isc_socketevent_t **); -static void send_connectdone_event(isc__socket_t *, isc_socket_connev_t **); -static void free_socket(isc__socket_t **); -static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t, - isc__socket_t **); -static void destroy(isc__socket_t **); -static void internal_accept(isc__socket_t *); -static void internal_connect(isc__socket_t *); -static void internal_recv(isc__socket_t *); -static void internal_send(isc__socket_t *); -static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *); -static void build_msghdr_send(isc__socket_t *, char *, isc_socketevent_t *, - struct msghdr *, struct iovec *, size_t *); -static void build_msghdr_recv(isc__socket_t *, char *, isc_socketevent_t *, - struct msghdr *, struct iovec *, size_t *); -static bool process_ctlfd(isc__socketthread_t *thread); -static void setdscp(isc__socket_t *sock, isc_dscp_t dscp); - -#define SELECT_POKE_SHUTDOWN (-1) -#define SELECT_POKE_NOTHING (-2) -#define SELECT_POKE_READ (-3) -#define SELECT_POKE_ACCEPT (-3) /*%< Same as _READ */ -#define SELECT_POKE_WRITE (-4) -#define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */ -#define SELECT_POKE_CLOSE (-5) +static isc_result_t +socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp, isc_socket_t *dup_socket); +static void +send_recvdone_event(isc__socket_t *, isc_socketevent_t **); +static void +send_senddone_event(isc__socket_t *, isc_socketevent_t **); +static void +send_connectdone_event(isc__socket_t *, isc_socket_connev_t **); +static void +free_socket(isc__socket_t **); +static isc_result_t +allocate_socket(isc__socketmgr_t *, isc_sockettype_t, isc__socket_t **); +static void +destroy(isc__socket_t **); +static void +internal_accept(isc__socket_t *); +static void +internal_connect(isc__socket_t *); +static void +internal_recv(isc__socket_t *); +static void +internal_send(isc__socket_t *); +static void +process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *); +static void +build_msghdr_send(isc__socket_t *, char *, isc_socketevent_t *, struct msghdr *, + struct iovec *, size_t *); +static void +build_msghdr_recv(isc__socket_t *, char *, isc_socketevent_t *, struct msghdr *, + struct iovec *, size_t *); +static bool +process_ctlfd(isc__socketthread_t *thread); +static void +setdscp(isc__socket_t *sock, isc_dscp_t dscp); + +#define SELECT_POKE_SHUTDOWN (-1) +#define SELECT_POKE_NOTHING (-2) +#define SELECT_POKE_READ (-3) +#define SELECT_POKE_ACCEPT (-3) /*%< Same as _READ */ +#define SELECT_POKE_WRITE (-4) +#define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */ +#define SELECT_POKE_CLOSE (-5) /*% * Shortcut index arrays to get access to statistics counters. */ -enum { - STATID_OPEN = 0, - STATID_OPENFAIL = 1, - STATID_CLOSE = 2, - STATID_BINDFAIL = 3, - STATID_CONNECTFAIL = 4, - STATID_CONNECT = 5, - STATID_ACCEPTFAIL = 6, - STATID_ACCEPT = 7, - STATID_SENDFAIL = 8, - STATID_RECVFAIL = 9, - STATID_ACTIVE = 10 -}; +enum { STATID_OPEN = 0, + STATID_OPENFAIL = 1, + STATID_CLOSE = 2, + STATID_BINDFAIL = 3, + STATID_CONNECTFAIL = 4, + STATID_CONNECT = 5, + STATID_ACCEPTFAIL = 6, + STATID_ACCEPT = 7, + STATID_SENDFAIL = 8, + STATID_RECVFAIL = 9, + STATID_ACTIVE = 10 }; static const isc_statscounter_t udp4statsindex[] = { isc_sockstatscounter_udp4open, isc_sockstatscounter_udp4openfail, @@ -515,42 +521,27 @@ static const isc_statscounter_t udp6statsindex[] = { isc_sockstatscounter_udp6active }; static const isc_statscounter_t tcp4statsindex[] = { - isc_sockstatscounter_tcp4open, - isc_sockstatscounter_tcp4openfail, - isc_sockstatscounter_tcp4close, - isc_sockstatscounter_tcp4bindfail, - isc_sockstatscounter_tcp4connectfail, - isc_sockstatscounter_tcp4connect, - isc_sockstatscounter_tcp4acceptfail, - isc_sockstatscounter_tcp4accept, - isc_sockstatscounter_tcp4sendfail, - isc_sockstatscounter_tcp4recvfail, + isc_sockstatscounter_tcp4open, isc_sockstatscounter_tcp4openfail, + isc_sockstatscounter_tcp4close, isc_sockstatscounter_tcp4bindfail, + isc_sockstatscounter_tcp4connectfail, isc_sockstatscounter_tcp4connect, + isc_sockstatscounter_tcp4acceptfail, isc_sockstatscounter_tcp4accept, + isc_sockstatscounter_tcp4sendfail, isc_sockstatscounter_tcp4recvfail, isc_sockstatscounter_tcp4active }; static const isc_statscounter_t tcp6statsindex[] = { - isc_sockstatscounter_tcp6open, - isc_sockstatscounter_tcp6openfail, - isc_sockstatscounter_tcp6close, - isc_sockstatscounter_tcp6bindfail, - isc_sockstatscounter_tcp6connectfail, - isc_sockstatscounter_tcp6connect, - isc_sockstatscounter_tcp6acceptfail, - isc_sockstatscounter_tcp6accept, - isc_sockstatscounter_tcp6sendfail, - isc_sockstatscounter_tcp6recvfail, + isc_sockstatscounter_tcp6open, isc_sockstatscounter_tcp6openfail, + isc_sockstatscounter_tcp6close, isc_sockstatscounter_tcp6bindfail, + isc_sockstatscounter_tcp6connectfail, isc_sockstatscounter_tcp6connect, + isc_sockstatscounter_tcp6acceptfail, isc_sockstatscounter_tcp6accept, + isc_sockstatscounter_tcp6sendfail, isc_sockstatscounter_tcp6recvfail, isc_sockstatscounter_tcp6active }; static const isc_statscounter_t unixstatsindex[] = { - isc_sockstatscounter_unixopen, - isc_sockstatscounter_unixopenfail, - isc_sockstatscounter_unixclose, - isc_sockstatscounter_unixbindfail, - isc_sockstatscounter_unixconnectfail, - isc_sockstatscounter_unixconnect, - isc_sockstatscounter_unixacceptfail, - isc_sockstatscounter_unixaccept, - isc_sockstatscounter_unixsendfail, - isc_sockstatscounter_unixrecvfail, + isc_sockstatscounter_unixopen, isc_sockstatscounter_unixopenfail, + isc_sockstatscounter_unixclose, isc_sockstatscounter_unixbindfail, + isc_sockstatscounter_unixconnectfail, isc_sockstatscounter_unixconnect, + isc_sockstatscounter_unixacceptfail, isc_sockstatscounter_unixaccept, + isc_sockstatscounter_unixsendfail, isc_sockstatscounter_unixrecvfail, isc_sockstatscounter_unixactive }; static const isc_statscounter_t rawstatsindex[] = { @@ -572,45 +563,42 @@ gen_threadid(isc__socket_t *sock); static int gen_threadid(isc__socket_t *sock) { - return sock->fd % sock->manager->nthreads; + return (sock->fd % sock->manager->nthreads); } static void -manager_log(isc__socketmgr_t *sockmgr, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); +manager_log(isc__socketmgr_t *sockmgr, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) + ISC_FORMAT_PRINTF(5, 6); static void -manager_log(isc__socketmgr_t *sockmgr, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) -{ +manager_log(isc__socketmgr_t *sockmgr, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; - if (! isc_log_wouldlog(isc_lctx, level)) + if (!isc_log_wouldlog(isc_lctx, level)) { return; + } va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); - isc_log_write(isc_lctx, category, module, level, - "sockmgr %p: %s", sockmgr, msgbuf); + isc_log_write(isc_lctx, category, module, level, "sockmgr %p: %s", + sockmgr, msgbuf); } static void -thread_log(isc__socketthread_t *thread, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); +thread_log(isc__socketthread_t *thread, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) + ISC_FORMAT_PRINTF(5, 6); static void -thread_log(isc__socketthread_t *thread, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) -{ +thread_log(isc__socketthread_t *thread, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; - if (! isc_log_wouldlog(isc_lctx, level)) { + if (!isc_log_wouldlog(isc_lctx, level)) { return; } @@ -619,8 +607,8 @@ thread_log(isc__socketthread_t *thread, va_end(ap); isc_log_write(isc_lctx, category, module, level, - "sockmgr %p thread %d: %s", - thread->manager, thread->threadid, msgbuf); + "sockmgr %p thread %d: %s", thread->manager, + thread->threadid, msgbuf); } static void @@ -630,14 +618,14 @@ socket_log(isc__socket_t *sock, const isc_sockaddr_t *address, static void socket_log(isc__socket_t *sock, const isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) -{ + const char *fmt, ...) { char msgbuf[2048]; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; va_list ap; - if (! isc_log_wouldlog(isc_lctx, level)) + if (!isc_log_wouldlog(isc_lctx, level)) { return; + } va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); @@ -660,8 +648,9 @@ static inline void inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) { REQUIRE(counterid != -1); - if (stats != NULL) + if (stats != NULL) { isc_stats_increment(stats, counterid); + } } /*% @@ -671,8 +660,9 @@ static inline void dec_stats(isc_stats_t *stats, isc_statscounter_t counterid) { REQUIRE(counterid != -1); - if (stats != NULL) + if (stats != NULL) { isc_stats_decrement(stats, counterid); + } } static inline isc_result_t @@ -713,12 +703,19 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) { event.data.fd = fd; op = (oldevents == 0U) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; + if (thread->fds[fd] != NULL) { + LOCK(&thread->fds[fd]->lock); + } ret = epoll_ctl(thread->epoll_fd, op, fd, &event); + if (thread->fds[fd] != NULL) { + UNLOCK(&thread->fds[fd]->lock); + } if (ret == -1) { if (errno == EEXIST) { UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_ctl(ADD/MOD) returned " - "EEXIST for fd %d", fd); + "EEXIST for fd %d", + fd); } result = isc__errno2result(errno); } @@ -726,7 +723,6 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) { return (result); #elif defined(USE_DEVPOLL) struct pollfd pfd; - int lockid = FDLOCK_ID(fd); memset(&pfd, 0, sizeof(pfd)); if (msg == SELECT_POKE_READ) { @@ -758,7 +754,7 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) { UNLOCK(&thread->manager->lock); return (result); -#endif +#endif /* ifdef USE_KQUEUE */ } static inline isc_result_t @@ -801,8 +797,8 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) { if (ret == -1 && errno != ENOENT) { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "epoll_ctl(DEL), %d: %s", fd, strbuf); + UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_ctl(DEL), %d: %s", + fd, strbuf); result = ISC_R_UNEXPECTED; } return (result); @@ -820,16 +816,12 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) { * only provides a way of canceling per FD, we may need to re-poll the * socket for the other operation. */ - if (msg == SELECT_POKE_READ && - thread->fdpollinfo[fd].want_write == 1) - { + if (msg == SELECT_POKE_READ && thread->fdpollinfo[fd].want_write == 1) { pfds[1].events = POLLOUT; pfds[1].fd = fd; writelen += sizeof(pfds[1]); } - if (msg == SELECT_POKE_WRITE && - thread->fdpollinfo[fd].want_read == 1) - { + if (msg == SELECT_POKE_WRITE && thread->fdpollinfo[fd].want_read == 1) { pfds[1].events = POLLIN; pfds[1].fd = fd; writelen += sizeof(pfds[1]); @@ -856,7 +848,7 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) { UNLOCK(&thread->manager->lock); return (result); -#endif +#endif /* ifdef USE_KQUEUE */ } /* @@ -877,19 +869,18 @@ wakeup_socket(isc__socketthread_t *thread, int fd, int msg) { INSIST(fd >= 0 && fd < (int)thread->manager->maxsocks); if (msg == SELECT_POKE_CLOSE) { - /* No one should be updating fdstate, so no need to lock it */ + LOCK(&thread->fdlock[lockid]); INSIST(thread->fdstate[fd] == CLOSE_PENDING); thread->fdstate[fd] = CLOSED; (void)unwatch_fd(thread, fd, SELECT_POKE_READ); (void)unwatch_fd(thread, fd, SELECT_POKE_WRITE); (void)close(fd); + UNLOCK(&thread->fdlock[lockid]); return; } LOCK(&thread->fdlock[lockid]); if (thread->fdstate[fd] == CLOSE_PENDING) { - UNLOCK(&thread->fdlock[lockid]); - /* * We accept (and ignore) any error from unwatch_fd() as we are * closing the socket, hoping it doesn't leave dangling state in @@ -900,13 +891,13 @@ wakeup_socket(isc__socketthread_t *thread, int fd, int msg) { */ (void)unwatch_fd(thread, fd, SELECT_POKE_READ); (void)unwatch_fd(thread, fd, SELECT_POKE_WRITE); + UNLOCK(&thread->fdlock[lockid]); return; } if (thread->fdstate[fd] != MANAGED) { UNLOCK(&thread->fdlock[lockid]); return; } - UNLOCK(&thread->fdlock[lockid]); /* * Set requested bit. @@ -920,9 +911,10 @@ wakeup_socket(isc__socketthread_t *thread, int fd, int msg) { */ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "failed to start watching FD (%d): %s", - fd, isc_result_totext(result)); + "failed to start watching FD (%d): %s", fd, + isc_result_totext(result)); } + UNLOCK(&thread->fdlock[lockid]); } /* @@ -940,8 +932,8 @@ select_poke(isc__socketmgr_t *mgr, int threadid, int fd, int msg) { buf[1] = msg; do { - cc = write(mgr->threads[threadid].pipe_fds[1], - buf, sizeof(buf)); + cc = write(mgr->threads[threadid].pipe_fds[1], buf, + sizeof(buf)); #ifdef ENOSR /* * Treat ENOSR as EAGAIN but loop slowly as it is @@ -951,14 +943,13 @@ select_poke(isc__socketmgr_t *mgr, int threadid, int fd, int msg) { sleep(1); errno = EAGAIN; } -#endif +#endif /* ifdef ENOSR */ } while (cc < 0 && SOFT_ERROR(errno)); if (cc < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, - "write() failed during watcher poke: %s", - strbuf); + "write() failed during watcher poke: %s", strbuf); } INSIST(cc == sizeof(buf)); @@ -976,14 +967,14 @@ select_readmsg(isc__socketthread_t *thread, int *fd, int *msg) { cc = read(thread->pipe_fds[0], buf, sizeof(buf)); if (cc < 0) { *msg = SELECT_POKE_NOTHING; - *fd = -1; /* Silence compiler. */ - if (SOFT_ERROR(errno)) + *fd = -1; /* Silence compiler. */ + if (SOFT_ERROR(errno)) { return; + } strerror_r(errno, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, - "read() failed during watcher poke: %s", - strbuf); + "read() failed during watcher poke: %s", strbuf); } INSIST(cc == sizeof(buf)); @@ -1000,26 +991,26 @@ make_nonblock(int fd) { char strbuf[ISC_STRERRORSIZE]; #ifdef USE_FIONBIO_IOCTL int on = 1; -#else +#else /* ifdef USE_FIONBIO_IOCTL */ int flags; -#endif +#endif /* ifdef USE_FIONBIO_IOCTL */ #ifdef USE_FIONBIO_IOCTL ret = ioctl(fd, FIONBIO, (char *)&on); -#else +#else /* ifdef USE_FIONBIO_IOCTL */ flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK; ret = fcntl(fd, F_SETFL, flags); -#endif +#endif /* ifdef USE_FIONBIO_IOCTL */ if (ret == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, #ifdef USE_FIONBIO_IOCTL "ioctl(%d, FIONBIO, &on): %s", fd, -#else +#else /* ifdef USE_FIONBIO_IOCTL */ "fcntl(%d, F_SETFL, %d): %s", fd, flags, -#endif +#endif /* ifdef USE_FIONBIO_IOCTL */ strbuf); return (ISC_R_UNEXPECTED); @@ -1040,7 +1031,7 @@ static inline socklen_t cmsg_len(socklen_t len) { #ifdef CMSG_LEN return (CMSG_LEN(len)); -#else +#else /* ifdef CMSG_LEN */ socklen_t hdrlen; /* @@ -1049,14 +1040,14 @@ cmsg_len(socklen_t len) { */ hdrlen = (socklen_t)CMSG_DATA(((struct cmsghdr *)NULL)); return (hdrlen + len); -#endif +#endif /* ifdef CMSG_LEN */ } static inline socklen_t cmsg_space(socklen_t len) { #ifdef CMSG_SPACE return (CMSG_SPACE(len)); -#else +#else /* ifdef CMSG_SPACE */ struct msghdr msg; struct cmsghdr *cmsgp; /* @@ -1073,11 +1064,12 @@ cmsg_space(socklen_t len) { cmsgp->cmsg_len = cmsg_len(len); cmsgp = CMSG_NXTHDR(&msg, cmsgp); - if (cmsgp != NULL) + if (cmsgp != NULL) { return ((char *)cmsgp - (char *)msg.msg_control); - else + } else { return (0); -#endif + } +#endif /* ifdef CMSG_SPACE */ } #endif /* USE_CMSG */ @@ -1091,8 +1083,8 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { struct in6_pktinfo *pktinfop; #ifdef SO_TIMESTAMP void *timevalp; -#endif -#endif +#endif /* ifdef SO_TIMESTAMP */ +#endif /* ifdef USE_CMSG */ /* * sock is used only when ISC_NET_BSD44MSGHDR and USE_CMSG are defined. @@ -1108,33 +1100,32 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { if ((msg->msg_flags & MSG_TRUNC) != 0) { dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; } -#endif +#endif /* ifdef MSG_TRUNC */ #ifdef MSG_CTRUNC if ((msg->msg_flags & MSG_CTRUNC) != 0) { dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC; } -#endif +#endif /* ifdef MSG_CTRUNC */ #ifndef USE_CMSG return; -#else - if (msg->msg_controllen == 0U || msg->msg_control == NULL) +#else /* ifndef USE_CMSG */ + if (msg->msg_controllen == 0U || msg->msg_control == NULL) { return; + } #ifdef SO_TIMESTAMP timevalp = NULL; -#endif +#endif /* ifdef SO_TIMESTAMP */ pktinfop = NULL; cmsgp = CMSG_FIRSTHDR(msg); while (cmsgp != NULL) { - socket_log(sock, NULL, TRACE, - "processing cmsg %p", cmsgp); - - if (cmsgp->cmsg_level == IPPROTO_IPV6 - && cmsgp->cmsg_type == IPV6_PKTINFO) { + socket_log(sock, NULL, TRACE, "processing cmsg %p", cmsgp); + if (cmsgp->cmsg_level == IPPROTO_IPV6 && + cmsgp->cmsg_type == IPV6_PKTINFO) { pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp); memmove(&dev->pktinfo, pktinfop, sizeof(struct in6_pktinfo)); @@ -1142,14 +1133,15 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { socket_log(sock, NULL, TRACE, "interface received on ifindex %u", dev->pktinfo.ipi6_ifindex); - if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr)) + if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr)) { dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST; + } goto next; } #ifdef SO_TIMESTAMP - if (cmsgp->cmsg_level == SOL_SOCKET - && cmsgp->cmsg_type == SCM_TIMESTAMP) { + if (cmsgp->cmsg_level == SOL_SOCKET && + cmsgp->cmsg_type == SCM_TIMESTAMP) { struct timeval tv; timevalp = CMSG_DATA(cmsgp); memmove(&tv, timevalp, sizeof(tv)); @@ -1158,31 +1150,32 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP; goto next; } -#endif +#endif /* ifdef SO_TIMESTAMP */ #ifdef IPV6_TCLASS - if (cmsgp->cmsg_level == IPPROTO_IPV6 - && cmsgp->cmsg_type == IPV6_TCLASS) { + if (cmsgp->cmsg_level == IPPROTO_IPV6 && + cmsgp->cmsg_type == IPV6_TCLASS) { dev->dscp = *(int *)CMSG_DATA(cmsgp); dev->dscp >>= 2; dev->attributes |= ISC_SOCKEVENTATTR_DSCP; goto next; } -#endif +#endif /* ifdef IPV6_TCLASS */ #ifdef IP_TOS - if (cmsgp->cmsg_level == IPPROTO_IP - && (cmsgp->cmsg_type == IP_TOS + if (cmsgp->cmsg_level == IPPROTO_IP && + (cmsgp->cmsg_type == IP_TOS #ifdef IP_RECVTOS - || cmsgp->cmsg_type == IP_RECVTOS -#endif - )) { - dev->dscp = (int) *(unsigned char *)CMSG_DATA(cmsgp); + || cmsgp->cmsg_type == IP_RECVTOS +#endif /* ifdef IP_RECVTOS */ + )) + { + dev->dscp = (int)*(unsigned char *)CMSG_DATA(cmsgp); dev->dscp >>= 2; dev->attributes |= ISC_SOCKEVENTATTR_DSCP; goto next; } -#endif +#endif /* ifdef IP_TOS */ next: cmsgp = CMSG_NXTHDR(msg, cmsgp); } @@ -1202,9 +1195,8 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { * this transaction can send. */ static void -build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, - struct msghdr *msg, struct iovec *iov, size_t *write_countp) -{ +build_msghdr_send(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev, + struct msghdr *msg, struct iovec *iov, size_t *write_countp) { unsigned int iovcount; size_t write_count; struct cmsghdr *cmsgp; @@ -1236,8 +1228,7 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, { struct in6_pktinfo *pktinfop; - socket_log(sock, NULL, TRACE, - "sendto pktinfo data, ifindex %u", + socket_log(sock, NULL, TRACE, "sendto pktinfo data, ifindex %u", dev->pktinfo.ipi6_ifindex); msg->msg_control = (void *)cmsgbuf; @@ -1256,10 +1247,9 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, if ((sock->type == isc_sockettype_udp) && (sock->pf == AF_INET6) && ((dev->attributes & ISC_SOCKEVENTATTR_USEMINMTU) != 0)) { - int use_min_mtu = 1; /* -1, 0, 1 */ + int use_min_mtu = 1; /* -1, 0, 1 */ - cmsgp = (struct cmsghdr *)(cmsgbuf + - msg->msg_controllen); + cmsgp = (struct cmsghdr *)(cmsgbuf + msg->msg_controllen); msg->msg_control = (void *)cmsgbuf; msg->msg_controllen += cmsg_space(sizeof(use_min_mtu)); INSIST(msg->msg_controllen <= SENDCMSGBUFLEN); @@ -1269,13 +1259,14 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, cmsgp->cmsg_len = cmsg_len(sizeof(use_min_mtu)); memmove(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu)); } -#endif +#endif /* if defined(IPV6_USE_MIN_MTU) */ if (isc_dscp_check_value > -1) { - if (sock->type == isc_sockettype_udp) + if (sock->type == isc_sockettype_udp) { INSIST((int)dev->dscp == isc_dscp_check_value); - else if (sock->type == isc_sockettype_tcp) + } else if (sock->type == isc_sockettype_tcp) { INSIST((int)sock->dscp == isc_dscp_check_value); + } } #if defined(IP_TOS) || (defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)) @@ -1297,22 +1288,21 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, cmsgp->cmsg_level = IPPROTO_IP; cmsgp->cmsg_type = IP_TOS; cmsgp->cmsg_len = cmsg_len(sizeof(char)); - *(unsigned char*)CMSG_DATA(cmsgp) = dscp; + *(unsigned char *)CMSG_DATA(cmsgp) = dscp; } else if (sock->pf == AF_INET && sock->dscp != dev->dscp) { if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS, - (void *)&dscp, sizeof(int)) < 0) - { + (void *)&dscp, sizeof(int)) < 0) { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IP_TOS, %.02x)" " failed: %s", - sock->fd, dscp >> 2, - strbuf); - } else + sock->fd, dscp >> 2, strbuf); + } else { sock->dscp = dscp; + } } -#endif +#endif /* ifdef IP_TOS */ #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) if (sock->pf == AF_INET6 && sock->pktdscp) { cmsgp = (struct cmsghdr *)(cmsgbuf + @@ -1327,30 +1317,33 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, memmove(CMSG_DATA(cmsgp), &dscp, sizeof(dscp)); } else if (sock->pf == AF_INET6 && sock->dscp != dev->dscp) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, - (void *)&dscp, sizeof(int)) < 0) { + (void *)&dscp, sizeof(int)) < 0) + { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_TCLASS, " "%.02x) failed: %s", - sock->fd, dscp >> 2, - strbuf); - } else + sock->fd, dscp >> 2, strbuf); + } else { sock->dscp = dscp; + } } -#endif +#endif /* if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) */ if (msg->msg_controllen != 0 && - msg->msg_controllen < SENDCMSGBUFLEN) - { + msg->msg_controllen < SENDCMSGBUFLEN) { memset(cmsgbuf + msg->msg_controllen, 0, SENDCMSGBUFLEN - msg->msg_controllen); } } -#endif +#endif /* if defined(IP_TOS) || (defined(IPPROTO_IPV6) && \ + * defined(IPV6_TCLASS)) \ + * */ #endif /* USE_CMSG */ - if (write_countp != NULL) + if (write_countp != NULL) { *write_countp = write_count; + } } /* @@ -1367,8 +1360,7 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev, */ static void build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev, - struct msghdr *msg, struct iovec *iov, size_t *read_countp) -{ + struct msghdr *msg, struct iovec *iov, size_t *read_countp) { unsigned int iovcount; size_t read_count; @@ -1399,7 +1391,7 @@ build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev, iov[iovcount].iov_len = 1; iovcount++; } -#endif +#endif /* ifdef ISC_PLATFORM_RECVOVERFLOW */ msg->msg_iov = iov; msg->msg_iovlen = iovcount; @@ -1407,25 +1399,26 @@ build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev, #if defined(USE_CMSG) msg->msg_control = cmsgbuf; msg->msg_controllen = RECVCMSGBUFLEN; -#else +#else /* if defined(USE_CMSG) */ msg->msg_control = NULL; msg->msg_controllen = 0; #endif /* USE_CMSG */ msg->msg_flags = 0; - if (read_countp != NULL) + if (read_countp != NULL) { *read_countp = read_count; + } } static void set_dev_address(const isc_sockaddr_t *address, isc__socket_t *sock, - isc_socketevent_t *dev) -{ + isc_socketevent_t *dev) { if (sock->type == isc_sockettype_udp) { - if (address != NULL) + if (address != NULL) { dev->address = *address; - else + } else { dev->address = sock->peer_address; + } } else if (sock->type == isc_sockettype_tcp) { INSIST(address == NULL); dev->address = sock->peer_address; @@ -1440,18 +1433,12 @@ destroy_socketevent(isc_event_t *event) { } static isc_socketevent_t * -allocate_socketevent(isc_mem_t *mctx, void *sender, - isc_eventtype_t eventtype, isc_taskaction_t action, - void *arg) -{ +allocate_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, + isc_taskaction_t action, void *arg) { isc_socketevent_t *ev; - ev = (isc_socketevent_t *)isc_event_allocate(mctx, sender, - eventtype, action, arg, - sizeof(*ev)); - - if (ev == NULL) - return (NULL); + ev = (isc_socketevent_t *)isc_event_allocate(mctx, sender, eventtype, + action, arg, sizeof(*ev)); ev->result = ISC_R_UNSET; ISC_LINK_INIT(ev, ev_link); @@ -1473,22 +1460,20 @@ dump_msg(struct msghdr *msg) { printf("MSGHDR %p\n", msg); printf("\tname %p, namelen %ld\n", msg->msg_name, - (long) msg->msg_namelen); - printf("\tiov %p, iovlen %ld\n", msg->msg_iov, - (long) msg->msg_iovlen); + (long)msg->msg_namelen); + printf("\tiov %p, iovlen %ld\n", msg->msg_iov, (long)msg->msg_iovlen); for (i = 0; i < (unsigned int)msg->msg_iovlen; i++) printf("\t\t%u\tbase %p, len %ld\n", i, - msg->msg_iov[i].iov_base, - (long) msg->msg_iov[i].iov_len); + msg->msg_iov[i].iov_base, (long)msg->msg_iov[i].iov_len); printf("\tcontrol %p, controllen %ld\n", msg->msg_control, - (long) msg->msg_controllen); + (long)msg->msg_controllen); } -#endif +#endif /* if defined(ISC_SOCKET_DEBUG) */ -#define DOIO_SUCCESS 0 /* i/o ok, event sent */ -#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ -#define DOIO_HARD 2 /* i/o error, event sent */ -#define DOIO_EOF 3 /* EOF, no event sent */ +#define DOIO_SUCCESS 0 /* i/o ok, event sent */ +#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ +#define DOIO_HARD 2 /* i/o error, event sent */ +#define DOIO_EOF 3 /* EOF, no event sent */ static int doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { @@ -1498,48 +1483,49 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { struct msghdr msghdr; int recv_errno; char strbuf[ISC_STRERRORSIZE]; - char cmsgbuf[RECVCMSGBUFLEN] = {0}; + char cmsgbuf[RECVCMSGBUFLEN] = { 0 }; build_msghdr_recv(sock, cmsgbuf, dev, &msghdr, iov, &read_count); #if defined(ISC_SOCKET_DEBUG) dump_msg(&msghdr); -#endif +#endif /* if defined(ISC_SOCKET_DEBUG) */ cc = recvmsg(sock->fd, &msghdr, 0); recv_errno = errno; #if defined(ISC_SOCKET_DEBUG) dump_msg(&msghdr); -#endif +#endif /* if defined(ISC_SOCKET_DEBUG) */ if (cc < 0) { - if (SOFT_ERROR(recv_errno)) + if (SOFT_ERROR(recv_errno)) { return (DOIO_SOFT); + } if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { strerror_r(recv_errno, strbuf, sizeof(strbuf)); socket_log(sock, NULL, IOEVENT, - "doio_recv: recvmsg(%d) %d bytes, err %d/%s", + "doio_recv: recvmsg(%d) %d bytes, err %d/%s", sock->fd, cc, recv_errno, strbuf); } -#define SOFT_OR_HARD(_system, _isc) \ - if (recv_errno == _system) { \ - if (sock->connected) { \ - dev->result = _isc; \ - inc_stats(sock->manager->stats, \ +#define SOFT_OR_HARD(_system, _isc) \ + if (recv_errno == _system) { \ + if (sock->connected) { \ + dev->result = _isc; \ + inc_stats(sock->manager->stats, \ sock->statsindex[STATID_RECVFAIL]); \ - return (DOIO_HARD); \ - } \ - return (DOIO_SOFT); \ - } -#define ALWAYS_HARD(_system, _isc) \ - if (recv_errno == _system) { \ - dev->result = _isc; \ - inc_stats(sock->manager->stats, \ + return (DOIO_HARD); \ + } \ + return (DOIO_SOFT); \ + } +#define ALWAYS_HARD(_system, _isc) \ + if (recv_errno == _system) { \ + dev->result = _isc; \ + inc_stats(sock->manager->stats, \ sock->statsindex[STATID_RECVFAIL]); \ - return (DOIO_HARD); \ + return (DOIO_HARD); \ } SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); @@ -1547,10 +1533,20 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); SOFT_OR_HARD(EHOSTDOWN, ISC_R_HOSTDOWN); SOFT_OR_HARD(ENOBUFS, ISC_R_NORESOURCES); + /* + * Older operating systems may still return EPROTO in some + * situations, for example when receiving ICMP/ICMPv6 errors. + * A real life scenario is when ICMPv6 returns code 5 or 6. + * These codes are introduced in RFC 4443 from March 2006, + * and the document obsoletes RFC 1885. But unfortunately not + * all operating systems have caught up with the new standard + * (in 2020) and thus a generic protocol error is returned. + */ + SOFT_OR_HARD(EPROTO, ISC_R_HOSTUNREACH); /* Should never get this one but it was seen. */ #ifdef ENOPROTOOPT SOFT_OR_HARD(ENOPROTOOPT, ISC_R_HOSTUNREACH); -#endif +#endif /* ifdef ENOPROTOOPT */ SOFT_OR_HARD(EINVAL, ISC_R_HOSTUNREACH); #undef SOFT_OR_HARD @@ -1570,8 +1566,9 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { switch (sock->type) { case isc_sockettype_tcp: case isc_sockettype_unix: - if (cc == 0) + if (cc == 0) { return (DOIO_EOF); + } break; case isc_sockettype_udp: case isc_sockettype_raw: @@ -1594,12 +1591,13 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { * Simulate a firewall blocking UDP responses bigger than * 'maxudp' bytes. */ - if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp) + if (sock->manager->maxudp != 0 && + cc > (int)sock->manager->maxudp) { return (DOIO_SOFT); + } } - socket_log(sock, &dev->address, IOEVENT, - "packet received correctly"); + socket_log(sock, &dev->address, IOEVENT, "packet received correctly"); /* * Overflow bit detection. If we received MORE bytes than we should, @@ -1611,7 +1609,7 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; cc--; } -#endif +#endif /* ifdef ISC_PLATFORM_RECVOVERFLOW */ /* * If there are control messages attached, run through them and pull @@ -1628,8 +1626,9 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { * If we read less than we expected, update counters, * and let the upper layer poke the descriptor. */ - if (((size_t)cc != read_count) && (dev->n < dev->minimum)) + if (((size_t)cc != read_count) && (dev->n < dev->minimum)) { return (DOIO_SOFT); + } /* * Full reads are posted, or partials if partials are ok. @@ -1661,48 +1660,51 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { int attempts = 0; int send_errno; char strbuf[ISC_STRERRORSIZE]; - char cmsgbuf[SENDCMSGBUFLEN] = {0}; + char cmsgbuf[SENDCMSGBUFLEN] = { 0 }; build_msghdr_send(sock, cmsgbuf, dev, &msghdr, iov, &write_count); - resend: - if (sock->type == isc_sockettype_udp && - sock->manager->maxudp != 0 && - write_count > (size_t)sock->manager->maxudp) +resend: + if (sock->type == isc_sockettype_udp && sock->manager->maxudp != 0 && + write_count > sock->manager->maxudp) + { cc = write_count; - else + } else { cc = sendmsg(sock->fd, &msghdr, 0); + } send_errno = errno; /* * Check for error or block condition. */ if (cc < 0) { - if (send_errno == EINTR && ++attempts < NRETRIES) + if (send_errno == EINTR && ++attempts < NRETRIES) { goto resend; + } if (SOFT_ERROR(send_errno)) { - if (errno == EWOULDBLOCK || errno == EAGAIN) + if (errno == EWOULDBLOCK || errno == EAGAIN) { dev->result = ISC_R_WOULDBLOCK; + } return (DOIO_SOFT); } -#define SOFT_OR_HARD(_system, _isc) \ - if (send_errno == _system) { \ - if (sock->connected) { \ - dev->result = _isc; \ - inc_stats(sock->manager->stats, \ +#define SOFT_OR_HARD(_system, _isc) \ + if (send_errno == _system) { \ + if (sock->connected) { \ + dev->result = _isc; \ + inc_stats(sock->manager->stats, \ sock->statsindex[STATID_SENDFAIL]); \ - return (DOIO_HARD); \ - } \ - return (DOIO_SOFT); \ - } -#define ALWAYS_HARD(_system, _isc) \ - if (send_errno == _system) { \ - dev->result = _isc; \ - inc_stats(sock->manager->stats, \ + return (DOIO_HARD); \ + } \ + return (DOIO_SOFT); \ + } +#define ALWAYS_HARD(_system, _isc) \ + if (send_errno == _system) { \ + dev->result = _isc; \ + inc_stats(sock->manager->stats, \ sock->statsindex[STATID_SENDFAIL]); \ - return (DOIO_HARD); \ + return (DOIO_HARD); \ } SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); @@ -1712,7 +1714,7 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { ALWAYS_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ALWAYS_HARD(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif +#endif /* ifdef EHOSTDOWN */ ALWAYS_HARD(ENETUNREACH, ISC_R_NETUNREACH); SOFT_OR_HARD(ENOBUFS, ISC_R_NORESOURCES); ALWAYS_HARD(EPERM, ISC_R_HOSTUNREACH); @@ -1752,8 +1754,9 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { * If we write less than we expected, update counters, poke. */ dev->n += cc; - if ((size_t)cc != write_count) + if ((size_t)cc != write_count) { return (DOIO_SOFT); + } /* * Exactly what we wanted to write. We're done with this @@ -1783,11 +1786,14 @@ socketclose(isc__socketthread_t *thread, isc__socket_t *sock, int fd) { select_poke(thread->manager, thread->threadid, fd, SELECT_POKE_CLOSE); inc_stats(thread->manager->stats, sock->statsindex[STATID_CLOSE]); + + LOCK(&sock->lock); if (sock->active == 1) { dec_stats(thread->manager->stats, sock->statsindex[STATID_ACTIVE]); sock->active = 0; } + UNLOCK(&sock->lock); /* * update manager->maxfd here (XXX: this should be implemented more @@ -1816,18 +1822,21 @@ socketclose(isc__socketthread_t *thread, isc__socket_t *sock, int fd) { } UNLOCK(&thread->manager->lock); -#endif /* USE_SELECT */ +#endif /* USE_SELECT */ } static void destroy(isc__socket_t **sockp) { - int fd; + int fd = 0; isc__socket_t *sock = *sockp; isc__socketmgr_t *manager = sock->manager; - isc__socketthread_t *thread; + isc__socketthread_t *thread = NULL; socket_log(sock, NULL, CREATION, "destroying"); + isc_refcount_destroy(&sock->references); + + LOCK(&sock->lock); INSIST(ISC_LIST_EMPTY(sock->connect_list)); INSIST(ISC_LIST_EMPTY(sock->accept_list)); INSIST(ISC_LIST_EMPTY(sock->recv_list)); @@ -1839,6 +1848,10 @@ destroy(isc__socket_t **sockp) { thread = &manager->threads[sock->threadid]; sock->fd = -1; sock->threadid = -1; + } + UNLOCK(&sock->lock); + + if (fd > 0) { socketclose(thread, sock, fd); } @@ -1846,8 +1859,9 @@ destroy(isc__socket_t **sockp) { ISC_LIST_UNLINK(manager->socklist, sock, link); - if (ISC_LIST_EMPTY(manager->socklist)) + if (ISC_LIST_EMPTY(manager->socklist)) { SIGNAL(&manager->shutdown_ok); + } /* can't unlock manager as its memory context is still used */ free_socket(sockp); @@ -1857,8 +1871,7 @@ destroy(isc__socket_t **sockp) { static isc_result_t allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, - isc__socket_t **socketp) -{ + isc__socket_t **socketp) { isc__socket_t *sock; sock = isc_mem_get(manager->mctx, sizeof(*sock)); @@ -1871,7 +1884,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->type = type; sock->fd = -1; sock->threadid = -1; - sock->dscp = 0; /* TOS/TCLASS is zero until set. */ + sock->dscp = 0; /* TOS/TCLASS is zero until set. */ sock->dupped = 0; sock->statsindex = NULL; sock->active = 0; @@ -1888,6 +1901,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, ISC_LIST_INIT(sock->send_list); ISC_LIST_INIT(sock->accept_list); ISC_LIST_INIT(sock->connect_list); + sock->listener = 0; sock->connected = 0; sock->connecting = 0; @@ -1916,15 +1930,18 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, static void free_socket(isc__socket_t **socketp) { isc__socket_t *sock = *socketp; + *socketp = NULL; INSIST(VALID_SOCKET(sock)); - INSIST(isc_refcount_current(&sock->references) == 0); + isc_refcount_destroy(&sock->references); + LOCK(&sock->lock); INSIST(!sock->connecting); INSIST(ISC_LIST_EMPTY(sock->recv_list)); INSIST(ISC_LIST_EMPTY(sock->send_list)); INSIST(ISC_LIST_EMPTY(sock->accept_list)); INSIST(ISC_LIST_EMPTY(sock->connect_list)); INSIST(!ISC_LINK_LINKED(sock, link)); + UNLOCK(&sock->lock); sock->common.magic = 0; sock->common.impmagic = 0; @@ -1932,13 +1949,11 @@ free_socket(isc__socket_t **socketp) { isc_mutex_destroy(&sock->lock); isc_mem_put(sock->manager->mctx, sock, sizeof(*sock)); - - *socketp = NULL; } -#ifdef SO_RCVBUF -static isc_once_t rcvbuf_once = ISC_ONCE_INIT; -static int rcvbuf = RCVBUFSIZE; +#if defined(SET_RCVBUF) +static isc_once_t rcvbuf_once = ISC_ONCE_INIT; +static int rcvbuf = ISC_RECV_BUFFER_SIZE; static void set_rcvbuf(void) { @@ -1961,15 +1976,18 @@ set_rcvbuf(void) { break; } } - if (fd == -1) + if (fd == -1) { return; + } len = sizeof(min); if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&min, &len) == 0 && - min < rcvbuf) { - again: + min < rcvbuf) + { + again: if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, - sizeof(rcvbuf)) == -1) { + sizeof(rcvbuf)) == -1) + { if (errno == ENOBUFS && rcvbuf > min) { max = rcvbuf - 1; rcvbuf = (rcvbuf + min) / 2; @@ -1978,21 +1996,22 @@ set_rcvbuf(void) { rcvbuf = min; goto cleanup; } - } else + } else { min = rcvbuf; + } if (min != max) { rcvbuf = max; goto again; } } - cleanup: - close (fd); +cleanup: + close(fd); } -#endif +#endif /* ifdef SO_RCVBUF */ -#ifdef SO_SNDBUF -static isc_once_t sndbuf_once = ISC_ONCE_INIT; -static int sndbuf = SNDBUFSIZE; +#if defined(SET_SNDBUF) +static isc_once_t sndbuf_once = ISC_ONCE_INIT; +static int sndbuf = ISC_SEND_BUFFER_SIZE; static void set_sndbuf(void) { @@ -2001,7 +2020,6 @@ set_sndbuf(void) { socklen_t len; fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); -#if defined(ISC_PLATFORM_HAVEIPV6) if (fd == -1) { switch (errno) { case EPROTONOSUPPORT: @@ -2016,7 +2034,6 @@ set_sndbuf(void) { break; } } -#endif if (fd == -1) { return; } @@ -2025,9 +2042,10 @@ set_sndbuf(void) { if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&min, &len) == 0 && min < sndbuf) { - again: + again: if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, - sizeof(sndbuf)) == -1) { + sizeof(sndbuf)) == -1) + { if (errno == ENOBUFS && sndbuf > min) { max = sndbuf - 1; sndbuf = (sndbuf + min) / 2; @@ -2044,100 +2062,62 @@ set_sndbuf(void) { goto again; } } - cleanup: - close (fd); +cleanup: + close(fd); } -#endif - -#ifdef SO_BSDCOMPAT -/* - * This really should not be necessary to do. Having to workout - * which kernel version we are on at run time so that we don't cause - * the kernel to issue a warning about us using a deprecated socket option. - * Such warnings should *never* be on by default in production kernels. - * - * We can't do this a build time because executables are moved between - * machines and hence kernels. - * - * We can't just not set SO_BSDCOMAT because some kernels require it. - */ - -static isc_once_t bsdcompat_once = ISC_ONCE_INIT; -bool bsdcompat = true; - -static void -clear_bsdcompat(void) { -#ifdef __linux__ - struct utsname buf; - char *endp; - long int major; - long int minor; - - uname(&buf); /* Can only fail if buf is bad in Linux. */ - - /* Paranoia in parsing can be increased, but we trust uname(). */ - major = strtol(buf.release, &endp, 10); - if (*endp == '.') { - minor = strtol(endp+1, &endp, 10); - if ((major > 2) || ((major == 2) && (minor >= 4))) { - bsdcompat = false; - } - } -#endif /* __linux __ */ -} -#endif +#endif /* ifdef SO_SNDBUF */ static void use_min_mtu(isc__socket_t *sock) { #if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) UNUSED(sock); -#endif +#endif /* if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) */ #ifdef IPV6_USE_MIN_MTU /* use minimum MTU */ if (sock->pf == AF_INET6) { int on = 1; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)); + (void *)&on, sizeof(on)); } -#endif +#endif /* ifdef IPV6_USE_MIN_MTU */ #if defined(IPV6_MTU) /* * Use minimum MTU on IPv6 sockets. */ if (sock->pf == AF_INET6) { int mtu = 1280; - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, - &mtu, sizeof(mtu)); + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, &mtu, + sizeof(mtu)); } -#endif +#endif /* if defined(IPV6_MTU) */ } static void set_tcp_maxseg(isc__socket_t *sock, int size) { #ifdef TCP_MAXSEG - if (sock->type == isc_sockettype_tcp) + if (sock->type == isc_sockettype_tcp) { (void)setsockopt(sock->fd, IPPROTO_TCP, TCP_MAXSEG, - (void *)&size, sizeof(size)); -#endif + (void *)&size, sizeof(size)); + } +#endif /* ifdef TCP_MAXSEG */ } static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, - isc__socket_t *dup_socket) -{ + isc__socket_t *dup_socket) { isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; -#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE) +#if defined(USE_CMSG) || defined(SO_NOSIGPIPE) int on = 1; -#endif -#if defined(SO_RCVBUF) || defined(SO_SNDBUF) +#endif /* if defined(USE_CMSG) || defined(SO_NOSIGPIPE) */ +#if defined(SET_RCVBUF) || defined(SET_SNDBUF) socklen_t optlen; int size = 0; #endif - again: +again: if (dup_socket == NULL) { switch (sock->type) { case isc_sockettype_udp: @@ -2159,9 +2139,9 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, #ifdef NETLINK_ROUTE sock->fd = socket(sock->pf, SOCK_RAW, NETLINK_ROUTE); -#else +#else /* ifdef NETLINK_ROUTE */ sock->fd = socket(sock->pf, SOCK_RAW, 0); -#endif +#endif /* ifdef NETLINK_ROUTE */ if (sock->fd != -1) { #ifdef NETLINK_ROUTE struct sockaddr_nl sa; @@ -2175,17 +2155,17 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, sa.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; n = bind(sock->fd, - (struct sockaddr *) &sa, + (struct sockaddr *)&sa, sizeof(sa)); if (n < 0) { close(sock->fd); sock->fd = -1; } -#endif +#endif /* ifdef NETLINK_ROUTE */ sock->bound = 1; } } -#endif +#endif /* if defined(PF_ROUTE) */ break; } } else { @@ -2193,15 +2173,17 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, sock->dupped = 1; sock->bound = dup_socket->bound; } - if (sock->fd == -1 && errno == EINTR && tries++ < 42) + if (sock->fd == -1 && errno == EINTR && tries++ < 42) { goto again; + } #ifdef F_DUPFD /* * Leave a space for stdio and TCP to work in. */ if (manager->reserved != 0 && sock->type == isc_sockettype_udp && - sock->fd >= 0 && sock->fd < manager->reserved) { + sock->fd >= 0 && sock->fd < manager->reserved) + { int newfd, tmp; newfd = fcntl(sock->fd, F_DUPFD, manager->reserved); tmp = errno; @@ -2218,7 +2200,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, sock->fd = newfd; err = "isc_socket_create: fcntl"; } -#endif +#endif /* ifdef F_DUPFD */ if (sock->fd >= (int)manager->maxsocks) { (void)close(sock->fd); @@ -2238,7 +2220,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "%s: %s", err, strbuf); - /* fallthrough */ + /* fallthrough */ case ENOBUFS: inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); @@ -2258,17 +2240,17 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, default: strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s() failed: %s", err, - strbuf); + UNEXPECTED_ERROR(__FILE__, __LINE__, "%s() failed: %s", + err, strbuf); inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (ISC_R_UNEXPECTED); } } - if (dup_socket != NULL) + if (dup_socket != NULL) { goto setup_done; + } result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { @@ -2277,32 +2259,16 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, return (result); } -#ifdef SO_BSDCOMPAT - RUNTIME_CHECK(isc_once_do(&bsdcompat_once, - clear_bsdcompat) == ISC_R_SUCCESS); - if (sock->type != isc_sockettype_unix && bsdcompat && - setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT, - (void *)&on, sizeof(on)) < 0) { - strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_BSDCOMPAT) failed: %s", - sock->fd, - strbuf); - /* Press on... */ - } -#endif - #ifdef SO_NOSIGPIPE - if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, - (void *)&on, sizeof(on)) < 0) { + if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, + sizeof(on)) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, SO_NOSIGPIPE) failed: %s", - sock->fd, - strbuf); + sock->fd, strbuf); /* Press on... */ } -#endif +#endif /* ifdef SO_NOSIGPIPE */ /* * Use minimum mtu if possible. @@ -2312,44 +2278,46 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, set_tcp_maxseg(sock, 1280 - 20 - 40); /* 1280 - TCP - IPV6 */ } -#if defined(USE_CMSG) || defined(SO_RCVBUF) || defined(SO_SNDBUF) +#if defined(USE_CMSG) || defined(SET_RCVBUF) || defined(SET_SNDBUF) if (sock->type == isc_sockettype_udp) { - #if defined(USE_CMSG) #if defined(SO_TIMESTAMP) - if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP, - (void *)&on, sizeof(on)) < 0 - && errno != ENOPROTOOPT) { + if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP, (void *)&on, + sizeof(on)) < 0 && + errno != ENOPROTOOPT) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_TIMESTAMP) failed: %s", - sock->fd, - strbuf); + "setsockopt(%d, SO_TIMESTAMP) failed: " + "%s", + sock->fd, strbuf); /* Press on... */ } #endif /* SO_TIMESTAMP */ #ifdef IPV6_RECVPKTINFO /* RFC 3542 */ - if ((sock->pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, - (void *)&on, sizeof(on)) < 0)) { + if ((sock->pf == AF_INET6) && + (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, + (void *)&on, sizeof(on)) < 0)) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVPKTINFO) " - "failed: %s", sock->fd, - strbuf); + "failed: %s", + sock->fd, strbuf); } -#else +#else /* ifdef IPV6_RECVPKTINFO */ /* RFC 2292 */ - if ((sock->pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, - (void *)&on, sizeof(on)) < 0)) { + if ((sock->pf == AF_INET6) && + (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, + (void *)&on, sizeof(on)) < 0)) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_PKTINFO) failed: %s", - sock->fd, - strbuf); + "setsockopt(%d, IPV6_PKTINFO) failed: " + "%s", + sock->fd, strbuf); } #endif /* IPV6_RECVPKTINFO */ #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) @@ -2362,7 +2330,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, IPV6_MTU_DISCOVER, &action, sizeof(action)); } -#endif +#endif /* if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) */ #endif /* defined(USE_CMSG) */ #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) @@ -2375,19 +2343,19 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, int action; #if defined(IP_PMTUDISC_OMIT) action = IP_PMTUDISC_OMIT; - if (setsockopt(sock->fd, IPPROTO_IP, - IP_MTU_DISCOVER, &action, - sizeof(action)) < 0) { -#endif + if (setsockopt(sock->fd, IPPROTO_IP, IP_MTU_DISCOVER, + &action, sizeof(action)) < 0) + { +#endif /* if defined(IP_PMTUDISC_OMIT) */ action = IP_PMTUDISC_DONT; (void)setsockopt(sock->fd, IPPROTO_IP, - IP_MTU_DISCOVER, - &action, sizeof(action)); + IP_MTU_DISCOVER, &action, + sizeof(action)); #if defined(IP_PMTUDISC_OMIT) } -#endif +#endif /* if defined(IP_PMTUDISC_OMIT) */ } -#endif +#endif /* if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) */ #if defined(IP_DONTFRAG) /* * Turn off Path MTU discovery on IPv4/UDP sockets. @@ -2397,65 +2365,73 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, (void)setsockopt(sock->fd, IPPROTO_IP, IP_DONTFRAG, &off, sizeof(off)); } -#endif +#endif /* if defined(IP_DONTFRAG) */ -#if defined(SO_RCVBUF) +#if defined(SET_RCVBUF) optlen = sizeof(size); - if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, - (void *)&size, &optlen) == 0 && size < rcvbuf) { - RUNTIME_CHECK(isc_once_do(&rcvbuf_once, - set_rcvbuf) == ISC_R_SUCCESS); + if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (void *)&size, + &optlen) == 0 && + size < rcvbuf) + { + RUNTIME_CHECK(isc_once_do(&rcvbuf_once, set_rcvbuf) == + ISC_R_SUCCESS); if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, - (void *)&rcvbuf, sizeof(rcvbuf)) == -1) { + (void *)&rcvbuf, sizeof(rcvbuf)) == -1) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_RCVBUF, %d) failed: %s", - sock->fd, rcvbuf, - strbuf); + "setsockopt(%d, SO_RCVBUF, " + "%d) failed: %s", + sock->fd, rcvbuf, strbuf); } } -#endif +#endif /* if defined(SET_RCVBUF) */ -#if defined(SO_SNDBUF) +#if defined(SET_SNDBUF) optlen = sizeof(size); - if (getsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, - (void *)&size, &optlen) == 0 && size < sndbuf) { - RUNTIME_CHECK(isc_once_do(&sndbuf_once, - set_sndbuf) == ISC_R_SUCCESS); + if (getsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, (void *)&size, + &optlen) == 0 && + size < sndbuf) + { + RUNTIME_CHECK(isc_once_do(&sndbuf_once, set_sndbuf) == + ISC_R_SUCCESS); if (setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, - (void *)&sndbuf, sizeof(sndbuf)) == -1) { + (void *)&sndbuf, sizeof(sndbuf)) == -1) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_SNDBUF, %d) failed: %s", - sock->fd, sndbuf, - strbuf); + "setsockopt(%d, SO_SNDBUF, " + "%d) failed: %s", + sock->fd, sndbuf, strbuf); } } -#endif +#endif /* if defined(SO_SNDBUF) */ } #ifdef IPV6_RECVTCLASS - if ((sock->pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVTCLASS, - (void *)&on, sizeof(on)) < 0)) { + if ((sock->pf == AF_INET6) && + (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVTCLASS, (void *)&on, + sizeof(on)) < 0)) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVTCLASS) " - "failed: %s", sock->fd, - strbuf); + "failed: %s", + sock->fd, strbuf); } -#endif +#endif /* ifdef IPV6_RECVTCLASS */ #ifdef IP_RECVTOS - if ((sock->pf == AF_INET) - && (setsockopt(sock->fd, IPPROTO_IP, IP_RECVTOS, - (void *)&on, sizeof(on)) < 0)) { + if ((sock->pf == AF_INET) && + (setsockopt(sock->fd, IPPROTO_IP, IP_RECVTOS, (void *)&on, + sizeof(on)) < 0)) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IP_RECVTOS) " - "failed: %s", sock->fd, - strbuf); + "failed: %s", + sock->fd, strbuf); } -#endif -#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) || defined(SO_SNDBUF) */ +#endif /* ifdef IP_RECVTOS */ +#endif /* defined(USE_CMSG) || defined(SET_RCVBUF) || defined(SET_SNDBUF) */ setup_done: inc_stats(manager->stats, sock->statsindex[STATID_OPEN]); @@ -2475,8 +2451,7 @@ setup_done: */ static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, - isc_socket_t **socketp, isc_socket_t *dup_socket) -{ + isc_socket_t **socketp, isc_socket_t *dup_socket) { isc__socket_t *sock = NULL; isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; isc__socketthread_t *thread; @@ -2487,19 +2462,20 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, REQUIRE(socketp != NULL && *socketp == NULL); result = allocate_socket(manager, type, &sock); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } switch (sock->type) { case isc_sockettype_udp: - sock->statsindex = - (pf == AF_INET) ? udp4statsindex : udp6statsindex; + sock->statsindex = (pf == AF_INET) ? udp4statsindex + : udp6statsindex; #define DCSPPKT(pf) ((pf == AF_INET) ? ISC_NET_DSCPPKTV4 : ISC_NET_DSCPPKTV6) sock->pktdscp = (isc_net_probedscp() & DCSPPKT(pf)) != 0; break; case isc_sockettype_tcp: - sock->statsindex = - (pf == AF_INET) ? tcp4statsindex : tcp6statsindex; + sock->statsindex = (pf == AF_INET) ? tcp4statsindex + : tcp6statsindex; break; case isc_sockettype_unix: sock->statsindex = unixstatsindex; @@ -2524,7 +2500,7 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, abort(); } sock->threadid = gen_threadid(sock); - isc_refcount_increment(&sock->references); + isc_refcount_increment0(&sock->references); thread = &manager->threads[sock->threadid]; *socketp = (isc_socket_t *)sock; @@ -2539,11 +2515,11 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, thread->fdstate[sock->fd] = MANAGED; #if defined(USE_EPOLL) thread->epoll_events[sock->fd] = 0; -#endif +#endif /* if defined(USE_EPOLL) */ #ifdef USE_DEVPOLL INSIST(thread->fdpollinfo[sock->fd].want_read == 0 && thread->fdpollinfo[sock->fd].want_write == 0); -#endif +#endif /* ifdef USE_DEVPOLL */ UNLOCK(&thread->fdlock[lockid]); LOCK(&manager->lock); @@ -2552,7 +2528,7 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, if (thread->maxfd < sock->fd) { thread->maxfd = sock->fd; } -#endif +#endif /* ifdef USE_SELECT */ UNLOCK(&manager->lock); socket_log(sock, NULL, CREATION, @@ -2569,8 +2545,7 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, */ isc_result_t isc_socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, - isc_socket_t **socketp) -{ + isc_socket_t **socketp) { return (socket_create(manager0, pf, type, socketp, NULL)); } @@ -2585,9 +2560,8 @@ isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); - return (socket_create((isc_socketmgr_t *) sock->manager, - sock->pf, sock->type, socketp, - sock0)); + return (socket_create((isc_socketmgr_t *)sock->manager, sock->pf, + sock->type, socketp, sock0)); } isc_result_t @@ -2620,25 +2594,25 @@ isc_socket_open(isc_socket_t *sock0) { thread->fdstate[sock->fd] = MANAGED; #if defined(USE_EPOLL) thread->epoll_events[sock->fd] = 0; -#endif +#endif /* if defined(USE_EPOLL) */ #ifdef USE_DEVPOLL INSIST(thread->fdpollinfo[sock->fd].want_read == 0 && thread->fdpollinfo[sock->fd].want_write == 0); -#endif +#endif /* ifdef USE_DEVPOLL */ UNLOCK(&thread->fdlock[lockid]); #ifdef USE_SELECT LOCK(&sock->manager->lock); - if (thread->maxfd < sock->fd) + if (thread->maxfd < sock->fd) { thread->maxfd = sock->fd; + } UNLOCK(&sock->manager->lock); -#endif +#endif /* ifdef USE_SELECT */ } return (result); } - /* * Attach to a socket. Caller must explicitly detach when it is done. */ @@ -2666,7 +2640,6 @@ isc_socket_detach(isc_socket_t **socketp) { REQUIRE(socketp != NULL); sock = (isc__socket_t *)*socketp; REQUIRE(VALID_SOCKET(sock)); - if (isc_refcount_decrement(&sock->references) == 1) { destroy(&sock); } @@ -2759,8 +2732,9 @@ send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) { task = (*dev)->ev_sender; (*dev)->ev_sender = sock; - if (ISC_LINK_LINKED(*dev, ev_link)) + if (ISC_LINK_LINKED(*dev, ev_link)) { ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link); + } if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) != 0) { isc_task_sendtoanddetach(&task, (isc_event_t **)dev, @@ -2815,15 +2789,9 @@ internal_accept(isc__socket_t *sock) { const char *err = "accept"; INSIST(VALID_SOCKET(sock)); + REQUIRE(sock->fd >= 0); - LOCK(&sock->lock); - if (sock->fd < 0) { - /* Socket is gone */ - UNLOCK(&sock->lock); - return; - } - socket_log(sock, NULL, TRACE, - "internal_accept called, locked socket"); + socket_log(sock, NULL, TRACE, "internal_accept called, locked socket"); manager = sock->manager; INSIST(VALID_MANAGER(manager)); @@ -2871,11 +2839,12 @@ internal_accept(isc__socket_t *sock) { fd = newfd; err = "accept/fcntl"; } -#endif +#endif /* ifdef F_DUPFD */ if (fd < 0) { - if (SOFT_ERROR(errno)) + if (SOFT_ERROR(errno)) { goto soft_error; + } switch (errno) { case ENFILE: case EMFILE: @@ -2896,10 +2865,10 @@ internal_accept(isc__socket_t *sock) { case ECONNREFUSED: #ifdef EPROTO case EPROTO: -#endif +#endif /* ifdef EPROTO */ #ifdef ENONET case ENONET: -#endif +#endif /* ifdef ENONET */ goto soft_error; default: break; @@ -2920,21 +2889,21 @@ internal_accept(isc__socket_t *sock) { (void)close(fd); goto soft_error; } else if (NEWCONNSOCK(dev)->peer_address.type.sa.sa_family != - sock->pf) - { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_accept(): " - "accept() returned peer address " - "family %u (expected %u)", - NEWCONNSOCK(dev)->peer_address. - type.sa.sa_family, - sock->pf); + sock->pf) { + UNEXPECTED_ERROR( + __FILE__, __LINE__, + "internal_accept(): " + "accept() returned peer address " + "family %u (expected %u)", + NEWCONNSOCK(dev)->peer_address.type.sa.sa_family, + sock->pf); (void)close(fd); goto soft_error; } else if (fd >= (int)manager->maxsocks) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "accept: file descriptor exceeds limit (%d/%u)", + "accept: file descriptor exceeds limit " + "(%d/%u)", fd, manager->maxsocks); (void)close(fd); goto soft_error; @@ -2954,11 +2923,9 @@ internal_accept(isc__socket_t *sock) { /* * Poke watcher if there are more pending accepts. */ - if (ISC_LIST_EMPTY(sock->accept_list)) - unwatch_fd(thread, sock->fd, - SELECT_POKE_ACCEPT); - - UNLOCK(&sock->lock); + if (ISC_LIST_EMPTY(sock->accept_list)) { + unwatch_fd(thread, sock->fd, SELECT_POKE_ACCEPT); + } if (fd != -1) { result = make_nonblock(fd); @@ -2969,6 +2936,12 @@ internal_accept(isc__socket_t *sock) { } /* + * We need to unlock sock->lock now to be able to lock manager->lock + * without risking a deadlock with xmlstats. + */ + UNLOCK(&sock->lock); + + /* * -1 means the new socket didn't happen. */ if (fd != -1) { @@ -2984,7 +2957,8 @@ internal_accept(isc__socket_t *sock) { * We already hold a lock on one fdlock in accepting thread, * we need to make sure that we don't double lock. */ - bool same_bucket = (sock->threadid == NEWCONNSOCK(dev)->threadid) && + bool same_bucket = (sock->threadid == + NEWCONNSOCK(dev)->threadid) && (FDLOCK_ID(sock->fd) == lockid); /* @@ -3016,7 +2990,7 @@ internal_accept(isc__socket_t *sock) { nthread->fdstate[fd] = MANAGED; #if defined(USE_EPOLL) nthread->epoll_events[fd] = 0; -#endif +#endif /* if defined(USE_EPOLL) */ if (!same_bucket) { UNLOCK(&nthread->fdlock[lockid]); } @@ -3024,9 +2998,10 @@ internal_accept(isc__socket_t *sock) { LOCK(&manager->lock); #ifdef USE_SELECT - if (nthread->maxfd < fd) + if (nthread->maxfd < fd) { nthread->maxfd = fd; -#endif + } +#endif /* ifdef USE_SELECT */ socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION, "accepted connection, new socket %p", @@ -3039,7 +3014,7 @@ internal_accept(isc__socket_t *sock) { inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]); } else { inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]); - (void)isc_refcount_decrement(&NEWCONNSOCK(dev)->references); + isc_refcount_decrementz(&NEWCONNSOCK(dev)->references); free_socket((isc__socket_t **)&dev->newsocket); } @@ -3053,7 +3028,7 @@ internal_accept(isc__socket_t *sock) { isc_task_sendtoanddetach(&task, ISC_EVENT_PTR(&dev), sock->threadid); return; - soft_error: +soft_error: watch_fd(thread, sock->fd, SELECT_POKE_ACCEPT); UNLOCK(&sock->lock); @@ -3066,20 +3041,15 @@ internal_recv(isc__socket_t *sock) { isc_socketevent_t *dev; INSIST(VALID_SOCKET(sock)); + REQUIRE(sock->fd >= 0); - LOCK(&sock->lock); - if (sock->fd < 0) { - /* Socket is gone */ - UNLOCK(&sock->lock); - return; - } dev = ISC_LIST_HEAD(sock->recv_list); if (dev == NULL) { goto finish; } - socket_log(sock, NULL, IOEVENT, - "internal_recv: event %p -> task %p", dev, dev->ev_sender); + socket_log(sock, NULL, IOEVENT, "internal_recv: event %p -> task %p", + dev, dev->ev_sender); /* * Try to do as much I/O as possible on this socket. There are no @@ -3112,12 +3082,11 @@ internal_recv(isc__socket_t *sock) { dev = ISC_LIST_HEAD(sock->recv_list); } - finish: +finish: if (ISC_LIST_EMPTY(sock->recv_list)) { unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd, SELECT_POKE_READ); } - UNLOCK(&sock->lock); } static void @@ -3125,20 +3094,14 @@ internal_send(isc__socket_t *sock) { isc_socketevent_t *dev; INSIST(VALID_SOCKET(sock)); + REQUIRE(sock->fd >= 0); - LOCK(&sock->lock); - if (sock->fd < 0) { - /* Socket is gone */ - UNLOCK(&sock->lock); - return; - } dev = ISC_LIST_HEAD(sock->send_list); if (dev == NULL) { goto finish; } - socket_log(sock, NULL, EVENT, - "internal_send: event %p -> task %p", - dev, dev->ev_sender); + socket_log(sock, NULL, EVENT, "internal_send: event %p -> task %p", dev, + dev->ev_sender); /* * Try to do as much I/O as possible on this socket. There are no @@ -3158,12 +3121,11 @@ internal_send(isc__socket_t *sock) { dev = ISC_LIST_HEAD(sock->send_list); } - finish: +finish: if (ISC_LIST_EMPTY(sock->send_list)) { - unwatch_fd(&sock->manager->threads[sock->threadid], - sock->fd, SELECT_POKE_WRITE); + unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd, + SELECT_POKE_WRITE); } - UNLOCK(&sock->lock); } /* @@ -3171,9 +3133,7 @@ internal_send(isc__socket_t *sock) { * and unlocking twice if both reads and writes are possible. */ static void -process_fd(isc__socketthread_t *thread, int fd, bool readable, - bool writeable) -{ +process_fd(isc__socketthread_t *thread, int fd, bool readable, bool writeable) { isc__socket_t *sock; int lockid = FDLOCK_ID(fd); @@ -3195,23 +3155,22 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, return; } - if (isc_refcount_increment(&sock->references) == 0) { + LOCK(&sock->lock); + + if (sock->fd < 0) { /* - * Sock is being closed, it will be destroyed, bail. + * Sock is being closed - the final external reference + * is gone but it was not yet removed from event loop + * and fdstate[]/fds[] as destroy() is waiting on + * thread->fdlock[lockid] or sock->lock that we're holding. + * Just release the locks and bail. */ - (void)isc_refcount_decrement(&sock->references); + UNLOCK(&sock->lock); UNLOCK(&thread->fdlock[lockid]); return; } - if (readable) { - if (sock->listener) { - internal_accept(sock); - } else { - internal_recv(sock); - } - } - + REQUIRE(readable || writeable); if (writeable) { if (sock->connecting) { internal_connect(sock); @@ -3220,10 +3179,23 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, } } - UNLOCK(&thread->fdlock[lockid]); - if (isc_refcount_decrement(&sock->references) == 1) { - destroy(&sock); + if (readable) { + if (sock->listener) { + internal_accept(sock); /* unlocks sock */ + } else { + internal_recv(sock); + UNLOCK(&sock->lock); + } + } else { + UNLOCK(&sock->lock); } + + UNLOCK(&thread->fdlock[lockid]); + + /* + * Socket destruction might be pending, it will resume + * after releasing fdlock and sock->lock. + */ } /* @@ -3233,9 +3205,7 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, */ #ifdef USE_KQUEUE static bool -process_fds(isc__socketthread_t *thread, struct kevent *events, - int nevents) -{ +process_fds(isc__socketthread_t *thread, struct kevent *events, int nevents) { int i; bool readable, writable; bool done = false; @@ -3263,16 +3233,16 @@ process_fds(isc__socketthread_t *thread, struct kevent *events, process_fd(thread, events[i].ident, readable, writable); } - if (have_ctlevent) + if (have_ctlevent) { done = process_ctlfd(thread); + } return (done); } #elif defined(USE_EPOLL) static bool process_fds(isc__socketthread_t *thread, struct epoll_event *events, - int nevents) -{ + int nevents) { int i; bool done = false; bool have_ctlevent = false; @@ -3307,16 +3277,15 @@ process_fds(isc__socketthread_t *thread, struct epoll_event *events, (events[i].events & EPOLLOUT) != 0); } - if (have_ctlevent) + if (have_ctlevent) { done = process_ctlfd(thread); + } return (done); } #elif defined(USE_DEVPOLL) static bool -process_fds(isc__socketthread_t *thread, struct pollfd *events, - int nevents) -{ +process_fds(isc__socketthread_t *thread, struct pollfd *events, int nevents) { int i; bool done = false; bool have_ctlevent = false; @@ -3339,28 +3308,29 @@ process_fds(isc__socketthread_t *thread, struct pollfd *events, (events[i].events & POLLOUT) != 0); } - if (have_ctlevent) + if (have_ctlevent) { done = process_ctlfd(thread); + } return (done); } #elif defined(USE_SELECT) static void process_fds(isc__socketthread_t *thread, int maxfd, fd_set *readfds, - fd_set *writefds) -{ + fd_set *writefds) { int i; REQUIRE(maxfd <= (int)thread->manager->maxsocks); for (i = 0; i < maxfd; i++) { - if (i == thread->pipe_fds[0] || i == thread->pipe_fds[1]) + if (i == thread->pipe_fds[0] || i == thread->pipe_fds[1]) { continue; + } process_fd(thread, i, FD_ISSET(i, readfds), FD_ISSET(i, writefds)); } } -#endif +#endif /* ifdef USE_KQUEUE */ static bool process_ctlfd(isc__socketthread_t *thread) { @@ -3375,8 +3345,9 @@ process_ctlfd(isc__socketthread_t *thread) { /* * Nothing to read? */ - if (msg == SELECT_POKE_NOTHING) + if (msg == SELECT_POKE_NOTHING) { break; + } /* * Handle shutdown message. We really should @@ -3384,8 +3355,9 @@ process_ctlfd(isc__socketthread_t *thread) { * it doesn't matter if we have to do a little * more work first. */ - if (msg == SELECT_POKE_SHUTDOWN) + if (msg == SELECT_POKE_SHUTDOWN) { return (true); + } /* * This is a wakeup on a socket. Look @@ -3418,7 +3390,7 @@ netthread(void *uap) { } #ifdef USE_KQUEUE const char *fnname = "kevent()"; -#elif defined (USE_EPOLL) +#elif defined(USE_EPOLL) const char *fnname = "epoll_wait()"; #elif defined(USE_DEVPOLL) isc_result_t result; @@ -3427,29 +3399,28 @@ netthread(void *uap) { int pass; #if defined(ISC_SOCKET_USE_POLLWATCH) pollstate_t pollstate = poll_idle; -#endif -#elif defined (USE_SELECT) +#endif /* if defined(ISC_SOCKET_USE_POLLWATCH) */ +#elif defined(USE_SELECT) const char *fnname = "select()"; int maxfd; int ctlfd; -#endif +#endif /* ifdef USE_KQUEUE */ char strbuf[ISC_STRERRORSIZE]; -#if defined (USE_SELECT) +#if defined(USE_SELECT) /* * Get the control fd here. This will never change. */ ctlfd = thread->pipe_fds[0]; -#endif +#endif /* if defined(USE_SELECT) */ done = false; while (!done) { do { #ifdef USE_KQUEUE - cc = kevent(thread->kqueue_fd, NULL, 0, - thread->events, thread->nevents, NULL); + cc = kevent(thread->kqueue_fd, NULL, 0, thread->events, + thread->nevents, NULL); #elif defined(USE_EPOLL) - cc = epoll_wait(thread->epoll_fd, - thread->events, + cc = epoll_wait(thread->epoll_fd, thread->events, thread->nevents, -1); #elif defined(USE_DEVPOLL) /* @@ -3457,8 +3428,8 @@ netthread(void *uap) { */ if (thread->calls++ > 1000U) { result = isc_resource_getcurlimit( - isc_resource_openfiles, - &thread->open_max); + isc_resource_openfiles, + &thread->open_max); if (result != ISC_R_SUCCESS) { thread->open_max = 64; } @@ -3472,14 +3443,14 @@ netthread(void *uap) { } #ifndef ISC_SOCKET_USE_POLLWATCH dvp.dp_timeout = -1; -#else +#else /* ifndef ISC_SOCKET_USE_POLLWATCH */ if (pollstate == poll_idle) { dvp.dp_timeout = -1; } else { dvp.dp_timeout = - ISC_SOCKET_POLLWATCH_TIMEOUT; + ISC_SOCKET_POLLWATCH_TIMEOUT; } -#endif /* ISC_SOCKET_USE_POLLWATCH */ +#endif /* ISC_SOCKET_USE_POLLWATCH */ cc = ioctl(thread->devpoll_fd, DP_POLL, &dvp); if (cc == -1 && errno == EINVAL) { /* @@ -3487,8 +3458,8 @@ netthread(void *uap) { * up the current value and try again. */ result = isc_resource_getcurlimit( - isc_resource_openfiles, - &thread->open_max); + isc_resource_openfiles, + &thread->open_max); if (result != ISC_R_SUCCESS) { thread->open_max = 64; } @@ -3511,12 +3482,12 @@ netthread(void *uap) { cc = select(maxfd, thread->read_fds_copy, thread->write_fds_copy, NULL, NULL); -#endif /* USE_KQUEUE */ +#endif /* USE_KQUEUE */ if (cc < 0 && !SOFT_ERROR(errno)) { strerror_r(errno, strbuf, sizeof(strbuf)); - FATAL_ERROR(__FILE__, __LINE__, - "%s failed: %s", fnname, strbuf); + FATAL_ERROR(__FILE__, __LINE__, "%s failed: %s", + fnname, strbuf); } #if defined(USE_DEVPOLL) && defined(ISC_SOCKET_USE_POLLWATCH) @@ -3544,10 +3515,10 @@ netthread(void *uap) { } pollstate = poll_active; } -#endif +#endif /* if defined(USE_DEVPOLL) && defined(ISC_SOCKET_USE_POLLWATCH) */ } while (cc < 0); -#if defined(USE_KQUEUE) || defined (USE_EPOLL) || defined (USE_DEVPOLL) +#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) done = process_fds(thread, thread->events, cc); #elif defined(USE_SELECT) process_fds(thread, maxfd, thread->read_fds_copy, @@ -3559,7 +3530,8 @@ netthread(void *uap) { if (FD_ISSET(ctlfd, thread->read_fds_copy)) { done = process_ctlfd(thread); } -#endif +#endif /* if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) \ + * */ } thread_log(thread, TRACE, "watcher exiting"); @@ -3576,7 +3548,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *manager0, uint32_t reserved) { } void -isc_socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) { +isc_socketmgr_maxudp(isc_socketmgr_t *manager0, unsigned int maxudp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); @@ -3601,7 +3573,7 @@ setup_thread(isc__socketthread_t *thread) { thread->fds = isc_mem_get(thread->manager->mctx, thread->manager->maxsocks * - sizeof(isc__socket_t *)); + sizeof(isc__socket_t *)); memset(thread->fds, 0, thread->manager->maxsocks * sizeof(isc_socket_t *)); @@ -3620,8 +3592,7 @@ setup_thread(isc__socketthread_t *thread) { if (pipe(thread->pipe_fds) != 0) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "pipe() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "pipe() failed: %s", strbuf); return (ISC_R_UNEXPECTED); } @@ -3636,8 +3607,7 @@ setup_thread(isc__socketthread_t *thread) { if (thread->kqueue_fd == -1) { result = isc__errno2result(errno); strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "kqueue failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "kqueue failed: %s", strbuf); isc_mem_put(thread->manager->mctx, thread->events, sizeof(struct kevent) * thread->nevents); @@ -3654,26 +3624,24 @@ setup_thread(isc__socketthread_t *thread) { #elif defined(USE_EPOLL) thread->nevents = ISC_SOCKET_MAXEVENTS; - thread->epoll_events = isc_mem_get(thread->manager->mctx, - (thread->manager->maxsocks * - sizeof(uint32_t))); + thread->epoll_events = + isc_mem_get(thread->manager->mctx, + (thread->manager->maxsocks * sizeof(uint32_t))); memset(thread->epoll_events, 0, thread->manager->maxsocks * sizeof(uint32_t)); - thread->events = isc_mem_get(thread->manager->mctx, - sizeof(struct epoll_event) * - thread->nevents); + thread->events = + isc_mem_get(thread->manager->mctx, + sizeof(struct epoll_event) * thread->nevents); thread->epoll_fd = epoll_create(thread->nevents); if (thread->epoll_fd == -1) { result = isc__errno2result(errno); strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "epoll_create failed: %s", - strbuf); + UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_create failed: %s", + strbuf); return (result); - } result = watch_fd(thread, thread->pipe_fds[0], SELECT_POKE_READ); @@ -3683,8 +3651,9 @@ setup_thread(isc__socketthread_t *thread) { thread->nevents = ISC_SOCKET_MAXEVENTS; result = isc_resource_getcurlimit(isc_resource_openfiles, &thread->open_max); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { thread->open_max = 64; + } thread->calls = 0; thread->events = isc_mem_get(thread->manager->mctx, sizeof(struct pollfd) * thread->nevents); @@ -3693,18 +3662,17 @@ setup_thread(isc__socketthread_t *thread) { * Note: fdpollinfo should be able to support all possible FDs, so * it must have maxsocks entries (not nevents). */ - thread->fdpollinfo = isc_mem_get(thread->manager->mctx, - sizeof(pollinfo_t) * - thread->manager->maxsocks); - memset(thread->fdpollinfo, 0, sizeof(pollinfo_t) * - thread->manager->maxsocks); + thread->fdpollinfo = + isc_mem_get(thread->manager->mctx, + sizeof(pollinfo_t) * thread->manager->maxsocks); + memset(thread->fdpollinfo, 0, + sizeof(pollinfo_t) * thread->manager->maxsocks); thread->devpoll_fd = open("/dev/poll", O_RDWR); if (thread->devpoll_fd == -1) { result = isc__errno2result(errno); strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "open(/dev/poll) failed: %s", - strbuf); + "open(/dev/poll) failed: %s", strbuf); isc_mem_put(thread->manager->mctx, thread->events, sizeof(struct pollfd) * thread->nevents); isc_mem_put(thread->manager->mctx, thread->fdpollinfo, @@ -3731,11 +3699,11 @@ setup_thread(isc__socketthread_t *thread) { * FD_SETSIZE, but we separate the cases to avoid possible portability * issues regarding howmany() and the actual representation of fd_set. */ - thread->fd_bufsize = - howmany(manager->maxsocks, NFDBITS) * sizeof(fd_mask); -#else + thread->fd_bufsize = howmany(manager->maxsocks, NFDBITS) * + sizeof(fd_mask); +#else /* if ISC_SOCKET_MAXSOCKETS > FD_SETSIZE */ thread->fd_bufsize = sizeof(fd_set); -#endif +#endif /* if ISC_SOCKET_MAXSOCKETS > FD_SETSIZE */ thread->read_fds = isc_mem_get(thread->manager->mctx, thread->fd_bufsize); @@ -3752,7 +3720,7 @@ setup_thread(isc__socketthread_t *thread) { thread->maxfd = thread->pipe_fds[0]; return (ISC_R_SUCCESS); -#endif /* USE_KQUEUE */ +#endif /* USE_KQUEUE */ } static void @@ -3762,8 +3730,7 @@ cleanup_thread(isc_mem_t *mctx, isc__socketthread_t *thread) { result = unwatch_fd(thread, thread->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "epoll_ctl(DEL) failed"); + UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_ctl(DEL) failed"); } #ifdef USE_KQUEUE close(thread->kqueue_fd); @@ -3793,7 +3760,7 @@ cleanup_thread(isc_mem_t *mctx, isc__socketthread_t *thread) { if (thread->write_fds_copy != NULL) { isc_mem_put(mctx, thread->write_fds_copy, thread->fd_bufsize); } -#endif /* USE_KQUEUE */ +#endif /* USE_KQUEUE */ for (i = 0; i < (int)thread->manager->maxsocks; i++) { if (thread->fdstate[i] == CLOSE_PENDING) { /* no need to lock */ @@ -3804,21 +3771,17 @@ cleanup_thread(isc_mem_t *mctx, isc__socketthread_t *thread) { #if defined(USE_EPOLL) isc_mem_put(thread->manager->mctx, thread->epoll_events, thread->manager->maxsocks * sizeof(uint32_t)); -#endif +#endif /* if defined(USE_EPOLL) */ isc_mem_put(thread->manager->mctx, thread->fds, thread->manager->maxsocks * sizeof(isc__socket_t *)); isc_mem_put(thread->manager->mctx, thread->fdstate, thread->manager->maxsocks * sizeof(int)); - - if (thread->fdlock != NULL) { - for (i = 0; i < FDLOCK_COUNT; i++) { - isc_mutex_destroy(&thread->fdlock[i]); - } - isc_mem_put(thread->manager->mctx, thread->fdlock, - FDLOCK_COUNT * sizeof(isc_mutex_t)); + for (i = 0; i < FDLOCK_COUNT; i++) { + isc_mutex_destroy(&thread->fdlock[i]); } - + isc_mem_put(thread->manager->mctx, thread->fdlock, + FDLOCK_COUNT * sizeof(isc_mutex_t)); } isc_result_t @@ -3828,15 +3791,15 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { isc_result_t isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, - unsigned int maxsocks, int nthreads) -{ + unsigned int maxsocks, int nthreads) { int i; isc__socketmgr_t *manager; REQUIRE(managerp != NULL && *managerp == NULL); - if (maxsocks == 0) + if (maxsocks == 0) { maxsocks = ISC_SOCKET_MAXSOCKETS; + } manager = isc_mem_get(mctx, sizeof(*manager)); @@ -3858,18 +3821,16 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, /* * Start up the select/poll thread. */ - manager->threads = isc_mem_get(mctx, sizeof(isc__socketthread_t) - * manager->nthreads); + manager->threads = isc_mem_get(mctx, sizeof(isc__socketthread_t) * + manager->nthreads); isc_mem_attach(mctx, &manager->mctx); - for (i=0; i < manager->nthreads; i++) { + for (i = 0; i < manager->nthreads; i++) { manager->threads[i].manager = manager; manager->threads[i].threadid = i; setup_thread(&manager->threads[i]); - RUNTIME_CHECK(isc_thread_create(netthread, - &manager->threads[i], - &manager->threads[i].thread) - == ISC_R_SUCCESS); + isc_thread_create(netthread, &manager->threads[i], + &manager->threads[i].thread); char tname[1024]; sprintf(tname, "isc-socket-%d", i); isc_thread_setname(manager->threads[i].thread, tname); @@ -3878,7 +3839,6 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, *managerp = (isc_socketmgr_t *)manager; return (ISC_R_SUCCESS); - } isc_result_t @@ -3907,8 +3867,6 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats) { void isc_socketmgr_destroy(isc_socketmgr_t **managerp) { isc__socketmgr_t *manager; - isc_mem_t *mctx; - int i; /* * Destroy a socket manager. @@ -3935,20 +3893,15 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { * half of the pipe, which will send EOF to the read half. * This is currently a no-op in the non-threaded case. */ - for (i = 0; i < manager->nthreads; i++) { + for (int i = 0; i < manager->nthreads; i++) { select_poke(manager, i, 0, SELECT_POKE_SHUTDOWN); } /* * Wait for thread to exit. */ - for (i = 0; i < manager->nthreads; i++) { - isc_result_t result; - result = isc_thread_join(manager->threads[i].thread, NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_thread_join() failed"); - } + for (int i = 0; i < manager->nthreads; i++) { + isc_thread_join(manager->threads[i].thread, NULL); cleanup_thread(manager->mctx, &manager->threads[i]); } /* @@ -3964,19 +3917,14 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { isc_mutex_destroy(&manager->lock); manager->common.magic = 0; manager->common.impmagic = 0; - mctx= manager->mctx; - isc_mem_put(mctx, manager, sizeof(*manager)); - - isc_mem_detach(&mctx); + isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager)); *managerp = NULL; - } static isc_result_t socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, - unsigned int flags) -{ + unsigned int flags) { int io_state; bool have_lock = false; isc_task_t *ntask = NULL; @@ -4025,8 +3973,7 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, } socket_log(sock, NULL, EVENT, - "socket_recv: event %p -> task %p", - dev, ntask); + "socket_recv: event %p -> task %p", dev, ntask); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) { result = ISC_R_INPROGRESS; @@ -4053,10 +4000,8 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, } isc_result_t -isc_socket_recv(isc_socket_t *sock0, isc_region_t *region, - unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, void *arg) -{ +isc_socket_recv(isc_socket_t *sock0, isc_region_t *region, unsigned int minimum, + isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; @@ -4069,19 +4014,19 @@ isc_socket_recv(isc_socket_t *sock0, isc_region_t *region, INSIST(sock->bound); - dev = allocate_socketevent(manager->mctx, sock, - ISC_SOCKEVENT_RECVDONE, action, arg); - if (dev == NULL) + dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, + action, arg); + if (dev == NULL) { return (ISC_R_NOMEMORY); + } return (isc_socket_recv2(sock0, region, minimum, task, dev, 0)); } isc_result_t isc_socket_recv2(isc_socket_t *sock0, isc_region_t *region, - unsigned int minimum, isc_task_t *task, - isc_socketevent_t *event, unsigned int flags) -{ + unsigned int minimum, isc_task_t *task, + isc_socketevent_t *event, unsigned int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; event->ev_sender = sock; @@ -4094,13 +4039,14 @@ isc_socket_recv2(isc_socket_t *sock0, isc_region_t *region, /* * UDP sockets are always partial read. */ - if (sock->type == isc_sockettype_udp) + if (sock->type == isc_sockettype_udp) { event->minimum = 1; - else { - if (minimum == 0) + } else { + if (minimum == 0) { event->minimum = region->length; - else + } else { event->minimum = minimum; + } } return (socket_recv(sock, event, task, flags)); @@ -4109,8 +4055,7 @@ isc_socket_recv2(isc_socket_t *sock0, isc_region_t *region, static isc_result_t socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, - unsigned int flags) -{ + unsigned int flags) { int io_state; bool have_lock = false; isc_task_t *ntask = NULL; @@ -4124,9 +4069,11 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, dev->pktinfo = *pktinfo; if (!isc_sockaddr_issitelocal(&dev->address) && - !isc_sockaddr_islinklocal(&dev->address)) { + !isc_sockaddr_islinklocal(&dev->address)) + { socket_log(sock, NULL, TRACE, - "pktinfo structure provided, ifindex %u (set to 0)", + "pktinfo structure provided, ifindex %u " + "(set to 0)", pktinfo->ipi6_ifindex); /* @@ -4174,12 +4121,11 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link); if (do_poke) { select_poke(sock->manager, sock->threadid, - sock->fd, - SELECT_POKE_WRITE); + sock->fd, SELECT_POKE_WRITE); } socket_log(sock, NULL, EVENT, - "socket_send: event %p -> task %p", - dev, ntask); + "socket_send: event %p -> task %p", dev, + ntask); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) { result = ISC_R_INPROGRESS; @@ -4191,6 +4137,10 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, case DOIO_HARD: case DOIO_SUCCESS: + if (!have_lock) { + LOCK(&sock->lock); + have_lock = true; + } if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0) { send_senddone_event(sock, &dev); } @@ -4205,21 +4155,18 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, } isc_result_t -isc_socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ +isc_socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg) { /* * REQUIRE() checking is performed in isc_socket_sendto(). */ - return (isc_socket_sendto(sock, region, task, action, arg, NULL, - NULL)); + return (isc_socket_sendto(sock, region, task, action, arg, NULL, NULL)); } isc_result_t -isc_socket_sendto(isc_socket_t *sock0, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg, - const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) -{ +isc_socket_sendto(isc_socket_t *sock0, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg, + const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; @@ -4234,10 +4181,11 @@ isc_socket_sendto(isc_socket_t *sock0, isc_region_t *region, INSIST(sock->bound); - dev = allocate_socketevent(manager->mctx, sock, - ISC_SOCKEVENT_SENDDONE, action, arg); - if (dev == NULL) + dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, + action, arg); + if (dev == NULL) { return (ISC_R_NOMEMORY); + } dev->region = *region; @@ -4245,17 +4193,17 @@ isc_socket_sendto(isc_socket_t *sock0, isc_region_t *region, } isc_result_t -isc_socket_sendto2(isc_socket_t *sock0, isc_region_t *region, - isc_task_t *task, - const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, - isc_socketevent_t *event, unsigned int flags) -{ +isc_socket_sendto2(isc_socket_t *sock0, isc_region_t *region, isc_task_t *task, + const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, + isc_socketevent_t *event, unsigned int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); - REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0); - if ((flags & ISC_SOCKFLAG_NORETRY) != 0) + REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE | ISC_SOCKFLAG_NORETRY)) == + 0); + if ((flags & ISC_SOCKFLAG_NORETRY) != 0) { REQUIRE(sock->type == isc_sockettype_udp); + } event->ev_sender = sock; event->result = ISC_R_UNSET; event->region = *region; @@ -4273,53 +4221,68 @@ isc_socket_cleanunix(const isc_sockaddr_t *sockaddr, bool active) { struct stat sb; char strbuf[ISC_STRERRORSIZE]; - if (sockaddr->type.sa.sa_family != AF_UNIX) + if (sockaddr->type.sa.sa_family != AF_UNIX) { return; + } #ifndef S_ISSOCK #if defined(S_IFMT) && defined(S_IFSOCK) -#define S_ISSOCK(mode) ((mode & S_IFMT)==S_IFSOCK) +#define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) #elif defined(_S_IFMT) && defined(S_IFSOCK) -#define S_ISSOCK(mode) ((mode & _S_IFMT)==S_IFSOCK) -#endif -#endif +#define S_ISSOCK(mode) ((mode & _S_IFMT) == S_IFSOCK) +#endif /* if defined(S_IFMT) && defined(S_IFSOCK) */ +#endif /* ifndef S_ISSOCK */ #ifndef S_ISFIFO #if defined(S_IFMT) && defined(S_IFIFO) -#define S_ISFIFO(mode) ((mode & S_IFMT)==S_IFIFO) +#define S_ISFIFO(mode) ((mode & S_IFMT) == S_IFIFO) #elif defined(_S_IFMT) && defined(S_IFIFO) -#define S_ISFIFO(mode) ((mode & _S_IFMT)==S_IFIFO) -#endif -#endif +#define S_ISFIFO(mode) ((mode & _S_IFMT) == S_IFIFO) +#endif /* if defined(S_IFMT) && defined(S_IFIFO) */ +#endif /* ifndef S_ISFIFO */ #if !defined(S_ISFIFO) && !defined(S_ISSOCK) -#error You need to define S_ISFIFO and S_ISSOCK as appropriate for your platform. See <sys/stat.h>. -#endif +/* cppcheck-suppress preprocessorErrorDirective */ +#error \ + You need to define S_ISFIFO and S_ISSOCK as appropriate for your platform. See <sys/stat.h>. +#endif /* if !defined(S_ISFIFO) && !defined(S_ISSOCK) */ #ifndef S_ISFIFO #define S_ISFIFO(mode) 0 -#endif +#endif /* ifndef S_ISFIFO */ #ifndef S_ISSOCK #define S_ISSOCK(mode) 0 -#endif +#endif /* ifndef S_ISSOCK */ - if (active) { - if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) { + if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) { + switch (errno) { + case ENOENT: + if (active) { /* We exited cleanly last time */ + break; + } + /* intentional fallthrough */ + default: strerror_r(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, + ISC_LOGMODULE_SOCKET, + active ? ISC_LOG_ERROR : ISC_LOG_WARNING, "isc_socket_cleanunix: stat(%s): %s", sockaddr->type.sunix.sun_path, strbuf); return; } + } else { if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, + ISC_LOGMODULE_SOCKET, + active ? ISC_LOG_ERROR : ISC_LOG_WARNING, "isc_socket_cleanunix: %s: not a socket", sockaddr->type.sunix.sun_path); return; } + } + + if (active) { if (unlink(sockaddr->type.sunix.sun_path) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, @@ -4340,43 +4303,20 @@ isc_socket_cleanunix(const isc_sockaddr_t *sockaddr, bool active) { return; } - if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) { - switch (errno) { - case ENOENT: /* We exited cleanly last time */ - break; - default: - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, - "isc_socket_cleanunix: stat(%s): %s", - sockaddr->type.sunix.sun_path, strbuf); - break; - } - goto cleanup; - } - - if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, - "isc_socket_cleanunix: %s: not a socket", - sockaddr->type.sunix.sun_path); - goto cleanup; - } - if (connect(s, (const struct sockaddr *)&sockaddr->type.sunix, - sizeof(sockaddr->type.sunix)) < 0) { + sizeof(sockaddr->type.sunix)) < 0) + { switch (errno) { case ECONNREFUSED: case ECONNRESET: if (unlink(sockaddr->type.sunix.sun_path) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, - ISC_LOG_WARNING, - "isc_socket_cleanunix: " - "unlink(%s): %s", - sockaddr->type.sunix.sun_path, - strbuf); + isc_log_write( + isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, + "isc_socket_cleanunix: " + "unlink(%s): %s", + sockaddr->type.sunix.sun_path, strbuf); } break; default: @@ -4388,25 +4328,23 @@ isc_socket_cleanunix(const isc_sockaddr_t *sockaddr, bool active) { break; } } - cleanup: close(s); -#else +#else /* ifdef ISC_PLATFORM_HAVESYSUNH */ UNUSED(sockaddr); UNUSED(active); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ } isc_result_t isc_socket_permunix(const isc_sockaddr_t *sockaddr, uint32_t perm, - uint32_t owner, uint32_t group) -{ + uint32_t owner, uint32_t group) { #ifdef ISC_PLATFORM_HAVESYSUNH isc_result_t result = ISC_R_SUCCESS; char strbuf[ISC_STRERRORSIZE]; char path[sizeof(sockaddr->type.sunix.sun_path)]; #ifdef NEED_SECURE_DIRECTORY char *slash; -#endif +#endif /* ifdef NEED_SECURE_DIRECTORY */ REQUIRE(sockaddr->type.sa.sa_family == AF_UNIX); INSIST(strlen(sockaddr->type.sunix.sun_path) < sizeof(path)); @@ -4423,14 +4361,14 @@ isc_socket_permunix(const isc_sockaddr_t *sockaddr, uint32_t perm, } else { strlcpy(path, ".", sizeof(path)); } -#endif +#endif /* ifdef NEED_SECURE_DIRECTORY */ if (chmod(path, perm) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "isc_socket_permunix: chmod(%s, %d): %s", - path, perm, strbuf); + "isc_socket_permunix: chmod(%s, %d): %s", path, + perm, strbuf); result = ISC_R_FAILURE; } if (chown(path, owner, group) < 0) { @@ -4438,24 +4376,22 @@ isc_socket_permunix(const isc_sockaddr_t *sockaddr, uint32_t perm, isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_permunix: chown(%s, %d, %d): %s", - path, owner, group, - strbuf); + path, owner, group, strbuf); result = ISC_R_FAILURE; } return (result); -#else +#else /* ifdef ISC_PLATFORM_HAVESYSUNH */ UNUSED(sockaddr); UNUSED(perm); UNUSED(owner); UNUSED(group); return (ISC_R_NOTIMPLEMENTED); -#endif +#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ } isc_result_t isc_socket_bind(isc_socket_t *sock0, const isc_sockaddr_t *sockaddr, - isc_socket_options_t options) -{ + isc_socket_options_t options) { isc__socket_t *sock = (isc__socket_t *)sock0; char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -4479,13 +4415,12 @@ isc_socket_bind(isc_socket_t *sock0, const isc_sockaddr_t *sockaddr, if (sock->pf == AF_UNIX) { goto bind_socket; } -#endif +#endif /* ifdef AF_UNIX */ if ((options & ISC_SOCKET_REUSEADDRESS) != 0 && - isc_sockaddr_getport(sockaddr) != (in_port_t) 0) + isc_sockaddr_getport(sockaddr) != (in_port_t)0) { - if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, - (void *)&on, sizeof(on)) < 0) - { + if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, + sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d) failed", sock->fd); } @@ -4497,18 +4432,17 @@ isc_socket_bind(isc_socket_t *sock0, const isc_sockaddr_t *sockaddr, "setsockopt(%d) failed", sock->fd); } #elif defined(__linux__) && defined(SO_REUSEPORT) - if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEPORT, - (void *)&on, sizeof(on)) < 0) - { + if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEPORT, (void *)&on, + sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d) failed", sock->fd); } -#endif +#endif /* if defined(__FreeBSD_kernel__) && defined(SO_REUSEPORT_LB) */ /* Press on... */ } #ifdef AF_UNIX - bind_socket: -#endif +bind_socket: +#endif /* ifdef AF_UNIX */ if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) { inc_stats(sock->manager->stats, sock->statsindex[STATID_BINDFAIL]); @@ -4541,7 +4475,7 @@ isc_socket_bind(isc_socket_t *sock0, const isc_sockaddr_t *sockaddr, /* * Enable this only for specific OS versions, and only when they have repaired * their problems with it. Until then, this is is broken and needs to be - * diabled by default. See RT22589 for details. + * disabled by default. See RT22589 for details. */ #undef ENABLE_ACCEPTFILTER @@ -4551,27 +4485,27 @@ isc_socket_filter(isc_socket_t *sock0, const char *filter) { #if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) char strbuf[ISC_STRERRORSIZE]; struct accept_filter_arg afa; -#else +#else /* if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) */ UNUSED(sock); UNUSED(filter); -#endif +#endif /* if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) */ REQUIRE(VALID_SOCKET(sock)); #if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) bzero(&afa, sizeof(afa)); strlcpy(afa.af_name, filter, sizeof(afa.af_name)); - if (setsockopt(sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, - &afa, sizeof(afa)) == -1) { + if (setsockopt(sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, + sizeof(afa)) == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); socket_log(sock, NULL, CREATION, "setsockopt(SO_ACCEPTFILTER): %s", strbuf); return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); -#else +#else /* if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) */ return (ISC_R_NOTIMPLEMENTED); -#endif +#endif /* if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) */ } /* @@ -4614,27 +4548,29 @@ set_tcp_fastopen(isc__socket_t *sock, unsigned int backlog) { } return; } -#endif +#endif /* if defined(__FreeBSD__) && defined(HAVE_SYSCTLBYNAME) */ #ifdef __APPLE__ backlog = 1; -#else +#else /* ifdef __APPLE__ */ backlog = backlog / 2; - if (backlog == 0) + if (backlog == 0) { backlog = 1; -#endif - if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN, - (void *)&backlog, sizeof(backlog)) < 0) { + } +#endif /* ifdef __APPLE__ */ + if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN, (void *)&backlog, + sizeof(backlog)) < 0) + { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, TCP_FASTOPEN) failed with %s", sock->fd, strbuf); /* TCP_FASTOPEN is experimental so ignore failures */ } -#else +#else /* if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) */ UNUSED(sock); UNUSED(backlog); -#endif +#endif /* if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) */ } /* @@ -4661,8 +4597,9 @@ isc_socket_listen(isc_socket_t *sock0, unsigned int backlog) { REQUIRE(sock->type == isc_sockettype_tcp || sock->type == isc_sockettype_unix); - if (backlog == 0) + if (backlog == 0) { backlog = SOMAXCONN; + } if (listen(sock->fd, (int)backlog) < 0) { UNLOCK(&sock->lock); @@ -4685,9 +4622,8 @@ isc_socket_listen(isc_socket_t *sock0, unsigned int backlog) { * This should try to do aggressive accept() XXXMLG */ isc_result_t -isc_socket_accept(isc_socket_t *sock0, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ +isc_socket_accept(isc_socket_t *sock0, isc_task_t *task, + isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_newconnev_t *dev; isc__socketmgr_t *manager; @@ -4709,13 +4645,9 @@ isc_socket_accept(isc_socket_t *sock0, * this event to. Just before the actual event is delivered the * actual ev_sender will be touched up to be the socket. */ - dev = (isc_socket_newconnev_t *) - isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN, - action, arg, sizeof(*dev)); - if (dev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } + dev = (isc_socket_newconnev_t *)isc_event_allocate( + manager->mctx, task, ISC_SOCKEVENT_NEWCONN, action, arg, + sizeof(*dev)); ISC_LINK_INIT(dev, ev_link); result = allocate_socket(manager, sock->type, &nsock); @@ -4736,7 +4668,7 @@ isc_socket_accept(isc_socket_t *sock0, UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } - isc_refcount_increment(&nsock->references); + isc_refcount_increment0(&nsock->references); nsock->statsindex = sock->statsindex; dev->ev_sender = ntask; @@ -4759,8 +4691,7 @@ isc_socket_accept(isc_socket_t *sock0, isc_result_t isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ + isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_connev_t *dev; isc_task_t *ntask = NULL; @@ -4778,19 +4709,15 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, REQUIRE(VALID_MANAGER(manager)); REQUIRE(addr != NULL); - if (isc_sockaddr_ismulticast(addr)) + if (isc_sockaddr_ismulticast(addr)) { return (ISC_R_MULTICAST); + } LOCK(&sock->lock); - dev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock, - ISC_SOCKEVENT_CONNECT, - action, arg, - sizeof(*dev)); - if (dev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } + dev = (isc_socket_connev_t *)isc_event_allocate( + manager->mctx, sock, ISC_SOCKEVENT_CONNECT, action, arg, + sizeof(*dev)); ISC_LINK_INIT(dev, ev_link); if (sock->connecting) { @@ -4829,11 +4756,15 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, cc = 0; goto success; } - if (SOFT_ERROR(errno) || errno == EINPROGRESS) + if (SOFT_ERROR(errno) || errno == EINPROGRESS) { goto queue; + } switch (errno) { -#define ERROR_MATCH(a, b) case a: dev->result = b; goto err_exit; +#define ERROR_MATCH(a, b) \ + case a: \ + dev->result = b; \ + goto err_exit; ERROR_MATCH(EACCES, ISC_R_NOPERM); ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); @@ -4841,11 +4772,12 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif +#endif /* ifdef EHOSTDOWN */ ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); ERROR_MATCH(EPIPE, ISC_R_NOTCONNECTED); + ERROR_MATCH(ETIMEDOUT, ISC_R_TIMEDOUT); ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET); #undef ERROR_MATCH } @@ -4876,7 +4808,7 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, /* * If connect completed, fire off the done event. */ - success: +success: if (cc == 0) { sock->connected = 1; sock->bound = 1; @@ -4891,7 +4823,7 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr, return (ISC_R_SUCCESS); } - queue: +queue: /* * Attach to task. @@ -4930,8 +4862,7 @@ internal_connect(isc__socket_t *sock) { char peerbuf[ISC_SOCKADDR_FORMATSIZE]; INSIST(VALID_SOCKET(sock)); - - LOCK(&sock->lock); + REQUIRE(sock->fd >= 0); /* * Get the first item off the connect list. @@ -4950,11 +4881,13 @@ internal_connect(isc__socket_t *sock) { * Get any possible error status here. */ optlen = sizeof(cc); - if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, - (void *)&cc, (void *)&optlen) != 0) + if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, (void *)&cc, + (void *)&optlen) != 0) + { cc = errno; - else + } else { errno = cc; + } if (errno != 0) { /* @@ -4963,7 +4896,6 @@ internal_connect(isc__socket_t *sock) { */ if (SOFT_ERROR(errno) || errno == EINPROGRESS) { sock->connecting = 1; - UNLOCK(&sock->lock); return; } @@ -4974,7 +4906,10 @@ internal_connect(isc__socket_t *sock) { * Translate other errors into ISC_R_* flavors. */ switch (errno) { -#define ERROR_MATCH(a, b) case a: result = b; break; +#define ERROR_MATCH(a, b) \ + case a: \ + result = b; \ + break; ERROR_MATCH(EACCES, ISC_R_NOPERM); ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); @@ -4982,7 +4917,7 @@ internal_connect(isc__socket_t *sock) { ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif +#endif /* ifdef EHOSTDOWN */ ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); @@ -5013,11 +4948,9 @@ internal_connect(isc__socket_t *sock) { dev = ISC_LIST_HEAD(sock->connect_list); } while (dev != NULL); - finish: +finish: unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd, SELECT_POKE_CONNECT); - - UNLOCK(&sock->lock); } isc_result_t @@ -5064,14 +4997,13 @@ isc_socket_getsockname(isc_socket_t *sock0, isc_sockaddr_t *addressp) { len = sizeof(addressp->type); if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", - strbuf); + UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", strbuf); result = ISC_R_UNEXPECTED; goto out; } addressp->length = (unsigned int)len; - out: +out: UNLOCK(&sock->lock); return (result); @@ -5091,8 +5023,9 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { * Quick exit if there is nothing to do. Don't even bother locking * in this case. */ - if (how == 0) + if (how == 0) { return; + } LOCK(&sock->lock); @@ -5106,11 +5039,11 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { * its done event with status of "ISC_R_CANCELED". * o Reset any state needed. */ - if (((how & ISC_SOCKCANCEL_RECV) != 0) - && !ISC_LIST_EMPTY(sock->recv_list)) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; + if (((how & ISC_SOCKCANCEL_RECV) != 0) && + !ISC_LIST_EMPTY(sock->recv_list)) { + isc_socketevent_t *dev; + isc_socketevent_t *next; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->recv_list); @@ -5126,11 +5059,11 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { } } - if (((how & ISC_SOCKCANCEL_SEND) != 0) - && !ISC_LIST_EMPTY(sock->send_list)) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; + if (((how & ISC_SOCKCANCEL_SEND) != 0) && + !ISC_LIST_EMPTY(sock->send_list)) { + isc_socketevent_t *dev; + isc_socketevent_t *next; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->send_list); @@ -5146,11 +5079,11 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { } } - if (((how & ISC_SOCKCANCEL_ACCEPT) != 0) - && !ISC_LIST_EMPTY(sock->accept_list)) { + if (((how & ISC_SOCKCANCEL_ACCEPT) != 0) && + !ISC_LIST_EMPTY(sock->accept_list)) { isc_socket_newconnev_t *dev; isc_socket_newconnev_t *next; - isc_task_t *current_task; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->accept_list); while (dev != NULL) { @@ -5158,12 +5091,11 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { - ISC_LIST_UNLINK(sock->accept_list, dev, ev_link); - (void)isc_refcount_decrement( - &NEWCONNSOCK(dev)->references); + isc_refcount_decrementz( + &NEWCONNSOCK(dev)->references); free_socket((isc__socket_t **)&dev->newsocket); dev->result = ISC_R_CANCELED; @@ -5177,11 +5109,12 @@ isc_socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { } } - if (((how & ISC_SOCKCANCEL_CONNECT) != 0) - && !ISC_LIST_EMPTY(sock->connect_list)) { - isc_socket_connev_t *dev; - isc_socket_connev_t *next; - isc_task_t *current_task; + if (((how & ISC_SOCKCANCEL_CONNECT) != 0) && + !ISC_LIST_EMPTY(sock->connect_list)) + { + isc_socket_connev_t *dev; + isc_socket_connev_t *next; + isc_task_t *current_task; INSIST(sock->connecting); sock->connecting = 0; @@ -5217,10 +5150,10 @@ isc_socket_ipv6only(isc_socket_t *sock0, bool yes) { isc__socket_t *sock = (isc__socket_t *)sock0; #if defined(IPV6_V6ONLY) int onoff = yes ? 1 : 0; -#else +#else /* if defined(IPV6_V6ONLY) */ UNUSED(yes); UNUSED(sock); -#endif +#endif /* if defined(IPV6_V6ONLY) */ REQUIRE(VALID_SOCKET(sock)); INSIST(!sock->dupped); @@ -5228,50 +5161,54 @@ isc_socket_ipv6only(isc_socket_t *sock0, bool yes) { #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, - (void *)&onoff, sizeof(int)) < 0) { + (void *)&onoff, sizeof(int)) < 0) + { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_V6ONLY) failed: %s", + "setsockopt(%d, IPV6_V6ONLY) failed: " + "%s", sock->fd, strbuf); } } -#endif +#endif /* ifdef IPV6_V6ONLY */ } static void setdscp(isc__socket_t *sock, isc_dscp_t dscp) { #if defined(IP_TOS) || defined(IPV6_TCLASS) int value = dscp << 2; -#endif +#endif /* if defined(IP_TOS) || defined(IPV6_TCLASS) */ sock->dscp = dscp; #ifdef IP_TOS if (sock->pf == AF_INET) { - if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS, - (void *)&value, sizeof(value)) < 0) { + if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS, (void *)&value, + sizeof(value)) < 0) { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IP_TOS, %.02x) failed: %s", - sock->fd, value >> 2, - strbuf); + "setsockopt(%d, IP_TOS, %.02x) " + "failed: %s", + sock->fd, value >> 2, strbuf); } } -#endif +#endif /* ifdef IP_TOS */ #ifdef IPV6_TCLASS if (sock->pf == AF_INET6) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, - (void *)&value, sizeof(value)) < 0) { + (void *)&value, sizeof(value)) < 0) + { char strbuf[ISC_STRERRORSIZE]; strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_TCLASS, %.02x) failed: %s", + "setsockopt(%d, IPV6_TCLASS, %.02x) " + "failed: %s", sock->fd, dscp >> 2, strbuf); } } -#endif +#endif /* ifdef IPV6_TCLASS */ } void @@ -5283,28 +5220,27 @@ isc_socket_dscp(isc_socket_t *sock0, isc_dscp_t dscp) { #if !defined(IP_TOS) && !defined(IPV6_TCLASS) UNUSED(dscp); -#else - if (dscp < 0) +#else /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */ + if (dscp < 0) { return; + } /* The DSCP value must not be changed once it has been set. */ - if (isc_dscp_check_value != -1) + if (isc_dscp_check_value != -1) { INSIST(dscp == isc_dscp_check_value); -#endif - + } +#endif /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */ #ifdef notyet REQUIRE(!sock->dupped); -#endif +#endif /* ifdef notyet */ setdscp(sock, dscp); } isc_socketevent_t * -isc_socket_socketevent(isc_mem_t *mctx, void *sender, - isc_eventtype_t eventtype, isc_taskaction_t action, - void *arg) -{ +isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, + isc_taskaction_t action, void *arg) { return (allocate_socketevent(mctx, sender, eventtype, action, arg)); } @@ -5342,11 +5278,11 @@ int isc_socket_getfd(isc_socket_t *socket0) { isc__socket_t *sock = (isc__socket_t *)socket0; - return ((short) sock->fd); + return ((short)sock->fd); } -static isc_once_t hasreuseport_once = ISC_ONCE_INIT; -static bool hasreuseport = false; +static isc_once_t hasreuseport_once = ISC_ONCE_INIT; +static bool hasreuseport = false; static void init_hasreuseport() { @@ -5356,7 +5292,7 @@ init_hasreuseport() { * sockets instead of re-binding them. */ #if (defined(SO_REUSEPORT) && defined(__linux__)) || \ - (defined(SO_REUSEPORT_LB) && defined(__FreeBSD_kernel__)) + (defined(SO_REUSEPORT_LB) && defined(__FreeBSD_kernel__)) int sock, yes = 1; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { @@ -5365,39 +5301,37 @@ init_hasreuseport() { return; } } - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&yes, sizeof(yes)) < 0) - { + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, + sizeof(yes)) < 0) { close(sock); return; #if defined(__FreeBSD_kernel__) - } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT_LB, - (void *)&yes, sizeof(yes)) < 0) -#else - } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, - (void *)&yes, sizeof(yes)) < 0) -#endif + } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT_LB, (void *)&yes, + sizeof(yes)) < 0) +#else /* if defined(__FreeBSD_kernel__) */ + } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void *)&yes, + sizeof(yes)) < 0) +#endif /* if defined(__FreeBSD_kernel__) */ { close(sock); return; } hasreuseport = true; close(sock); -#endif +#endif /* if (defined(SO_REUSEPORT) && defined(__linux__)) || \ + * (defined(SO_REUSEPORT_LB) && defined(__FreeBSD_kernel__)) */ } bool isc_socket_hasreuseport() { - RUNTIME_CHECK(isc_once_do(&hasreuseport_once, init_hasreuseport) - == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&hasreuseport_once, init_hasreuseport) == + ISC_R_SUCCESS); return (hasreuseport); } - -#if defined(HAVE_LIBXML2) || defined(HAVE_JSON) +#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) static const char * -_socktype(isc_sockettype_t type) -{ +_socktype(isc_sockettype_t type) { switch (type) { case isc_sockettype_udp: return ("udp"); @@ -5409,18 +5343,24 @@ _socktype(isc_sockettype_t type) return ("not-initialized"); } } -#endif +#endif /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */ #ifdef HAVE_LIBXML2 -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +#define TRY0(a) \ + do { \ + xmlrc = (a); \ + if (xmlrc < 0) \ + goto error; \ + } while (0) int -isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { +isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, void *writer0) { isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; isc__socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; socklen_t len; int xmlrc; + xmlTextWriterPtr writer = (xmlTextWriterPtr)writer0; LOCK(&mgr->lock); @@ -5444,46 +5384,52 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - (int)isc_refcount_current(&sock->references))); + TRY0(xmlTextWriterWriteFormatString( + writer, "%d", + (int)isc_refcount_current(&sock->references))); TRY0(xmlTextWriterEndElement(writer)); - TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR _socktype(sock->type))); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "type", + ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "peer-address", - ISC_XMLCHAR peerbuf)); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "peer-address", + ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "local-address", - ISC_XMLCHAR peerbuf)); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "local-address", + ISC_XMLCHAR peerbuf)); } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); - if (sock->listener) + if (sock->listener) { TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "listener")); - if (sock->connected) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "connected")); - if (sock->connecting) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "connecting")); - if (sock->bound) + } + if (sock->connected) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "connected")); + } + if (sock->connecting) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "connecting")); + } + if (sock->bound) { TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "bound")); + } TRY0(xmlTextWriterEndElement(writer)); /* states */ @@ -5494,9 +5440,10 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { } TRY0(xmlTextWriterEndElement(writer)); /* sockets */ - error: - if (sock != NULL) +error: + if (sock != NULL) { UNLOCK(&sock->lock); + } UNLOCK(&mgr->lock); @@ -5504,16 +5451,17 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { } #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) +#ifdef HAVE_JSON_C +#define CHECKMEM(m) \ + do { \ + if (m == NULL) { \ + result = ISC_R_NOMEMORY; \ + goto error; \ + } \ + } while (0) isc_result_t -isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) { +isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, void *stats0) { isc_result_t result = ISC_R_SUCCESS; isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; isc__socket_t *sock = NULL; @@ -5521,6 +5469,7 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) { isc_sockaddr_t addr; socklen_t len; json_object *obj, *array = json_object_new_array(); + json_object *stats = (json_object *)stats0; CHECKMEM(array); @@ -5548,7 +5497,7 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) { } obj = json_object_new_int( - (int)isc_refcount_current(&sock->references)); + (int)isc_refcount_current(&sock->references)); CHECKMEM(obj); json_object_object_add(entry, "references", obj); @@ -5608,29 +5557,26 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) { array = NULL; result = ISC_R_SUCCESS; - error: - if (array != NULL) +error: + if (array != NULL) { json_object_put(array); + } - if (sock != NULL) + if (sock != NULL) { UNLOCK(&sock->lock); + } UNLOCK(&mgr->lock); return (result); } -#endif /* HAVE_JSON */ +#endif /* HAVE_JSON_C */ isc_result_t -isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - isc_socketmgr_t **managerp) -{ +isc_socketmgr_createinctx(isc_mem_t *mctx, isc_socketmgr_t **managerp) { isc_result_t result; result = isc_socketmgr_create(mctx, managerp); - if (result == ISC_R_SUCCESS) - isc_appctx_setsocketmgr(actx, *managerp); - return (result); } diff --git a/lib/isc/unix/socket_p.h b/lib/isc/unix/socket_p.h index 6ab124d0..e6dd818d 100644 --- a/lib/isc/unix/socket_p.h +++ b/lib/isc/unix/socket_p.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SOCKET_P_H #define ISC_SOCKET_P_H @@ -18,7 +17,9 @@ #include <sys/time.h> typedef struct isc_socketwait isc_socketwait_t; -int isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *, - isc_socketwait_t **); -isc_result_t isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *); +int +isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *, + isc_socketwait_t **); +isc_result_t +isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *); #endif /* ISC_SOCKET_P_H */ diff --git a/lib/isc/unix/stdio.c b/lib/isc/unix/stdio.c index d2b1ddaa..2cbda65e 100644 --- a/lib/isc/unix/stdio.c +++ b/lib/isc/unix/stdio.c @@ -3,20 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <errno.h> #include <unistd.h> -#include <isc/stdio.h> #include <isc/stat.h> +#include <isc/stdio.h> #include <isc/util.h> #include "errno2result.h" @@ -26,8 +23,9 @@ isc_stdio_open(const char *filename, const char *mode, FILE **fp) { FILE *f; f = fopen(filename, mode); - if (f == NULL) + if (f == NULL) { return (isc__errno2result(errno)); + } *fp = f; return (ISC_R_SUCCESS); } @@ -37,10 +35,11 @@ isc_stdio_close(FILE *f) { int r; r = fclose(f); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -48,10 +47,11 @@ isc_stdio_seek(FILE *f, off_t offset, int whence) { int r; r = fseeko(f, offset, whence); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -64,8 +64,9 @@ isc_stdio_tell(FILE *f, off_t *offsetp) { if (r >= 0) { *offsetp = r; return (ISC_R_SUCCESS); - } else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -76,29 +77,32 @@ isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { clearerr(f); r = fread(ptr, size, nmemb, f); if (r != nmemb) { - if (feof(f)) + if (feof(f)) { result = ISC_R_EOF; - else + } else { result = isc__errno2result(errno); + } } - if (nret != NULL) + if (nret != NULL) { *nret = r; + } return (result); } isc_result_t isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, - size_t *nret) -{ + size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fwrite(ptr, size, nmemb, f); - if (r != nmemb) + if (r != nmemb) { result = isc__errno2result(errno); - if (nret != NULL) + } + if (nret != NULL) { *nret = r; + } return (result); } @@ -107,10 +111,11 @@ isc_stdio_flush(FILE *f) { int r; r = fflush(f); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } /* @@ -118,26 +123,28 @@ isc_stdio_flush(FILE *f) { */ #if defined(EOPNOTSUPP) && !defined(ENOTSUP) #define ENOTSUP EOPNOTSUPP -#endif +#endif /* if defined(EOPNOTSUPP) && !defined(ENOTSUP) */ isc_result_t isc_stdio_sync(FILE *f) { struct stat buf; int r; - if (fstat(fileno(f), &buf) != 0) + if (fstat(fileno(f), &buf) != 0) { return (isc__errno2result(errno)); + } /* * Only call fsync() on regular files. */ - if ((buf.st_mode & S_IFMT) != S_IFREG) + if ((buf.st_mode & S_IFMT) != S_IFREG) { return (ISC_R_SUCCESS); + } r = fsync(fileno(f)); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } - diff --git a/lib/isc/unix/stdtime.c b/lib/isc/unix/stdtime.c index 989bde46..363a699e 100644 --- a/lib/isc/unix/stdtime.c +++ b/lib/isc/unix/stdtime.c @@ -3,78 +3,64 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - +#include <errno.h> #include <stdbool.h> -#include <stddef.h> /* NULL */ -#include <stdlib.h> /* NULL */ +#include <stddef.h> /* NULL */ +#include <stdlib.h> /* NULL */ #include <syslog.h> - -#include <sys/time.h> +#include <time.h> #include <isc/stdtime.h> +#include <isc/strerr.h> #include <isc/util.h> -#ifndef ISC_FIX_TV_USEC -#define ISC_FIX_TV_USEC 1 -#endif +#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ + +#if defined(CLOCK_REALTIME_COARSE) +#define CLOCKSOURCE CLOCK_REALTIME_COARSE +#elif defined(CLOCK_REALTIME_FAST) +#define CLOCKSOURCE CLOCK_REALTIME_FAST +#else /* if defined(CLOCK_REALTIME_COARSE) */ +#define CLOCKSOURCE CLOCK_REALTIME +#endif /* if defined(CLOCK_REALTIME_COARSE) */ -#define US_PER_S 1000000 +void +isc_stdtime_get(isc_stdtime_t *t) { + REQUIRE(t != NULL); -#if ISC_FIX_TV_USEC -static inline void -fix_tv_usec(struct timeval *tv) { - bool fixed = false; + struct timespec ts; - if (tv->tv_usec < 0) { - fixed = true; - do { - tv->tv_sec -= 1; - tv->tv_usec += US_PER_S; - } while (tv->tv_usec < 0); - } else if (tv->tv_usec >= US_PER_S) { - fixed = true; - do { - tv->tv_sec += 1; - tv->tv_usec -= US_PER_S; - } while (tv->tv_usec >=US_PER_S); + if (clock_gettime(CLOCKSOURCE, &ts) == -1) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, "clock_gettime failed: %s", + strbuf); } - /* - * Call syslog directly as we are called from the logging functions. - */ - if (fixed) - (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); -} -#endif -void -isc_stdtime_get(isc_stdtime_t *t) { - struct timeval tv; + REQUIRE(ts.tv_sec > 0 && ts.tv_nsec >= 0 && ts.tv_nsec < NS_PER_S); - /* - * Set 't' to the number of seconds since 00:00:00 UTC, January 1, - * 1970. - */ + *t = (isc_stdtime_t)ts.tv_sec; +} - REQUIRE(t != NULL); +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen) { + time_t when; - RUNTIME_CHECK(gettimeofday(&tv, NULL) != -1); + REQUIRE(out != NULL); + REQUIRE(outlen >= 26); -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - INSIST(tv.tv_usec >= 0); -#else - INSIST(tv.tv_usec >= 0 && tv.tv_usec < US_PER_S); -#endif + UNUSED(outlen); - *t = (unsigned int)tv.tv_sec; + /* time_t and isc_stdtime_t might be different sizes */ + when = t; + INSIST((ctime_r(&when, out) != NULL)); + *(out + strlen(out) - 1) = '\0'; } diff --git a/lib/isc/unix/syslog.c b/lib/isc/unix/syslog.c index 4ce32725..af386b18 100644 --- a/lib/isc/unix/syslog.c +++ b/lib/isc/unix/syslog.c @@ -3,17 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <stdlib.h> #include <syslog.h> @@ -25,39 +22,37 @@ static struct dsn_c_pvt_sfnt { int val; const char *strval; -} facilities[] = { - { LOG_KERN, "kern" }, - { LOG_USER, "user" }, - { LOG_MAIL, "mail" }, - { LOG_DAEMON, "daemon" }, - { LOG_AUTH, "auth" }, - { LOG_SYSLOG, "syslog" }, - { LOG_LPR, "lpr" }, +} facilities[] = { { LOG_KERN, "kern" }, + { LOG_USER, "user" }, + { LOG_MAIL, "mail" }, + { LOG_DAEMON, "daemon" }, + { LOG_AUTH, "auth" }, + { LOG_SYSLOG, "syslog" }, + { LOG_LPR, "lpr" }, #ifdef LOG_NEWS - { LOG_NEWS, "news" }, -#endif + { LOG_NEWS, "news" }, +#endif /* ifdef LOG_NEWS */ #ifdef LOG_UUCP - { LOG_UUCP, "uucp" }, -#endif + { LOG_UUCP, "uucp" }, +#endif /* ifdef LOG_UUCP */ #ifdef LOG_CRON - { LOG_CRON, "cron" }, -#endif + { LOG_CRON, "cron" }, +#endif /* ifdef LOG_CRON */ #ifdef LOG_AUTHPRIV - { LOG_AUTHPRIV, "authpriv" }, -#endif + { LOG_AUTHPRIV, "authpriv" }, +#endif /* ifdef LOG_AUTHPRIV */ #ifdef LOG_FTP - { LOG_FTP, "ftp" }, -#endif - { LOG_LOCAL0, "local0"}, - { LOG_LOCAL1, "local1"}, - { LOG_LOCAL2, "local2"}, - { LOG_LOCAL3, "local3"}, - { LOG_LOCAL4, "local4"}, - { LOG_LOCAL5, "local5"}, - { LOG_LOCAL6, "local6"}, - { LOG_LOCAL7, "local7"}, - { 0, NULL } -}; + { LOG_FTP, "ftp" }, +#endif /* ifdef LOG_FTP */ + { LOG_LOCAL0, "local0" }, + { LOG_LOCAL1, "local1" }, + { LOG_LOCAL2, "local2" }, + { LOG_LOCAL3, "local3" }, + { LOG_LOCAL4, "local4" }, + { LOG_LOCAL5, "local5" }, + { LOG_LOCAL6, "local6" }, + { LOG_LOCAL7, "local7" }, + { 0, NULL } }; isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp) { @@ -73,5 +68,4 @@ isc_syslog_facilityfromstring(const char *str, int *facilityp) { } } return (ISC_R_NOTFOUND); - } diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index 605b0293..b7e900aa 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -3,27 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> - #include <errno.h> -#include <limits.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <stdlib.h> +#include <sys/time.h> /* Required for struct timeval on some platforms. */ #include <syslog.h> #include <time.h> -#include <sys/time.h> /* Required for struct timeval on some platforms. */ - #include <isc/log.h> #include <isc/platform.h> #include <isc/print.h> @@ -33,59 +29,28 @@ #include <isc/tm.h> #include <isc/util.h> -#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ -#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */ -#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */ -#define US_PER_S 1000000 /*%< Microseconds per second. */ +#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ +#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */ +#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */ -/* - * All of the INSIST()s checks of nanoseconds < NS_PER_S are for - * consistency checking of the type. In lieu of magic numbers, it - * is the best we've got. The check is only performed on functions which - * need an initialized type. - */ - -#ifndef ISC_FIX_TV_USEC -#define ISC_FIX_TV_USEC 1 -#endif +#if defined(CLOCK_REALTIME_COARSE) +#define CLOCKSOURCE CLOCK_REALTIME_COARSE +#elif defined(CLOCK_REALTIME_FAST) +#define CLOCKSOURCE CLOCK_REALTIME_FAST +#else /* if defined(CLOCK_REALTIME_COARSE) */ +#define CLOCKSOURCE CLOCK_REALTIME +#endif /* if defined(CLOCK_REALTIME_COARSE) */ /*% *** Intervals ***/ static const isc_interval_t zero_interval = { 0, 0 }; -const isc_interval_t * const isc_interval_zero = &zero_interval; - -#if ISC_FIX_TV_USEC -static inline void -fix_tv_usec(struct timeval *tv) { - bool fixed = false; - - if (tv->tv_usec < 0) { - fixed = true; - do { - tv->tv_sec -= 1; - tv->tv_usec += US_PER_S; - } while (tv->tv_usec < 0); - } else if (tv->tv_usec >= US_PER_S) { - fixed = true; - do { - tv->tv_sec += 1; - tv->tv_usec -= US_PER_S; - } while (tv->tv_usec >=US_PER_S); - } - /* - * Call syslog directly as was are called from the logging functions. - */ - if (fixed) - (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); -} -#endif +const isc_interval_t *const isc_interval_zero = &zero_interval; void -isc_interval_set(isc_interval_t *i, - unsigned int seconds, unsigned int nanoseconds) -{ +isc_interval_set(isc_interval_t *i, unsigned int seconds, + unsigned int nanoseconds) { REQUIRE(i != NULL); REQUIRE(nanoseconds < NS_PER_S); @@ -98,19 +63,19 @@ isc_interval_iszero(const isc_interval_t *i) { REQUIRE(i != NULL); INSIST(i->nanoseconds < NS_PER_S); - if (i->seconds == 0 && i->nanoseconds == 0) + if (i->seconds == 0 && i->nanoseconds == 0) { return (true); + } return (false); } - /*** *** Absolute Times ***/ static const isc_time_t epoch = { 0, 0 }; -const isc_time_t * const isc_time_epoch = &epoch; +const isc_time_t *const isc_time_epoch = &epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { @@ -134,85 +99,63 @@ isc_time_isepoch(const isc_time_t *t) { REQUIRE(t != NULL); INSIST(t->nanoseconds < NS_PER_S); - if (t->seconds == 0 && t->nanoseconds == 0) + if (t->seconds == 0 && t->nanoseconds == 0) { return (true); + } return (false); } - isc_result_t isc_time_now(isc_time_t *t) { - struct timeval tv; + struct timespec ts; char strbuf[ISC_STRERRORSIZE]; REQUIRE(t != NULL); - if (gettimeofday(&tv, NULL) == -1) { + if (clock_gettime(CLOCKSOURCE, &ts) == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); return (ISC_R_UNEXPECTED); } - /* - * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, - * then this test will generate warnings for platforms on which it is - * unsigned. In any event, the chances of any of these problems - * happening are pretty much zero, but since the libisc library ensures - * certain things to be true ... - */ -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - if (tv.tv_sec < 0) - return (ISC_R_UNEXPECTED); -#else - if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) + if (ts.tv_sec < 0 || ts.tv_nsec < 0 || ts.tv_nsec >= NS_PER_S) { return (ISC_R_UNEXPECTED); -#endif + } /* * Ensure the tv_sec value fits in t->seconds. */ - if (sizeof(tv.tv_sec) > sizeof(t->seconds) && - ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U) + if (sizeof(ts.tv_sec) > sizeof(t->seconds) && + ((ts.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U) + { return (ISC_R_RANGE); + } - t->seconds = tv.tv_sec; - t->nanoseconds = tv.tv_usec * NS_PER_US; + t->seconds = ts.tv_sec; + t->nanoseconds = ts.tv_nsec; return (ISC_R_SUCCESS); } isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { - struct timeval tv; + struct timespec ts; char strbuf[ISC_STRERRORSIZE]; REQUIRE(t != NULL); REQUIRE(i != NULL); INSIST(i->nanoseconds < NS_PER_S); - if (gettimeofday(&tv, NULL) == -1) { + if (clock_gettime(CLOCKSOURCE, &ts) == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); return (ISC_R_UNEXPECTED); } - /* - * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, - * then this test will generate warnings for platforms on which it is - * unsigned. In any event, the chances of any of these problems - * happening are pretty much zero, but since the libisc library ensures - * certain things to be true ... - */ -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - if (tv.tv_sec < 0) - return (ISC_R_UNEXPECTED); -#else - if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) + if (ts.tv_sec < 0 || ts.tv_nsec < 0 || ts.tv_nsec >= NS_PER_S) { return (ISC_R_UNEXPECTED); -#endif + } /* * Ensure the resulting seconds value fits in the size of an @@ -220,12 +163,14 @@ isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { * note that even if both values == INT_MAX, then when added * and getting another 1 added below the result is UINT_MAX.) */ - if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) && - ((long long)tv.tv_sec + i->seconds > UINT_MAX)) + if ((ts.tv_sec > INT_MAX || i->seconds > INT_MAX) && + ((long long)ts.tv_sec + i->seconds > UINT_MAX)) + { return (ISC_R_RANGE); + } - t->seconds = tv.tv_sec + i->seconds; - t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds; + t->seconds = ts.tv_sec + i->seconds; + t->nanoseconds = ts.tv_nsec + i->nanoseconds; if (t->nanoseconds >= NS_PER_S) { t->seconds++; t->nanoseconds -= NS_PER_S; @@ -239,20 +184,23 @@ isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) { REQUIRE(t1 != NULL && t2 != NULL); INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S); - if (t1->seconds < t2->seconds) + if (t1->seconds < t2->seconds) { return (-1); - if (t1->seconds > t2->seconds) + } + if (t1->seconds > t2->seconds) { return (1); - if (t1->nanoseconds < t2->nanoseconds) + } + if (t1->nanoseconds < t2->nanoseconds) { return (-1); - if (t1->nanoseconds > t2->nanoseconds) + } + if (t1->nanoseconds > t2->nanoseconds) { return (1); + } return (0); } isc_result_t -isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) -{ +isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { REQUIRE(t != NULL && i != NULL && result != NULL); INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); @@ -264,7 +212,9 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) */ if ((t->seconds > INT_MAX || i->seconds > INT_MAX) && ((long long)t->seconds + i->seconds > UINT_MAX)) + { return (ISC_R_RANGE); + } result->seconds = t->seconds + i->seconds; result->nanoseconds = t->nanoseconds + i->nanoseconds; @@ -278,22 +228,23 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) isc_result_t isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, - isc_time_t *result) -{ + isc_time_t *result) { REQUIRE(t != NULL && i != NULL && result != NULL); INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); if ((unsigned int)t->seconds < i->seconds || ((unsigned int)t->seconds == i->seconds && t->nanoseconds < i->nanoseconds)) - return (ISC_R_RANGE); + { + return (ISC_R_RANGE); + } result->seconds = t->seconds - i->seconds; - if (t->nanoseconds >= i->nanoseconds) + if (t->nanoseconds >= i->nanoseconds) { result->nanoseconds = t->nanoseconds - i->nanoseconds; - else { + } else { result->nanoseconds = NS_PER_S - i->nanoseconds + - t->nanoseconds; + t->nanoseconds; result->seconds--; } @@ -310,8 +261,9 @@ isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) { i1 = (uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds; i2 = (uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds; - if (i1 <= i2) + if (i1 <= i2) { return (0); + } i3 = i1 - i2; @@ -360,8 +312,9 @@ isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) { INSIST(sizeof(unsigned int) == sizeof(uint32_t)); INSIST(sizeof(time_t) >= sizeof(uint32_t)); - if (t->seconds > (~0U>>1) && seconds <= (time_t)(~0U>>1)) + if (t->seconds > (~0U >> 1) && seconds <= (time_t)(~0U >> 1)) { return (ISC_R_RANGE); + } *secondsp = seconds; @@ -388,13 +341,13 @@ isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { REQUIRE(buf != NULL); REQUIRE(len > 0); - now = (time_t) t->seconds; + now = (time_t)t->seconds; flen = strftime(buf, len, "%d-%b-%Y %X", localtime_r(&now, &tm)); INSIST(flen < len); - if (flen != 0) - snprintf(buf + flen, len - flen, - ".%03u", t->nanoseconds / NS_PER_MS); - else { + if (flen != 0) { + snprintf(buf + flen, len - flen, ".%03u", + t->nanoseconds / NS_PER_MS); + } else { strlcpy(buf, "99-Bad-9999 99:99:99.999", len); } } @@ -429,11 +382,13 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { REQUIRE(t != NULL); p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm); - if (p == NULL) + if (p == NULL) { return (ISC_R_UNEXPECTED); + } when = isc_tm_timegm(&t_tm); - if (when == -1) + if (when == -1) { return (ISC_R_UNEXPECTED); + } isc_time_set(t, when, 0); return (ISC_R_SUCCESS); } @@ -475,6 +430,26 @@ isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len) { } void +isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len) { + time_t now; + unsigned int flen; + struct tm tm; + + REQUIRE(t != NULL); + INSIST(t->nanoseconds < NS_PER_S); + REQUIRE(buf != NULL); + REQUIRE(len > 0); + + now = (time_t)t->seconds; + flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime_r(&now, &tm)); + INSIST(flen < len); + if (flen > 0U && len - flen >= 6) { + snprintf(buf + flen, len - flen, ".%06u", + t->nanoseconds / NS_PER_US); + } +} + +void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { time_t now; unsigned int flen; @@ -512,8 +487,29 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) { } void -isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len) -{ +isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len) { + time_t now; + unsigned int flen; + struct tm tm; + + REQUIRE(t != NULL); + INSIST(t->nanoseconds < NS_PER_S); + REQUIRE(buf != NULL); + REQUIRE(len > 0); + + now = (time_t)t->seconds; + flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime_r(&now, &tm)); + INSIST(flen < len); + if (flen > 0U && len - flen >= 5) { + flen -= 1; /* rewind one character (Z) */ + snprintf(buf + flen, len - flen, ".%06uZ", + t->nanoseconds / NS_PER_US); + } +} + +void +isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, + unsigned int len) { time_t now; unsigned int flen; struct tm tm; diff --git a/lib/isc/utf8.c b/lib/isc/utf8.c new file mode 100644 index 00000000..8803bb85 --- /dev/null +++ b/lib/isc/utf8.c @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#include <string.h> + +#include <isc/utf8.h> +#include <isc/util.h> + +/* + * UTF-8 is defined in "The Unicode Standard -- Version 4.0" + * Also see RFC 3629. + * + * Char. number range | UTF-8 octet sequence + * (hexadecimal) | (binary) + * --------------------+--------------------------------------------- + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + */ +bool +isc_utf8_valid(const unsigned char *buf, size_t len) { + REQUIRE(buf != NULL); + + for (size_t i = 0; i < len; i++) { + if (buf[i] <= 0x7f) { + continue; + } + if ((i + 1) < len && (buf[i] & 0xe0) == 0xc0 && + (buf[i + 1] & 0xc0) == 0x80) { + unsigned int w; + w = (buf[i] & 0x1f) << 6; + w |= (buf[++i] & 0x3f); + if (w < 0x80) { + return (false); + } + continue; + } + if ((i + 2) < len && (buf[i] & 0xf0) == 0xe0 && + (buf[i + 1] & 0xc0) == 0x80 && (buf[i + 2] & 0xc0) == 0x80) + { + unsigned int w; + w = (buf[i] & 0x0f) << 12; + w |= (buf[++i] & 0x3f) << 6; + w |= (buf[++i] & 0x3f); + if (w < 0x0800) { + return (false); + } + continue; + } + if ((i + 3) < len && (buf[i] & 0xf8) == 0xf0 && + (buf[i + 1] & 0xc0) == 0x80 && + (buf[i + 2] & 0xc0) == 0x80 && (buf[i + 3] & 0xc0) == 0x80) + { + unsigned int w; + w = (buf[i] & 0x07) << 18; + w |= (buf[++i] & 0x3f) << 12; + w |= (buf[++i] & 0x3f) << 6; + w |= (buf[++i] & 0x3f); + if (w < 0x10000 || w > 0x10FFFF) { + return (false); + } + continue; + } + return (false); + } + return (true); +} + +bool +isc_utf8_bom(const unsigned char *buf, size_t len) { + REQUIRE(buf != NULL); + + if (len >= 3U && !memcmp(buf, "\xef\xbb\xbf", 3)) { + return (true); + } + return (false); +} diff --git a/lib/isc/version.c b/lib/isc/version.c index 8efdbe68..717a6ddc 100644 --- a/lib/isc/version.c +++ b/lib/isc/version.c @@ -3,15 +3,13 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ -#include <config.h> #include <isc/version.h> diff --git a/lib/isc/win32/DLLMain.c b/lib/isc/win32/DLLMain.c index 5361c966..91f14e7b 100644 --- a/lib/isc/win32/DLLMain.c +++ b/lib/isc/win32/DLLMain.c @@ -3,25 +3,21 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - -#include <windows.h> #include <stdio.h> +#include <windows.h> /* * Called when we enter the DLL */ -__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { +__declspec(dllexport) BOOL WINAPI + DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. @@ -49,4 +45,3 @@ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, } return (TRUE); } - diff --git a/lib/isc/win32/app.c b/lib/isc/win32/app.c deleted file mode 100644 index 7ab08007..00000000 --- a/lib/isc/win32/app.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * 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 http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include <config.h> - -#include <sys/types.h> - -#include <stdbool.h> -#include <stddef.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <process.h> - -#include <isc/app.h> -#include <isc/condition.h> -#include <isc/mem.h> -#include <isc/mutex.h> -#include <isc/event.h> -#include <isc/platform.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/time.h> -#include <isc/util.h> -#include <isc/thread.h> - -/*% - * For BIND9 internal applications built with threads, we use a single app - * context and let multiple worker, I/O, timer threads do actual jobs. - */ - -static isc_thread_t blockedthread; -static bool is_running; - -#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') -#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) - -/* Events to wait for */ - -#define NUM_EVENTS 2 - -enum { - RELOAD_EVENT, - SHUTDOWN_EVENT -}; - -typedef struct isc__appctx { - isc_appctx_t common; - isc_mem_t *mctx; - isc_eventlist_t on_run; - isc_mutex_t lock; - bool shutdown_requested; - bool running; - /* - * We assume that 'want_shutdown' can be read and written atomically. - */ - bool want_shutdown; - /* - * We assume that 'want_reload' can be read and written atomically. - */ - bool want_reload; - - bool blocked; - - HANDLE hEvents[NUM_EVENTS]; - - isc_taskmgr_t *taskmgr; - isc_socketmgr_t *socketmgr; - isc_timermgr_t *timermgr; -} isc__appctx_t; - -static isc__appctx_t isc_g_appctx; - -/* - * We need to remember which thread is the main thread... - */ -static isc_thread_t main_thread; - -isc_result_t -isc_app_ctxstart(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - isc_result_t result; - - REQUIRE(VALID_APPCTX(ctx)); - - /* - * Start an ISC library application. - */ - - main_thread = GetCurrentThread(); - - isc_mutex_init(&ctx->lock); - - ctx->shutdown_requested = false; - ctx->running = false; - ctx->want_shutdown = false; - ctx->want_reload = false; - ctx->blocked = false; - - /* Create the reload event in a non-signaled state */ - ctx->hEvents[RELOAD_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); - - /* Create the shutdown event in a non-signaled state */ - ctx->hEvents[SHUTDOWN_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); - - ISC_LIST_INIT(ctx->on_run); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_start(void) { - isc_g_appctx.common.impmagic = APPCTX_MAGIC; - isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC; - isc_g_appctx.mctx = NULL; - /* The remaining members will be initialized in ctxstart() */ - - return (isc_app_ctxstart((isc_appctx_t *)&isc_g_appctx)); -} - -isc_result_t -isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, - void *arg) -{ - return (isc_app_ctxonrun((isc_appctx_t *)&isc_g_appctx, mctx, - task, action, arg)); -} - -isc_result_t -isc_app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task, - isc_taskaction_t action, void *arg) -{ - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - isc_event_t *event; - isc_task_t *cloned_task = NULL; - isc_result_t result; - - LOCK(&ctx->lock); - - if (ctx->running) { - result = ISC_R_ALREADYRUNNING; - goto unlock; - } - - /* - * Note that we store the task to which we're going to send the event - * in the event's "sender" field. - */ - isc_task_attach(task, &cloned_task); - event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, - action, arg, sizeof(*event)); - if (event == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - - ISC_LINK_INIT(event, ev_link); - ISC_LIST_APPEND(ctx->on_run, event, ev_link); - - result = ISC_R_SUCCESS; - - unlock: - UNLOCK(&ctx->lock); - - return (result); -} - -isc_result_t -isc_app_ctxrun(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - isc_event_t *event, *next_event; - isc_task_t *task; - HANDLE *pHandles = NULL; - DWORD dwWaitResult; - - REQUIRE(VALID_APPCTX(ctx)); - - REQUIRE(main_thread == GetCurrentThread()); - - LOCK(&ctx->lock); - - if (!ctx->running) { - ctx->running = true; - - /* - * Post any on-run events (in FIFO order). - */ - for (event = ISC_LIST_HEAD(ctx->on_run); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(ctx->on_run, event, ev_link); - task = event->ev_sender; - event->ev_sender = NULL; - isc_task_sendanddetach(&task, &event); - } - - } - - UNLOCK(&ctx->lock); - - /* - * There is no danger if isc_app_shutdown() is called before we wait - * for events. - */ - - while (!ctx->want_shutdown) { - dwWaitResult = WaitForMultipleObjects(NUM_EVENTS, ctx->hEvents, - FALSE, INFINITE); - - /* See why we returned */ - - if (WaitSucceeded(dwWaitResult, NUM_EVENTS)) { - /* - * The return was due to one of the events - * being signaled - */ - switch (WaitSucceededIndex(dwWaitResult)) { - case RELOAD_EVENT: - ctx->want_reload = true; - break; - - case SHUTDOWN_EVENT: - ctx->want_shutdown = true; - break; - } - } - - if (ctx->want_reload) { - ctx->want_reload = false; - return (ISC_R_RELOAD); - } - - if (ctx->want_shutdown && ctx->blocked) - exit(-1); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_run(void) { - isc_result_t result; - - is_running = true; - result = isc_app_ctxrun((isc_appctx_t *)&isc_g_appctx); - is_running = false; - - return (result); -} - -bool -isc_app_isrunning() { - return (is_running); -} - -isc_result_t -isc_app_ctxshutdown(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - bool want_kill = true; - - REQUIRE(VALID_APPCTX(ctx)); - - LOCK(&ctx->lock); - - REQUIRE(ctx->running); - - if (ctx->shutdown_requested) - want_kill = false; /* We're only signaling once */ - else - ctx->shutdown_requested = true; - - UNLOCK(&ctx->lock); - - if (want_kill) - SetEvent(ctx->hEvents[SHUTDOWN_EVENT]); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_shutdown(void) { - return (isc_app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); -} - -isc_result_t -isc_app_ctxsuspend(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - bool want_kill = true; - - REQUIRE(VALID_APPCTX(ctx)); - - LOCK(&ctx->lock); - - REQUIRE(ctx->running); - - /* - * Don't send the reload signal if we're shutting down. - */ - if (ctx->shutdown_requested) - want_kill = false; - - UNLOCK(&ctx->lock); - - if (want_kill) - SetEvent(ctx->hEvents[RELOAD_EVENT]); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_reload(void) { - return (isc_app_ctxsuspend((isc_appctx_t *)&isc_g_appctx)); -} - -void -isc_app_ctxfinish(isc_appctx_t *ctx0) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - isc_mutex_destroy(&ctx->lock); -} - -void -isc_app_finish(void) { - isc_app_ctxfinish((isc_appctx_t *)&isc_g_appctx); -} - -void -isc_app_block(void) { - REQUIRE(isc_g_appctx.running); - REQUIRE(!isc_g_appctx.blocked); - - isc_g_appctx.blocked = true; - blockedthread = GetCurrentThread(); -} - -void -isc_app_unblock(void) { - REQUIRE(isc_g_appctx.running); - REQUIRE(isc_g_appctx.blocked); - - isc_g_appctx.blocked = false; - REQUIRE(blockedthread == GetCurrentThread()); -} - -isc_result_t -isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { - isc__appctx_t *ctx; - - REQUIRE(mctx != NULL); - REQUIRE(ctxp != NULL && *ctxp == NULL); - - ctx = isc_mem_get(mctx, sizeof(*ctx)); - if (ctx == NULL) - return (ISC_R_NOMEMORY); - - ctx->common.impmagic = APPCTX_MAGIC; - ctx->common.magic = ISCAPI_APPCTX_MAGIC; - - ctx->mctx = NULL; - isc_mem_attach(mctx, &ctx->mctx); - - ctx->taskmgr = NULL; - ctx->socketmgr = NULL; - ctx->timermgr = NULL; - - *ctxp = (isc_appctx_t *)ctx; - - return (ISC_R_SUCCESS); -} - -void -isc_appctx_destroy(isc_appctx_t **ctxp) { - isc__appctx_t *ctx; - - REQUIRE(ctxp != NULL); - ctx = (isc__appctx_t *)*ctxp; - REQUIRE(VALID_APPCTX(ctx)); - - isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); - - *ctxp = NULL; -} - -void -isc_appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->taskmgr = taskmgr; -} - -void -isc_appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->socketmgr = socketmgr; -} - -void -isc_appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) { - isc__appctx_t *ctx = (isc__appctx_t *)ctx0; - - REQUIRE(VALID_APPCTX(ctx)); - - ctx->timermgr = timermgr; -} diff --git a/lib/isc/win32/condition.c b/lib/isc/win32/condition.c index e39ba937..e0945d4d 100644 --- a/lib/isc/win32/condition.c +++ b/lib/isc/win32/condition.c @@ -3,27 +3,25 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <inttypes.h> #include <stdbool.h> -#include <isc/condition.h> #include <isc/assertions.h> +#include <isc/condition.h> #include <isc/error.h> -#include <isc/util.h> #include <isc/strerr.h> #include <isc/thread.h> #include <isc/time.h> +#include <isc/util.h> -#define LSIGNAL 0 -#define LBROADCAST 1 +#define LSIGNAL 0 +#define LBROADCAST 1 void isc_condition_init(isc_condition_t *cond) { @@ -40,8 +38,8 @@ isc_condition_init(isc_condition_t *cond) { char strbuf[ISC_STRERRORSIZE]; DWORD err = GetLastError(); strerror_r(err, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "CreateEvent failed: %s", strbuf); + isc_error_fatal(__FILE__, __LINE__, "CreateEvent failed: %s", + strbuf); } cond->events[LSIGNAL] = h; @@ -57,16 +55,16 @@ isc_condition_init(isc_condition_t *cond) { */ static isc_result_t register_thread(unsigned long thrd, isc_condition_t *gblcond, - isc_condition_thread_t **localcond) -{ + isc_condition_thread_t **localcond) { HANDLE hc; isc_condition_thread_t *newthread; REQUIRE(localcond != NULL && *localcond == NULL); newthread = malloc(sizeof(isc_condition_thread_t)); - if (newthread == NULL) + if (newthread == NULL) { return (ISC_R_NOMEMORY); + } /* * Create the thread-specific handle @@ -95,8 +93,7 @@ register_thread(unsigned long thrd, isc_condition_t *gblcond, static isc_result_t find_thread_condition(unsigned long thrd, isc_condition_t *cond, - isc_condition_thread_t **threadcondp) -{ + isc_condition_thread_t **threadcondp) { isc_condition_thread_t *threadcond; REQUIRE(threadcondp != NULL && *threadcondp == NULL); @@ -104,10 +101,9 @@ find_thread_condition(unsigned long thrd, isc_condition_t *cond, /* * Look for the thread ID. */ - for (threadcond = ISC_LIST_HEAD(cond->threadlist); - threadcond != NULL; - threadcond = ISC_LIST_NEXT(threadcond, link)) { - + for (threadcond = ISC_LIST_HEAD(cond->threadlist); threadcond != NULL; + threadcond = ISC_LIST_NEXT(threadcond, link)) + { if (threadcond->th == thrd) { *threadcondp = threadcond; return (ISC_R_SUCCESS); @@ -122,7 +118,6 @@ find_thread_condition(unsigned long thrd, isc_condition_t *cond, isc_result_t isc_condition_signal(isc_condition_t *cond) { - /* * Unlike pthreads, the caller MUST hold the lock associated with * the condition variable when calling us. @@ -138,7 +133,6 @@ isc_condition_signal(isc_condition_t *cond) { isc_result_t isc_condition_broadcast(isc_condition_t *cond) { - isc_condition_thread_t *threadcond; bool failed = false; @@ -151,23 +145,23 @@ isc_condition_broadcast(isc_condition_t *cond) { /* * Notify every thread registered for this */ - for (threadcond = ISC_LIST_HEAD(cond->threadlist); - threadcond != NULL; - threadcond = ISC_LIST_NEXT(threadcond, link)) { - - if (!SetEvent(threadcond->handle[LBROADCAST])) + for (threadcond = ISC_LIST_HEAD(cond->threadlist); threadcond != NULL; + threadcond = ISC_LIST_NEXT(threadcond, link)) + { + if (!SetEvent(threadcond->handle[LBROADCAST])) { failed = true; + } } - if (failed) + if (failed) { return (ISC_R_UNEXPECTED); + } return (ISC_R_SUCCESS); } isc_result_t isc_condition_destroy(isc_condition_t *cond) { - isc_condition_thread_t *next, *threadcond; REQUIRE(cond != NULL); @@ -183,7 +177,7 @@ isc_condition_destroy(isc_condition_t *cond) { while (threadcond != NULL) { next = ISC_LIST_NEXT(threadcond, link); DEQUEUE(cond->threadlist, threadcond, link); - (void) CloseHandle(threadcond->handle[LBROADCAST]); + (void)CloseHandle(threadcond->handle[LBROADCAST]); free(threadcond); threadcond = next; } @@ -210,8 +204,9 @@ wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) { * Get the thread events needed for the wait */ tresult = find_thread_condition(isc_thread_self(), cond, &threadcond); - if (tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) { return (tresult); + } cond->waiters++; LeaveCriticalSection(mutex); @@ -223,8 +218,9 @@ wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) { /* XXX */ return (ISC_R_UNEXPECTED); } - if (result == WAIT_TIMEOUT) + if (result == WAIT_TIMEOUT) { return (ISC_R_TIMEDOUT); + } return (ISC_R_SUCCESS); } @@ -247,10 +243,11 @@ isc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex, } microseconds = isc_time_microdiff(t, &now); - if (microseconds > 0xFFFFFFFFi64 * 1000) + if (microseconds > 0xFFFFFFFFi64 * 1000) { milliseconds = 0xFFFFFFFF; - else + } else { milliseconds = (DWORD)(microseconds / 1000); + } return (wait(cond, mutex, milliseconds)); } diff --git a/lib/isc/win32/dir.c b/lib/isc/win32/dir.c index 5db2c235..006f60a9 100644 --- a/lib/isc/win32/dir.c +++ b/lib/isc/win32/dir.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - -#include <string.h> #include <direct.h> -#include <process.h> #include <io.h> - +#include <process.h> +#include <string.h> #include <sys/stat.h> #include <isc/assertions.h> @@ -27,8 +24,8 @@ #include "errno2result.h" -#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') -#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) +#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') +#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) static isc_result_t start_directory(isc_dir_t *p); @@ -65,17 +62,19 @@ isc_dir_open(isc_dir_t *dir, const char *dirname) { * Copy directory name. Need to have enough space for the name, * a possible path separator, the wildcard, and the final NUL. */ - if (strlen(dirname) + 3 > sizeof(dir->dirname)) + if (strlen(dirname) + 3 > sizeof(dir->dirname)) { /* XXXDCL ? */ return (ISC_R_NOSPACE); + } strlcpy(dir->dirname, dirname, sizeof(dir->dirname)); /* * Append path separator, if needed, and "*". */ p = dir->dirname + strlen(dir->dirname); - if (dir->dirname < p && *(p - 1) != '\\' && *(p - 1) != ':') + if (dir->dirname < p && *(p - 1) != '\\' && *(p - 1) != ':') { *p++ = '\\'; + } *p++ = '*'; *p = '\0'; @@ -96,27 +95,28 @@ isc_result_t isc_dir_read(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); - if (dir->entry_filled) + if (dir->entry_filled) { /* * start_directory() already filled in the first entry. */ dir->entry_filled = false; - - else { + } else { /* * Fetch next file in directory. */ - if (FindNextFile(dir->search_handle, - &dir->entry.find_data) == FALSE) + if (FindNextFile(dir->search_handle, &dir->entry.find_data) == + FALSE) { /* * Either the last file has been processed or * an error has occurred. The former is not * really an error, but the latter is. */ - if (GetLastError() == ERROR_NO_MORE_FILES) + if (GetLastError() == ERROR_NO_MORE_FILES) { return (ISC_R_NOMORE); - else + } else { return (ISC_R_UNEXPECTED); + } + } } /* @@ -134,10 +134,10 @@ isc_dir_read(isc_dir_t *dir) { */ void isc_dir_close(isc_dir_t *dir) { - REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); + REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); - FindClose(dir->search_handle); - dir->search_handle = INVALID_HANDLE_VALUE; + FindClose(dir->search_handle); + dir->search_handle = INVALID_HANDLE_VALUE; } /* @@ -171,8 +171,7 @@ isc_dir_reset(isc_dir_t *dir) { * - Be sure to close previous stream before opening new one */ static isc_result_t -start_directory(isc_dir_t *dir) -{ +start_directory(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir)); REQUIRE(dir->search_handle == INVALID_HANDLE_VALUE); @@ -181,8 +180,7 @@ start_directory(isc_dir_t *dir) /* * Open stream and retrieve first file. */ - dir->search_handle = FindFirstFile(dir->dirname, - &dir->entry.find_data); + dir->search_handle = FindFirstFile(dir->dirname, &dir->entry.find_data); if (dir->search_handle == INVALID_HANDLE_VALUE) { /* @@ -223,8 +221,9 @@ isc_dir_chdir(const char *dirname) { REQUIRE(dirname != NULL); - if (chdir(dirname) < 0) + if (chdir(dirname) < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); } @@ -257,26 +256,28 @@ isc_dir_createunique(char *templet) { x--, pid /= 10) *x = pid % 10 + '0'; - x++; /* Set x to start of ex-Xs. */ + x++; /* Set x to start of ex-Xs. */ do { i = mkdir(templet); - if (i == 0) + if (i == 0) { i = chmod(templet, 0700); + } - if (i == 0 || errno != EEXIST) + if (i == 0 || errno != EEXIST) { break; + } /* * The BSD algorithm. */ p = x; while (*p != '\0') { - if (isdigit(*p & 0xff)) + if (isdigit(*p & 0xff)) { *p = 'a'; - else if (*p != 'z') + } else if (*p != 'z') { ++*p; - else { + } else { /* * Reset character and move to next. */ @@ -298,10 +299,11 @@ isc_dir_createunique(char *templet) { } } while (1); - if (i == -1) + if (i == -1) { result = isc__errno2result(errno); - else + } else { result = ISC_R_SUCCESS; + } return (result); } diff --git a/lib/isc/win32/errno.c b/lib/isc/win32/errno.c index 74ebf0c5..7940c14d 100644 --- a/lib/isc/win32/errno.c +++ b/lib/isc/win32/errno.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -11,8 +11,6 @@ /*! \file */ -#include <config.h> - #include "errno2result.h" isc_result_t diff --git a/lib/isc/win32/errno2result.c b/lib/isc/win32/errno2result.c index 59af4cae..6ad0b82c 100644 --- a/lib/isc/win32/errno2result.c +++ b/lib/isc/win32/errno2result.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - +#include "errno2result.h" #include <stdbool.h> #include <winsock2.h> -#include "errno2result.h" #include <isc/result.h> #include <isc/strerr.h> #include <isc/string.h> @@ -28,16 +25,14 @@ * not already there. */ isc_result_t -isc__errno2resultx(int posixerrno, bool dolog, - const char *file, int line) -{ +isc__errno2resultx(int posixerrno, bool dolog, const char *file, int line) { char strbuf[ISC_STRERRORSIZE]; switch (posixerrno) { case ENOTDIR: case WSAELOOP: case WSAEINVAL: - case EINVAL: /* XXX sometimes this is not for files */ + case EINVAL: /* XXX sometimes this is not for files */ case ENAMETOOLONG: case WSAENAMETOOLONG: case EBADF: @@ -58,7 +53,7 @@ isc__errno2resultx(int posixerrno, bool dolog, #ifdef EOVERFLOW case EOVERFLOW: return (ISC_R_RANGE); -#endif +#endif /* ifdef EOVERFLOW */ case ENFILE: case EMFILE: case WSAEMFILE: diff --git a/lib/isc/win32/errno2result.h b/lib/isc/win32/errno2result.h index 99752ae5..f44597b0 100644 --- a/lib/isc/win32/errno2result.h +++ b/lib/isc/win32/errno2result.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef UNIX_ERRNO2RESULT_H #define UNIX_ERRNO2RESULT_H 1 /* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */ -#include <errno.h> /* Provides errno. */ +#include <errno.h> /* Provides errno. */ #include <stdbool.h> #include <isc/lang.h> @@ -27,8 +26,7 @@ ISC_LANG_BEGINDECLS isc__errno2resultx(posixerrno, true, __FILE__, __LINE__) isc_result_t -isc__errno2resultx(int posixerrno, bool dolog, - const char *file, int line); +isc__errno2resultx(int posixerrno, bool dolog, const char *file, int line); ISC_LANG_ENDDECLS diff --git a/lib/isc/win32/file.c b/lib/isc/win32/file.c index 76662f35..624b24d7 100644 --- a/lib/isc/win32/file.c +++ b/lib/isc/win32/file.c @@ -3,31 +3,28 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #undef rename #include <errno.h> -#include <limits.h> +#include <fcntl.h> #include <inttypes.h> -#include <stdbool.h> -#include <stdlib.h> #include <io.h> +#include <limits.h> #include <process.h> - +#include <stdbool.h> +#include <stdlib.h> #include <sys/stat.h> -#include <fcntl.h> #include <sys/utime.h> #include <isc/file.h> #include <isc/md.h> #include <isc/mem.h> +#include <isc/platform.h> #include <isc/print.h> #include <isc/random.h> #include <isc/result.h> @@ -38,8 +35,8 @@ #include "errno2result.h" -static const char alphnum[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +static const char alphnum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" + "wxyz0123456789"; /* * Emulate UNIX mkstemp, which returns an open FD to the new file @@ -49,10 +46,11 @@ static int gettemp(char *path, bool binary, int *doopen) { char *start, *trv; struct stat sbuf; - int flags = O_CREAT|O_EXCL|O_RDWR; + int flags = O_CREAT | O_EXCL | O_RDWR; - if (binary) + if (binary) { flags |= _O_BINARY; + } trv = strrchr(path, 'X'); trv++; @@ -66,12 +64,14 @@ gettemp(char *path, bool binary, int *doopen) { * doesn't exist this runs for a *very* long time. */ for (start = trv + 1;; --trv) { - if (trv <= path) + if (trv <= path) { break; + } if (*trv == '\\') { *trv = '\0'; - if (stat(path, &sbuf)) + if (stat(path, &sbuf)) { return (0); + } if (!S_ISDIR(sbuf.st_mode)) { errno = ENOTDIR; return (0); @@ -83,25 +83,30 @@ gettemp(char *path, bool binary, int *doopen) { for (;;) { if (doopen) { - if ((*doopen = - open(path, flags, _S_IREAD | _S_IWRITE)) >= 0) + if ((*doopen = open(path, flags, + _S_IREAD | _S_IWRITE)) >= 0) { return (1); - if (errno != EEXIST) + } + if (errno != EEXIST) { return (0); - } else if (stat(path, &sbuf)) + } + } else if (stat(path, &sbuf)) { return (errno == ENOENT ? 1 : 0); + } /* tricky little algorithm for backward compatibility */ for (trv = start;;) { - if (!*trv) + if (!*trv) { return (0); - if (*trv == 'z') + } + if (*trv == 'z') { *trv++ = 'a'; - else { - if (isdigit(*trv)) + } else { + if (isdigit(*trv)) { *trv = 'a'; - else + } else { ++*trv; + } break; } } @@ -131,8 +136,9 @@ file_stats(const char *file, struct stat *stats) { REQUIRE(file != NULL); REQUIRE(stats != NULL); - if (stat(file, stats) != 0) + if (stat(file, stats) != 0) { result = isc__errno2result(errno); + } return (result); } @@ -143,8 +149,9 @@ fd_stats(int fd, struct stat *stats) { REQUIRE(stats != NULL); - if (fstat(fd, stats) != 0) + if (fstat(fd, stats) != 0) { result = isc__errno2result(errno); + } return (result); } @@ -158,8 +165,9 @@ isc_file_getsizefd(int fd, off_t *size) { result = fd_stats(fd, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *size = stats.st_size; + } return (result); } @@ -171,8 +179,9 @@ isc_file_mode(const char *file, mode_t *modep) { REQUIRE(modep != NULL); result = file_stats(file, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *modep = (stats.st_mode & 07777); + } return (result); } @@ -207,8 +216,9 @@ isc_file_safemovefile(const char *oldname, const char *newname) { strlcpy(buf, newname, sizeof(buf)); strlcat(buf, ".XXXXX", sizeof(buf)); tmpfd = mkstemp(buf, true); - if (tmpfd > 0) + if (tmpfd > 0) { _close(tmpfd); + } (void)DeleteFile(buf); _chmod(newname, _S_IREAD | _S_IWRITE); @@ -226,8 +236,9 @@ isc_file_safemovefile(const char *oldname, const char *newname) { */ if (exists == TRUE) { filestatus = MoveFile(buf, newname); - if (filestatus == 0) + if (filestatus == 0) { errno = EACCES; + } } return (-1); } @@ -235,8 +246,9 @@ isc_file_safemovefile(const char *oldname, const char *newname) { /* * Delete the backup file if it got created */ - if (exists == TRUE) + if (exists == TRUE) { (void)DeleteFile(buf); + } return (0); } @@ -247,14 +259,12 @@ isc_file_getmodtime(const char *file, isc_time_t *time) { REQUIRE(file != NULL); REQUIRE(time != NULL); - if ((fh = open(file, _O_RDONLY | _O_BINARY)) < 0) + if ((fh = open(file, _O_RDONLY | _O_BINARY)) < 0) { return (isc__errno2result(errno)); + } - if (!GetFileTime((HANDLE) _get_osfhandle(fh), - NULL, - NULL, - &time->absolute)) - { + if (!GetFileTime((HANDLE)_get_osfhandle(fh), NULL, NULL, + &time->absolute)) { close(fh); errno = EINVAL; return (isc__errno2result(errno)); @@ -273,8 +283,9 @@ isc_file_getsize(const char *file, off_t *size) { result = file_stats(file, &stats); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { *size = stats.st_size; + } return (result); } @@ -285,17 +296,16 @@ isc_file_settime(const char *file, isc_time_t *time) { REQUIRE(file != NULL && time != NULL); - if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0) + if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0) { return (isc__errno2result(errno)); + } /* * Set the date via the filedate system call and return. Failing * this call implies the new file times are not supported by the * underlying file system. */ - if (!SetFileTime((HANDLE) _get_osfhandle(fh), - NULL, - &time->absolute, + if (!SetFileTime((HANDLE)_get_osfhandle(fh), NULL, &time->absolute, &time->absolute)) { close(fh); @@ -305,7 +315,6 @@ isc_file_settime(const char *file, isc_time_t *time) { close(fh); return (ISC_R_SUCCESS); - } #undef TEMPLATE @@ -318,33 +327,36 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen) { isc_result_t isc_file_template(const char *path, const char *templet, char *buf, - size_t buflen) -{ + size_t buflen) { char *s; REQUIRE(templet != NULL); REQUIRE(buf != NULL); - if (path == NULL) + if (path == NULL) { path = ""; + } s = strrchr(templet, '\\'); - if (s != NULL) + if (s != NULL) { templet = s + 1; + } s = strrchr(path, '\\'); if (s != NULL) { size_t prefixlen = s - path + 1; - if ((prefixlen + strlen(templet) + 1) > buflen) + if ((prefixlen + strlen(templet) + 1) > buflen) { return (ISC_R_NOSPACE); + } /* Copy 'prefixlen' bytes and NUL terminate. */ strlcpy(buf, path, ISC_MIN(prefixlen + 1, buflen)); strlcat(buf, templet, buflen); } else { - if ((strlen(templet) + 1) > buflen) + if ((strlen(templet) + 1) > buflen) { return (ISC_R_NOSPACE); + } strlcpy(buf, templet, buflen); } @@ -355,19 +367,20 @@ isc_file_template(const char *path, const char *templet, char *buf, isc_result_t isc_file_renameunique(const char *file, char *templet) { int fd; - int res = 0; isc_result_t result = ISC_R_SUCCESS; REQUIRE(file != NULL); REQUIRE(templet != NULL); fd = mkstemp(templet, true); - if (fd == -1) + if (fd == -1) { result = isc__errno2result(errno); - else + } else { close(fd); + } if (result == ISC_R_SUCCESS) { + int res; res = isc_file_safemovefile(file, templet); if (res != 0) { result = isc__errno2result(errno); @@ -391,21 +404,23 @@ openuniquemode(char *templet, int mode, bool binary, FILE **fp) { */ fd = mkstemp(templet, binary); - if (fd == -1) + if (fd == -1) { result = isc__errno2result(errno); + } if (result == ISC_R_SUCCESS) { #if 1 UNUSED(mode); -#else +#else /* if 1 */ (void)fchmod(fd, mode); -#endif +#endif /* if 1 */ f = fdopen(fd, binary ? "wb+" : "w+"); if (f == NULL) { result = isc__errno2result(errno); (void)remove(templet); (void)close(fd); - } else + } else { *fp = f; + } } return (result); @@ -452,10 +467,11 @@ isc_file_remove(const char *filename) { REQUIRE(filename != NULL); r = unlink(filename); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -466,10 +482,11 @@ isc_file_rename(const char *oldname, const char *newname) { REQUIRE(newname != NULL); r = isc_file_safemovefile(oldname, newname); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } bool @@ -487,15 +504,17 @@ isc_file_isplainfile(const char *filename) { * This function returns success if filename is a plain file. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((stat(filename, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((stat(filename, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISREG(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISREG(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } isc_result_t @@ -504,15 +523,17 @@ isc_file_isplainfilefd(int fd) { * This function returns success if filename is a plain file. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((fstat(fd, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((fstat(fd, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISREG(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISREG(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } isc_result_t @@ -521,18 +542,19 @@ isc_file_isdirectory(const char *filename) { * This function returns success if filename is a directory. */ struct stat filestat; - memset(&filestat,0,sizeof(struct stat)); + memset(&filestat, 0, sizeof(struct stat)); - if ((stat(filename, &filestat)) == -1) - return(isc__errno2result(errno)); + if ((stat(filename, &filestat)) == -1) { + return (isc__errno2result(errno)); + } - if(! S_ISDIR(filestat.st_mode)) - return(ISC_R_INVALIDFILE); + if (!S_ISDIR(filestat.st_mode)) { + return (ISC_R_INVALIDFILE); + } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } - bool isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); @@ -540,12 +562,15 @@ isc_file_isabsolute(const char *filename) { * Look for c:\path\... style, c:/path/... or \\computer\shar\path... * the UNC style file specs */ - if ((filename[0] == '\\') && (filename[1] == '\\')) + if ((filename[0] == '\\') && (filename[1] == '\\')) { return (true); - if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '\\') + } + if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '\\') { return (true); - if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/') + } + if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/') { return (true); + } return (false); } @@ -559,14 +584,18 @@ bool isc_file_ischdiridempotent(const char *filename) { REQUIRE(filename != NULL); - if (isc_file_isabsolute(filename)) + if (isc_file_isabsolute(filename)) { return (true); - if (filename[0] == '\\') + } + if (filename[0] == '\\') { return (true); - if (filename[0] == '/') + } + if (filename[0] == '/') { return (true); - if (isc_file_iscurrentdir(filename)) + } + if (isc_file_iscurrentdir(filename)) { return (true); + } return (false); } @@ -577,8 +606,9 @@ isc_file_basename(const char *filename) { REQUIRE(filename != NULL); s = strrchr(filename, '\\'); - if (s == NULL) + if (s == NULL) { return (filename); + } return (s + 1); } @@ -604,8 +634,9 @@ isc_file_progname(const char *filename, char *progname, size_t namelen) { */ p = strchr(s, '.'); if (p == NULL) { - if (namelen <= strlen(s)) + if (namelen <= strlen(s)) { return (ISC_R_NOSPACE); + } strlcpy(progname, s, namelen); return (ISC_R_SUCCESS); @@ -615,8 +646,9 @@ isc_file_progname(const char *filename, char *progname, size_t namelen) { * Copy the result to the buffer */ len = p - s; - if (len >= namelen) + if (len >= namelen) { return (ISC_R_NOSPACE); + } /* Copy up to 'len' bytes and NUL terminate. */ strlcpy(progname, s, ISC_MIN(len + 1, namelen)); @@ -631,14 +663,16 @@ isc_file_absolutepath(const char *filename, char *path, size_t pathlen) { REQUIRE(filename != NULL); REQUIRE(path != NULL); - retval = GetFullPathName(filename, (DWORD) pathlen, path, &ptrname); + retval = GetFullPathName(filename, (DWORD)pathlen, path, &ptrname); /* Something went wrong in getting the path */ - if (retval == 0) + if (retval == 0) { return (ISC_R_NOTFOUND); + } /* Caller needs to provide a larger buffer to contain the string */ - if (retval >= pathlen) + if (retval >= pathlen) { return (ISC_R_NOSPACE); + } return (ISC_R_SUCCESS); } @@ -648,10 +682,11 @@ isc_file_truncate(const char *filename, isc_offset_t size) { REQUIRE(filename != NULL && size >= 0); - if ((fh = open(filename, _O_RDWR | _O_BINARY)) < 0) + if ((fh = open(filename, _O_RDWR | _O_BINARY)) < 0) { return (isc__errno2result(errno)); + } - if(_chsize(fh, size) != 0) { + if (_chsize(fh, size) != 0) { close(fh); return (isc__errno2result(errno)); } @@ -673,17 +708,20 @@ isc_file_safecreate(const char *filename, FILE **fp) { result = file_stats(filename, &sb); if (result == ISC_R_SUCCESS) { - if ((sb.st_mode & S_IFREG) == 0) + if ((sb.st_mode & S_IFREG) == 0) { return (ISC_R_INVALIDFILE); + } flags = O_WRONLY | O_TRUNC; } else if (result == ISC_R_FILENOTFOUND) { flags = O_WRONLY | O_CREAT | O_EXCL; - } else + } else { return (result); + } fd = open(filename, flags, S_IRUSR | S_IWUSR); - if (fd == -1) + if (fd == -1) { return (isc__errno2result(errno)); + } f = fdopen(fd, "w"); if (f == NULL) { @@ -698,8 +736,7 @@ isc_file_safecreate(const char *filename, FILE **fp) { isc_result_t isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, - char const ** basename) -{ + char const **basename) { char *dir; const char *file, *slash; char *backslash; @@ -709,7 +746,9 @@ isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, backslash = strrchr(path, '\\'); if ((slash != NULL && backslash != NULL && backslash > slash) || (slash == NULL && backslash != NULL)) + { slash = backslash; + } if (slash == path) { file = ++slash; @@ -717,15 +756,15 @@ isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, } else if (slash != NULL) { file = ++slash; dir = isc_mem_allocate(mctx, slash - path); - if (dir != NULL) - strlcpy(dir, path, slash - path); + strlcpy(dir, path, slash - path); } else { file = path; dir = isc_mem_strdup(mctx, "."); } - if (dir == NULL) + if (dir == NULL) { return (ISC_R_NOMEMORY); + } if (*file == '\0') { isc_mem_free(mctx, dir); @@ -739,9 +778,8 @@ isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname, } void * -isc_file_mmap(void *addr, size_t len, int prot, - int flags, int fd, off_t offset) -{ +isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, + off_t offset) { void *buf; ssize_t ret; off_t end; @@ -752,15 +790,17 @@ isc_file_mmap(void *addr, size_t len, int prot, end = lseek(fd, 0, SEEK_END); lseek(fd, offset, SEEK_SET); - if (end - offset < (off_t) len) + if (end - offset < (off_t)len) { len = end - offset; + } buf = malloc(len); - if (buf == NULL) + if (buf == NULL) { return (NULL); + } - ret = read(fd, buf, (unsigned int) len); - if (ret != (ssize_t) len) { + ret = read(fd, buf, (unsigned int)len); + if (ret != (ssize_t)len) { free(buf); buf = NULL; } @@ -776,14 +816,10 @@ isc_file_munmap(void *addr, size_t len) { } #define DISALLOW "\\/:ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif static isc_result_t -digest2hex(unsigned char *digest, unsigned int digestlen, - char *hash, size_t hashlen) -{ +digest2hex(unsigned char *digest, unsigned int digestlen, char *hash, + size_t hashlen) { unsigned int i; int ret; for (i = 0; i < digestlen; i++) { @@ -798,8 +834,7 @@ digest2hex(unsigned char *digest, unsigned int digestlen, isc_result_t isc_file_sanitize(const char *dir, const char *base, const char *ext, - char *path, size_t length) -{ + char *path, size_t length) { char buf[PATH_MAX]; unsigned char digest[ISC_MAX_MD_SIZE]; unsigned int digestlen; @@ -816,20 +851,24 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, * allow room for a full sha256 hash (64 chars * plus null terminator) */ - if (l < 65) + if (l < 65) { l = 65; + } - if (dir != NULL) + if (dir != NULL) { l += strlen(dir) + 1; - if (ext != NULL) + } + if (ext != NULL) { l += strlen(ext) + 1; + } - if (l > length || l > PATH_MAX) + if (l > length || l > PATH_MAX) { return (ISC_R_NOSPACE); + } /* Check whether the full-length SHA256 hash filename exists */ - err = isc_md(ISC_MD_SHA256, (const unsigned char *)base, - strlen(base), digest, &digestlen); + err = isc_md(ISC_MD_SHA256, (const unsigned char *)base, strlen(base), + digest, &digestlen); if (err != ISC_R_SUCCESS) { return (err); } @@ -839,9 +878,9 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, return (err); } - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - hash, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", hash, ext != NULL ? "." : "", + ext != NULL ? ext : ""); if (isc_file_exists(buf)) { strlcpy(path, buf, length); return (ISC_R_SUCCESS); @@ -849,9 +888,9 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, /* Check for a truncated SHA256 hash filename */ hash[16] = '\0'; - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - hash, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", hash, ext != NULL ? "." : "", + ext != NULL ? ext : ""); if (isc_file_exists(buf)) { strlcpy(path, buf, length); return (ISC_R_SUCCESS); @@ -867,9 +906,9 @@ isc_file_sanitize(const char *dir, const char *base, const char *ext, return (ISC_R_SUCCESS); } - snprintf(buf, sizeof(buf), "%s%s%s%s%s", - dir != NULL ? dir : "", dir != NULL ? "/" : "", - base, ext != NULL ? "." : "", ext != NULL ? ext : ""); + snprintf(buf, sizeof(buf), "%s%s%s%s%s", dir != NULL ? dir : "", + dir != NULL ? "/" : "", base, ext != NULL ? "." : "", + ext != NULL ? ext : ""); strlcpy(path, buf, length); return (ISC_R_SUCCESS); } @@ -891,9 +930,10 @@ isc_file_isdirwritable(const char *path) { /* * Figure out buffer size. GetFileSecurity() should not succeed. */ - if (GetFileSecurity(path, OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, + if (GetFileSecurity(path, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION, NULL, 0, &length)) { return (answer); @@ -911,23 +951,24 @@ isc_file_isdirwritable(const char *path) { /* * GetFileSecurity() should succeed. */ - if (!GetFileSecurity(path, OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, + if (!GetFileSecurity(path, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION, security, length, &length)) { return (answer); } - if (OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | - TOKEN_QUERY | TOKEN_DUPLICATE | - STANDARD_RIGHTS_READ, &hToken)) + if (OpenProcessToken(GetCurrentProcess(), + TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | + STANDARD_RIGHTS_READ, + &hToken)) { HANDLE hImpersonatedToken = NULL; if (DuplicateToken(hToken, SecurityImpersonation, - &hImpersonatedToken)) - { + &hImpersonatedToken)) { GENERIC_MAPPING mapping; PRIVILEGE_SET privileges = { 0 }; DWORD grantedAccess = 0; diff --git a/lib/isc/win32/fsaccess.c b/lib/isc/win32/fsaccess.c index 28bc8a56..a0981fc9 100644 --- a/lib/isc/win32/fsaccess.c +++ b/lib/isc/win32/fsaccess.c @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /* * Note that Win32 does not have the concept of files having access * and ownership bits. The FAT File system only has a readonly flag @@ -20,16 +19,12 @@ * NTFS file systems. Nothing can be done for FAT file systems. */ -#include <config.h> - -#include <stdbool.h> - #include <aclapi.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <io.h> #include <errno.h> +#include <io.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> #include <isc/file.h> #include <isc/stat.h> @@ -52,8 +47,7 @@ static DWORD namelen = 0; */ BOOL -is_ntfs(const char * file) { - +is_ntfs(const char *file) { char drive[255]; char FSType[20]; char tmpbuf[256]; @@ -64,8 +58,8 @@ is_ntfs(const char * file) { REQUIRE(filename != NULL); - if (isc_file_absolutepath(file, filename, - sizeof(filename)) != ISC_R_SUCCESS) { + if (isc_file_absolutepath(file, filename, sizeof(filename)) != + ISC_R_SUCCESS) { return (FALSE); } @@ -74,7 +68,8 @@ is_ntfs(const char * file) { * the UNC style file specs */ if (isalpha(filename[0]) && filename[1] == ':' && - (filename[2] == '\\' || filename[2] == '/')) { + (filename[2] == '\\' || filename[2] == '/')) + { /* Copy 'c:\' or 'c:/' and NUL terminate. */ strlcpy(drive, filename, ISC_MIN(3 + 1, sizeof(drive))); } else if ((filename[0] == '\\') && (filename[1] == '\\')) { @@ -87,16 +82,17 @@ is_ntfs(const char * file) { strlcat(drive, "\\", sizeof(drive)); strlcat(drive, sharename, sizeof(drive)); strlcat(drive, "\\", sizeof(drive)); - - } else /* Not determinable */ + } else { /* Not determinable */ return (FALSE); + } GetVolumeInformation(drive, NULL, 0, NULL, 0, NULL, FSType, sizeof(FSType)); - if (strcmp(FSType, "NTFS") == 0) + if (strcmp(FSType, "NTFS") == 0) { return (TRUE); - else + } else { return (FALSE); + } } /* @@ -114,32 +110,32 @@ FAT_fsaccess_set(const char *path, isc_fsaccess_t access) { */ mode = 0; -#define SET_AND_CLEAR1(modebit) \ +#define SET_AND_CLEAR1(modebit) \ if ((access & bits) != 0) { \ - mode |= modebit; \ - access &= ~bits; \ + mode |= modebit; \ + access &= ~bits; \ } #define SET_AND_CLEAR(user, group, other) \ - SET_AND_CLEAR1(user); \ - bits <<= STEP; \ - SET_AND_CLEAR1(group); \ - bits <<= STEP; \ + SET_AND_CLEAR1(user); \ + bits <<= STEP; \ + SET_AND_CLEAR1(group); \ + bits <<= STEP; \ SET_AND_CLEAR1(other); bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); - bits = ISC_FSACCESS_WRITE | - ISC_FSACCESS_CREATECHILD | + bits = ISC_FSACCESS_WRITE | ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_DELETECHILD; SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); INSIST(access == 0); - if (_chmod(path, mode) < 0) + if (_chmod(path, mode) < 0) { return (isc__errno2result(errno)); + } return (ISC_R_SUCCESS); } @@ -149,15 +145,15 @@ NTFS_Access_Control(const char *filename, const char *user, int access, bool isdir) { SECURITY_DESCRIPTOR sd; BYTE aclBuffer[1024]; - PACL pacl=(PACL)&aclBuffer; + PACL pacl = (PACL)&aclBuffer; BYTE sidBuffer[100]; - PSID psid=(PSID) &sidBuffer; + PSID psid = (PSID)&sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); BYTE adminSidBuffer[100]; - PSID padminsid=(PSID) &adminSidBuffer; + PSID padminsid = (PSID)&adminSidBuffer; DWORD adminSidBufferSize = sizeof(adminSidBuffer); BYTE otherSidBuffer[100]; - PSID pothersid=(PSID) &otherSidBuffer; + PSID pothersid = (PSID)&otherSidBuffer; DWORD otherSidBufferSize = sizeof(otherSidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); @@ -165,24 +161,30 @@ NTFS_Access_Control(const char *filename, const char *user, int access, DWORD NTFSbits; int caccess; - /* Initialize an ACL */ - if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) + if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { return (ISC_R_NOPERM); - if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION)) + } + if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION)) { return (ISC_R_NOPERM); + } if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, - &domainBufferSize, &snu)) + &domainBufferSize, &snu)) + { return (ISC_R_NOPERM); + } domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", padminsid, - &adminSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { + &adminSidBufferSize, domainBuffer, + &domainBufferSize, &snu)) + { (void)GetLastError(); return (ISC_R_NOPERM); } domainBufferSize = sizeof(domainBuffer); - if (!LookupAccountName(0, "Everyone", pothersid, - &otherSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { + if (!LookupAccountName(0, "Everyone", pothersid, &otherSidBufferSize, + domainBuffer, &domainBufferSize, &snu)) + { (void)GetLastError(); return (ISC_R_NOPERM); } @@ -202,7 +204,7 @@ NTFS_Access_Control(const char *filename, const char *user, int access, } /* For directories check the directory-specific bits */ - if (isdir == true) { + if (isdir) { if ((caccess & ISC_FSACCESS_CREATECHILD) != 0) { NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE; } @@ -217,9 +219,10 @@ NTFS_Access_Control(const char *filename, const char *user, int access, } } - if (NTFSbits == (FILE_GENERIC_READ | FILE_GENERIC_WRITE - | FILE_GENERIC_EXECUTE)) - NTFSbits |= FILE_ALL_ACCESS; + if (NTFSbits == + (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)) { + NTFSbits |= FILE_ALL_ACCESS; + } /* * Owner and Administrator also get STANDARD_RIGHTS_ALL * to ensure that they have full control @@ -228,10 +231,12 @@ NTFS_Access_Control(const char *filename, const char *user, int access, NTFSbits |= STANDARD_RIGHTS_ALL; /* Add the ACE to the ACL */ - if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid)) + if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid)) { return (ISC_R_NOPERM); - if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid)) + } + if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid)) { return (ISC_R_NOPERM); + } /* * Group is ignored since we can be in multiple groups or no group @@ -273,31 +278,31 @@ NTFS_Access_Control(const char *filename, const char *user, int access, } } /* Add the ACE to the ACL */ - if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, - pothersid)) + if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, pothersid)) { return (ISC_R_NOPERM); + } - if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE)) + if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE)) { return (ISC_R_NOPERM); + } if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd)) { return (ISC_R_NOPERM); } - return(ISC_R_SUCCESS); + return (ISC_R_SUCCESS); } isc_result_t -NTFS_fsaccess_set(const char *path, isc_fsaccess_t access, - bool isdir){ - +NTFS_fsaccess_set(const char *path, isc_fsaccess_t access, bool isdir) { /* * For NTFS we first need to get the name of the account under * which BIND is running */ if (namelen == 0) { namelen = sizeof(username); - if (GetUserName(username, &namelen) == 0) + if (GetUserName(username, &namelen) == 0) { return (ISC_R_FAILURE); + } } return (NTFS_Access_Control(path, username, access, isdir)); } @@ -308,26 +313,30 @@ isc_fsaccess_set(const char *path, isc_fsaccess_t access) { bool is_dir = false; isc_result_t result; - if (stat(path, &statb) != 0) + if (stat(path, &statb) != 0) { return (isc__errno2result(errno)); + } - if ((statb.st_mode & S_IFDIR) != 0) + if ((statb.st_mode & S_IFDIR) != 0) { is_dir = true; - else if ((statb.st_mode & S_IFREG) == 0) + } else if ((statb.st_mode & S_IFREG) == 0) { return (ISC_R_INVALIDFILE); + } result = check_bad_bits(access, is_dir); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the permissions */ - if (is_ntfs(path)) + if (is_ntfs(path)) { return (NTFS_fsaccess_set(path, access, is_dir)); - else + } else { return (FAT_fsaccess_set(path, access)); + } } isc_result_t @@ -335,47 +344,57 @@ isc_fsaccess_changeowner(const char *filename, const char *user) { SECURITY_DESCRIPTOR psd; BYTE sidBuffer[500]; BYTE groupBuffer[500]; - PSID psid=(PSID) &sidBuffer; + PSID psid = (PSID)&sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; - PSID pSidGroup = (PSID) &groupBuffer; + PSID pSidGroup = (PSID)&groupBuffer; DWORD groupBufferSize = sizeof(groupBuffer); - /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the ownership * FAT disks do not have ownership attributes so it's * a noop. */ - if (is_ntfs(filename) == FALSE) + if (is_ntfs(filename) == FALSE) { return (ISC_R_SUCCESS); + } - if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION)) + if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION)) { return (ISC_R_NOPERM); + } if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, - &domainBufferSize, &snu)) + &domainBufferSize, &snu)) + { return (ISC_R_NOPERM); + } /* Make sure administrators can get to it */ domainBufferSize = sizeof(domainBuffer); - if (!LookupAccountName(0, "Administrators", pSidGroup, - &groupBufferSize, domainBuffer, &domainBufferSize, &snu)) + if (!LookupAccountName(0, "Administrators", pSidGroup, &groupBufferSize, + domainBuffer, &domainBufferSize, &snu)) + { return (ISC_R_NOPERM); + } - if (!SetSecurityDescriptorOwner(&psd, psid, FALSE)) + if (!SetSecurityDescriptorOwner(&psd, psid, FALSE)) { return (ISC_R_NOPERM); + } - if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE)) + if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE)) { return (ISC_R_NOPERM); + } if (!SetFileSecurity(filename, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, - &psd)) + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION, + &psd)) + { return (ISC_R_NOPERM); + } return (ISC_R_SUCCESS); } diff --git a/lib/isc/win32/include/.clang-format b/lib/isc/win32/include/.clang-format new file mode 120000 index 00000000..e919bbad --- /dev/null +++ b/lib/isc/win32/include/.clang-format @@ -0,0 +1 @@ +../../../../.clang-format.headers
\ No newline at end of file diff --git a/lib/isc/win32/include/Makefile.in b/lib/isc/win32/include/Makefile.in index 2cbf021b..f87423b4 100644 --- a/lib/isc/win32/include/Makefile.in +++ b/lib/isc/win32/include/Makefile.in @@ -2,7 +2,7 @@ # # 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 http://mozilla.org/MPL/2.0/. +# 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. @@ -11,7 +11,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -SUBDIRS = isc pkcs11 +SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ diff --git a/lib/isc/win32/include/isc/Makefile.in b/lib/isc/win32/include/isc/Makefile.in index 51b7a3aa..bc05f974 100644 --- a/lib/isc/win32/include/isc/Makefile.in +++ b/lib/isc/win32/include/isc/Makefile.in @@ -2,7 +2,7 @@ # # 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 http://mozilla.org/MPL/2.0/. +# 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. @@ -13,7 +13,7 @@ top_srcdir = @top_srcdir@ VERSION=@BIND9_VERSION@ -HEADERS = dir.h mutex.h net.h netdb.h once.h \ +HEADERS = align.h dir.h mutex.h net.h netdb.h once.h \ stat.h stdtime.h thread.h time.h SUBDIRS = diff --git a/lib/isc/win32/include/isc/align.h b/lib/isc/win32/include/isc/align.h new file mode 100644 index 00000000..d845d365 --- /dev/null +++ b/lib/isc/win32/include/isc/align.h @@ -0,0 +1,13 @@ +/* + * 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 +#define alignas(x) __declspec(align(x)) diff --git a/lib/isc/win32/include/isc/bind_registry.h b/lib/isc/win32/include/isc/bind_registry.h index 57970be8..e728b0ff 100644 --- a/lib/isc/win32/include/isc/bind_registry.h +++ b/lib/isc/win32/include/isc/bind_registry.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_BINDREGISTRY_H #define ISC_BINDREGISTRY_H @@ -18,26 +17,24 @@ * during startup and installation */ -#define BIND_SUBKEY "Software\\ISC\\BIND" -#define BIND_SESSION "CurrentSession" -#define BIND_SESSION_SUBKEY "Software\\ISC\\BIND\\CurrentSession" -#define BIND_UNINSTALL_SUBKEY \ +#define BIND_SUBKEY "Software\\ISC\\BIND" +#define BIND_SESSION "CurrentSession" +#define BIND_SESSION_SUBKEY "Software\\ISC\\BIND\\CurrentSession" +#define BIND_UNINSTALL_SUBKEY \ "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ISC BIND" -#define EVENTLOG_APP_SUBKEY \ +#define EVENTLOG_APP_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application" -#define BIND_MESSAGE_SUBKEY \ +#define BIND_MESSAGE_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\named" -#define BIND_MESSAGE_NAME "named" - -#define BIND_SERVICE_SUBKEY \ - "SYSTEM\\CurrentControlSet\\Services\\named" +#define BIND_MESSAGE_NAME "named" +#define BIND_SERVICE_SUBKEY "SYSTEM\\CurrentControlSet\\Services\\named" -#define BIND_CONFIGFILE 0 -#define BIND_DEBUGLEVEL 1 -#define BIND_QUERYLOG 2 -#define BIND_FOREGROUND 3 -#define BIND_PORT 4 +#define BIND_CONFIGFILE 0 +#define BIND_DEBUGLEVEL 1 +#define BIND_QUERYLOG 2 +#define BIND_FOREGROUND 3 +#define BIND_PORT 4 #endif /* ISC_BINDREGISTRY_H */ diff --git a/lib/isc/win32/include/isc/bindevt.h b/lib/isc/win32/include/isc/bindevt.h index d4088e86..99d3fb86 100644 --- a/lib/isc/win32/include/isc/bindevt.h +++ b/lib/isc/win32/include/isc/bindevt.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_BINDEVT_H #define ISC_BINDEVT_H 1 @@ -19,7 +18,7 @@ */ /* - * Values are 32 bit values layed out as follows: + * Values are 32 bit values laid out as follows: * * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 @@ -48,12 +47,10 @@ * Define the facility codes */ - /* * Define the severity codes */ - /* * MessageId: BIND_ERR_MSG * @@ -61,7 +58,7 @@ * * %1 */ -#define BIND_ERR_MSG ((DWORD)0xC0000001L) +#define BIND_ERR_MSG ((DWORD)0xC0000001L) /* * MessageId: BIND_WARN_MSG @@ -70,7 +67,7 @@ * * %1 */ -#define BIND_WARN_MSG ((DWORD)0x80000002L) +#define BIND_WARN_MSG ((DWORD)0x80000002L) /* * MessageId: BIND_INFO_MSG @@ -79,6 +76,6 @@ * * %1 */ -#define BIND_INFO_MSG ((DWORD)0x40000003L) +#define BIND_INFO_MSG ((DWORD)0x40000003L) #endif /* ISC_BINDEVT_H */ diff --git a/lib/isc/win32/include/isc/condition.h b/lib/isc/win32/include/isc/condition.h index e69425b2..39a1420b 100644 --- a/lib/isc/win32/include/isc/condition.h +++ b/lib/isc/win32/include/isc/condition.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_CONDITION_H #define ISC_CONDITION_H 1 @@ -23,15 +22,14 @@ typedef struct isc_condition_thread isc_condition_thread_t; struct isc_condition_thread { - unsigned long th; - HANDLE handle[2]; - ISC_LINK(isc_condition_thread_t) link; - + unsigned long th; + HANDLE handle[2]; + ISC_LINK(isc_condition_thread_t) link; }; typedef struct isc_condition { - HANDLE events[2]; - unsigned int waiters; + HANDLE events[2]; + unsigned int waiters; ISC_LIST(isc_condition_thread_t) threadlist; } isc_condition_t; diff --git a/lib/isc/win32/include/isc/dir.h b/lib/isc/win32/include/isc/dir.h index 7ec8e0c1..2f2c775a 100644 --- a/lib/isc/win32/include/isc/dir.h +++ b/lib/isc/win32/include/isc/dir.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -12,33 +12,26 @@ #ifndef ISC_DIR_H #define ISC_DIR_H 1 -#include <windows.h> #include <stdbool.h> #include <stdlib.h> +#include <windows.h> #include <isc/lang.h> +#include <isc/platform.h> #include <isc/result.h> -#ifndef NAME_MAX -#define NAME_MAX _MAX_FNAME -#endif - -#ifndef PATH_MAX -#define PATH_MAX _MAX_PATH -#endif - typedef struct { - char name[NAME_MAX]; + char name[NAME_MAX]; unsigned int length; - WIN32_FIND_DATA find_data; + WIN32_FIND_DATA find_data; } isc_direntry_t; typedef struct { - unsigned int magic; - char dirname[PATH_MAX]; - isc_direntry_t entry; - bool entry_filled; - HANDLE search_handle; + unsigned int magic; + char dirname[PATH_MAX]; + isc_direntry_t entry; + bool entry_filled; + HANDLE search_handle; } isc_dir_t; ISC_LANG_BEGINDECLS diff --git a/lib/isc/win32/include/isc/ipv6.h b/lib/isc/win32/include/isc/ipv6.h index bee1bd0f..46df6ed9 100644 --- a/lib/isc/win32/include/isc/ipv6.h +++ b/lib/isc/win32/include/isc/ipv6.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_IPV6_H #define ISC_IPV6_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /* * IPv6 definitions for systems which do not support IPv6. @@ -38,17 +37,32 @@ #if _MSC_VER < 1300 #define in6_addr in_addr6 -#endif +#endif /* if _MSC_VER < 1300 */ #ifndef IN6ADDR_ANY_INIT -#define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }} -#endif +#define IN6ADDR_ANY_INIT \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } \ + } +#endif /* ifndef IN6ADDR_ANY_INIT */ #ifndef IN6ADDR_LOOPBACK_INIT -#define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }} -#endif +#define IN6ADDR_LOOPBACK_INIT \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ + } \ + } +#endif /* ifndef IN6ADDR_LOOPBACK_INIT */ #ifndef IN6ADDR_V4MAPPED_INIT -#define IN6ADDR_V4MAPPED_INIT {{ 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 }} -#endif +#define IN6ADDR_V4MAPPED_INIT \ + { \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0 \ + } \ + } +#endif /* ifndef IN6ADDR_V4MAPPED_INIT */ LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_in6addr_any; LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_in6addr_loopback; @@ -57,64 +71,58 @@ LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_in6addr_loopback; * Unspecified */ #ifndef IN6_IS_ADDR_UNSPECIFIED -#define IN6_IS_ADDR_UNSPECIFIED(a) (\ -*((u_long *)((a)->s6_addr) ) == 0 && \ -*((u_long *)((a)->s6_addr) + 1) == 0 && \ -*((u_long *)((a)->s6_addr) + 2) == 0 && \ -*((u_long *)((a)->s6_addr) + 3) == 0 \ -) -#endif +#define IN6_IS_ADDR_UNSPECIFIED(a) \ + (*((u_long *)((a)->s6_addr)) == 0 && \ + *((u_long *)((a)->s6_addr) + 1) == 0 && \ + *((u_long *)((a)->s6_addr) + 2) == 0 && \ + *((u_long *)((a)->s6_addr) + 3) == 0) +#endif /* ifndef IN6_IS_ADDR_UNSPECIFIED */ /* * Loopback */ #ifndef IN6_IS_ADDR_LOOPBACK -#define IN6_IS_ADDR_LOOPBACK(a) (\ -*((u_long *)((a)->s6_addr) ) == 0 && \ -*((u_long *)((a)->s6_addr) + 1) == 0 && \ -*((u_long *)((a)->s6_addr) + 2) == 0 && \ -*((u_long *)((a)->s6_addr) + 3) == htonl(1) \ -) -#endif +#define IN6_IS_ADDR_LOOPBACK(a) \ + (*((u_long *)((a)->s6_addr)) == 0 && \ + *((u_long *)((a)->s6_addr) + 1) == 0 && \ + *((u_long *)((a)->s6_addr) + 2) == 0 && \ + *((u_long *)((a)->s6_addr) + 3) == htonl(1)) +#endif /* ifndef IN6_IS_ADDR_LOOPBACK */ /* * IPv4 compatible */ -#define IN6_IS_ADDR_V4COMPAT(a) (\ -*((u_long *)((a)->s6_addr) ) == 0 && \ -*((u_long *)((a)->s6_addr) + 1) == 0 && \ -*((u_long *)((a)->s6_addr) + 2) == 0 && \ -*((u_long *)((a)->s6_addr) + 3) != 0 && \ -*((u_long *)((a)->s6_addr) + 3) != htonl(1) \ -) +#define IN6_IS_ADDR_V4COMPAT(a) \ + (*((u_long *)((a)->s6_addr)) == 0 && \ + *((u_long *)((a)->s6_addr) + 1) == 0 && \ + *((u_long *)((a)->s6_addr) + 2) == 0 && \ + *((u_long *)((a)->s6_addr) + 3) != 0 && \ + *((u_long *)((a)->s6_addr) + 3) != htonl(1)) /* * Mapped */ -#define IN6_IS_ADDR_V4MAPPED(a) (\ -*((u_long *)((a)->s6_addr) ) == 0 && \ -*((u_long *)((a)->s6_addr) + 1) == 0 && \ -*((u_long *)((a)->s6_addr) + 2) == htonl(0x0000ffff)) +#define IN6_IS_ADDR_V4MAPPED(a) \ + (*((u_long *)((a)->s6_addr)) == 0 && \ + *((u_long *)((a)->s6_addr) + 1) == 0 && \ + *((u_long *)((a)->s6_addr) + 2) == htonl(0x0000ffff)) /* * Multicast */ -#define IN6_IS_ADDR_MULTICAST(a) \ - ((a)->s6_addr[0] == 0xffU) +#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xffU) /* * Unicast link / site local. */ #ifndef IN6_IS_ADDR_LINKLOCAL -#define IN6_IS_ADDR_LINKLOCAL(a) (\ - ((a)->s6_addr[0] == 0xfe) && \ - (((a)->s6_addr[1] & 0xc0) == 0x80)) -#endif +#define IN6_IS_ADDR_LINKLOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) +#endif /* ifndef IN6_IS_ADDR_LINKLOCAL */ #ifndef IN6_IS_ADDR_SITELOCAL -#define IN6_IS_ADDR_SITELOCAL(a) (\ - ((a)->s6_addr[0] == 0xfe) && \ - (((a)->s6_addr[1] & 0xc0) == 0xc0)) -#endif +#define IN6_IS_ADDR_SITELOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) +#endif /* ifndef IN6_IS_ADDR_SITELOCAL */ #endif /* ISC_IPV6_H */ diff --git a/lib/isc/win32/include/isc/mutex.h b/lib/isc/win32/include/isc/mutex.h index 28a08a05..4be07689 100644 --- a/lib/isc/win32/include/isc/mutex.h +++ b/lib/isc/win32/include/isc/mutex.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_MUTEX_H #define ISC_MUTEX_H 1 -#include <isc/net.h> #include <windows.h> +#include <isc/net.h> #include <isc/result.h> typedef CRITICAL_SECTION isc_mutex_t; @@ -29,20 +28,18 @@ WINBASEAPI BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); #endif /* _WIN32_WINNT < 0x0400 */ -#define isc_mutex_init(mp) \ - InitializeCriticalSection((mp)) -#define isc_mutex_lock(mp) \ - (EnterCriticalSection((mp)), ISC_R_SUCCESS) -#define isc_mutex_unlock(mp) \ - (LeaveCriticalSection((mp)), ISC_R_SUCCESS) +#define isc_mutex_init(mp) InitializeCriticalSection((mp)) +#define isc_mutex_lock(mp) (EnterCriticalSection((mp)), ISC_R_SUCCESS) +#define isc_mutex_unlock(mp) (LeaveCriticalSection((mp)), ISC_R_SUCCESS) #define isc_mutex_trylock(mp) \ (TryEnterCriticalSection((mp)) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY) -#define isc_mutex_destroy(mp) \ - (DeleteCriticalSection((mp))) +#define isc_mutex_destroy(mp) (DeleteCriticalSection((mp))) /* * This is a placeholder for now since we are not keeping any mutex stats */ -#define isc_mutex_stats(fp) do {} while (0) +#define isc_mutex_stats(fp) \ + do { \ + } while (0) #endif /* ISC_MUTEX_H */ diff --git a/lib/isc/win32/include/isc/net.h b/lib/isc/win32/include/isc/net.h index 54e1c31f..600130a6 100644 --- a/lib/isc/win32/include/isc/net.h +++ b/lib/isc/win32/include/isc/net.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -13,8 +13,8 @@ #define ISC_NET_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /* * Basic Networking Types @@ -73,18 +73,17 @@ * figure it out. */ #ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ -#endif +#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ +#endif /* ifndef _WINSOCKAPI_ */ #include <winsock2.h> +#include <ws2tcpip.h> -#include <sys/types.h> - +#include <isc/ipv6.h> #include <isc/lang.h> #include <isc/types.h> -#include <ws2tcpip.h> -#include <isc/ipv6.h> +#include <sys/types.h> /* * This is here because named client, interfacemgr.c, etc. use the name as @@ -94,16 +93,16 @@ #ifndef INADDR_ANY #define INADDR_ANY 0x00000000UL -#endif +#endif /* ifndef INADDR_ANY */ #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001UL -#endif +#endif /* ifndef INADDR_LOOPBACK */ #if _MSC_VER < 1300 -#define in6addr_any isc_in6addr_any +#define in6addr_any isc_in6addr_any #define in6addr_loopback isc_in6addr_loopback -#endif +#endif /* if _MSC_VER < 1300 */ /* * Ensure type in_port_t is defined. @@ -117,167 +116,171 @@ typedef uint16_t in_port_t; */ #ifndef MSG_TRUNC #define ISC_PLATFORM_RECVOVERFLOW -#endif +#endif /* ifndef MSG_TRUNC */ -#define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x))) +#define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x))) #define ISC_IPADDR_ISMULTICAST(i) \ - (((uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xe0000000)) + (((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xe0000000)) #define ISC_IPADDR_ISEXPERIMENTAL(i) \ - (((uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xf0000000)) + (((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xf0000000)) /* * Fix the FD_SET and FD_CLR Macros to properly cast */ #undef FD_CLR -#define FD_CLR(fd, set) do { \ - u_int __i; \ - for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ - if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \ - while (__i < ((fd_set FAR *)(set))->fd_count-1) { \ - ((fd_set FAR *)(set))->fd_array[__i] = \ - ((fd_set FAR *)(set))->fd_array[__i+1]; \ - __i++; \ - } \ - ((fd_set FAR *)(set))->fd_count--; \ - break; \ - } \ - } \ -} while (0) +#define FD_CLR(fd, set) \ + do { \ + u_int __i; \ + for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ + if (((fd_set FAR *)(set))->fd_array[__i] == \ + (SOCKET)fd) { \ + while (__i < \ + ((fd_set FAR *)(set))->fd_count - 1) { \ + ((fd_set FAR *)(set))->fd_array[__i] = \ + ((fd_set FAR *)(set)) \ + ->fd_array[__i + 1]; \ + __i++; \ + } \ + ((fd_set FAR *)(set))->fd_count--; \ + break; \ + } \ + } \ + } while (0) #undef FD_SET -#define FD_SET(fd, set) do { \ - u_int __i; \ - for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ - if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \ - break; \ - } \ - } \ - if (__i == ((fd_set FAR *)(set))->fd_count) { \ - if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \ - ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \ - ((fd_set FAR *)(set))->fd_count++; \ - } \ - } \ -} while (0) +#define FD_SET(fd, set) \ + do { \ + u_int __i; \ + for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ + if (((fd_set FAR *)(set))->fd_array[__i] == \ + (SOCKET)(fd)) { \ + break; \ + } \ + } \ + if (__i == ((fd_set FAR *)(set))->fd_count) { \ + if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \ + ((fd_set FAR *)(set))->fd_array[__i] = \ + (SOCKET)(fd); \ + ((fd_set FAR *)(set))->fd_count++; \ + } \ + } \ + } while (0) /* * Windows Sockets errors redefined as regular Berkeley error constants. - * These are usually commented out in Windows NT to avoid conflicts with errno.h. - * Use the WSA constants instead. + * These are usually commented out in Windows NT to avoid conflicts with + * errno.h. Use the WSA constants instead. */ #include <errno.h> #ifndef EWOULDBLOCK -#define EWOULDBLOCK WSAEWOULDBLOCK -#endif +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif /* ifndef EWOULDBLOCK */ #ifndef EINPROGRESS -#define EINPROGRESS WSAEINPROGRESS -#endif +#define EINPROGRESS WSAEINPROGRESS +#endif /* ifndef EINPROGRESS */ #ifndef EALREADY -#define EALREADY WSAEALREADY -#endif +#define EALREADY WSAEALREADY +#endif /* ifndef EALREADY */ #ifndef ENOTSOCK -#define ENOTSOCK WSAENOTSOCK -#endif +#define ENOTSOCK WSAENOTSOCK +#endif /* ifndef ENOTSOCK */ #ifndef EDESTADDRREQ -#define EDESTADDRREQ WSAEDESTADDRREQ -#endif +#define EDESTADDRREQ WSAEDESTADDRREQ +#endif /* ifndef EDESTADDRREQ */ #ifndef EMSGSIZE -#define EMSGSIZE WSAEMSGSIZE -#endif +#define EMSGSIZE WSAEMSGSIZE +#endif /* ifndef EMSGSIZE */ #ifndef EPROTOTYPE -#define EPROTOTYPE WSAEPROTOTYPE -#endif +#define EPROTOTYPE WSAEPROTOTYPE +#endif /* ifndef EPROTOTYPE */ #ifndef ENOPROTOOPT -#define ENOPROTOOPT WSAENOPROTOOPT -#endif +#define ENOPROTOOPT WSAENOPROTOOPT +#endif /* ifndef ENOPROTOOPT */ #ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#endif +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#endif /* ifndef EPROTONOSUPPORT */ #ifndef ESOCKTNOSUPPORT -#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT -#endif +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#endif /* ifndef ESOCKTNOSUPPORT */ #ifndef EOPNOTSUPP -#define EOPNOTSUPP WSAEOPNOTSUPP -#endif +#define EOPNOTSUPP WSAEOPNOTSUPP +#endif /* ifndef EOPNOTSUPP */ #ifndef EPFNOSUPPORT -#define EPFNOSUPPORT WSAEPFNOSUPPORT -#endif +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#endif /* ifndef EPFNOSUPPORT */ #ifndef EAFNOSUPPORT -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#endif +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif /* ifndef EAFNOSUPPORT */ #ifndef EADDRINUSE -#define EADDRINUSE WSAEADDRINUSE -#endif +#define EADDRINUSE WSAEADDRINUSE +#endif /* ifndef EADDRINUSE */ #ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#endif +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#endif /* ifndef EADDRNOTAVAIL */ #ifndef ENETDOWN -#define ENETDOWN WSAENETDOWN -#endif +#define ENETDOWN WSAENETDOWN +#endif /* ifndef ENETDOWN */ #ifndef ENETUNREACH -#define ENETUNREACH WSAENETUNREACH -#endif +#define ENETUNREACH WSAENETUNREACH +#endif /* ifndef ENETUNREACH */ #ifndef ENETRESET -#define ENETRESET WSAENETRESET -#endif +#define ENETRESET WSAENETRESET +#endif /* ifndef ENETRESET */ #ifndef ECONNABORTED -#define ECONNABORTED WSAECONNABORTED -#endif +#define ECONNABORTED WSAECONNABORTED +#endif /* ifndef ECONNABORTED */ #ifndef ECONNRESET -#define ECONNRESET WSAECONNRESET -#endif +#define ECONNRESET WSAECONNRESET +#endif /* ifndef ECONNRESET */ #ifndef ENOBUFS -#define ENOBUFS WSAENOBUFS -#endif +#define ENOBUFS WSAENOBUFS +#endif /* ifndef ENOBUFS */ #ifndef EISCONN -#define EISCONN WSAEISCONN -#endif +#define EISCONN WSAEISCONN +#endif /* ifndef EISCONN */ #ifndef ENOTCONN -#define ENOTCONN WSAENOTCONN -#endif +#define ENOTCONN WSAENOTCONN +#endif /* ifndef ENOTCONN */ #ifndef ESHUTDOWN -#define ESHUTDOWN WSAESHUTDOWN -#endif +#define ESHUTDOWN WSAESHUTDOWN +#endif /* ifndef ESHUTDOWN */ #ifndef ETOOMANYREFS -#define ETOOMANYREFS WSAETOOMANYREFS -#endif +#define ETOOMANYREFS WSAETOOMANYREFS +#endif /* ifndef ETOOMANYREFS */ #ifndef ETIMEDOUT -#define ETIMEDOUT WSAETIMEDOUT -#endif +#define ETIMEDOUT WSAETIMEDOUT +#endif /* ifndef ETIMEDOUT */ #ifndef ECONNREFUSED -#define ECONNREFUSED WSAECONNREFUSED -#endif +#define ECONNREFUSED WSAECONNREFUSED +#endif /* ifndef ECONNREFUSED */ #ifndef ELOOP -#define ELOOP WSAELOOP -#endif +#define ELOOP WSAELOOP +#endif /* ifndef ELOOP */ #ifndef EHOSTDOWN -#define EHOSTDOWN WSAEHOSTDOWN -#endif +#define EHOSTDOWN WSAEHOSTDOWN +#endif /* ifndef EHOSTDOWN */ #ifndef EHOSTUNREACH -#define EHOSTUNREACH WSAEHOSTUNREACH -#endif +#define EHOSTUNREACH WSAEHOSTUNREACH +#endif /* ifndef EHOSTUNREACH */ #ifndef EPROCLIM -#define EPROCLIM WSAEPROCLIM -#endif +#define EPROCLIM WSAEPROCLIM +#endif /* ifndef EPROCLIM */ #ifndef EUSERS -#define EUSERS WSAEUSERS -#endif +#define EUSERS WSAEUSERS +#endif /* ifndef EUSERS */ #ifndef EDQUOT -#define EDQUOT WSAEDQUOT -#endif +#define EDQUOT WSAEDQUOT +#endif /* ifndef EDQUOT */ #ifndef ESTALE -#define ESTALE WSAESTALE -#endif +#define ESTALE WSAESTALE +#endif /* ifndef ESTALE */ #ifndef EREMOTE -#define EREMOTE WSAEREMOTE -#endif - +#define EREMOTE WSAEREMOTE +#endif /* ifndef EREMOTE */ /*** *** Functions. @@ -322,13 +325,13 @@ isc_net_probeunix(void); * ISC_R_NOTFOUND */ -#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ -#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ -#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ -#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ -#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ -#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ -#define ISC_NET_DSCPALL 0x3f /* All valid flags */ +#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ +#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ +#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ +#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ +#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ +#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ +#define ISC_NET_DSCPALL 0x3f /* All valid flags */ unsigned int isc_net_probedscp(void); diff --git a/lib/isc/win32/include/isc/netdb.h b/lib/isc/win32/include/isc/netdb.h index c07194d5..37d38361 100644 --- a/lib/isc/win32/include/isc/netdb.h +++ b/lib/isc/win32/include/isc/netdb.h @@ -3,19 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NETDB_H #define ISC_NETDB_H 1 /***** - ***** Module Info - *****/ +***** Module Info +*****/ /* * Portable netdb.h support. diff --git a/lib/isc/win32/include/isc/ntgroups.h b/lib/isc/win32/include/isc/ntgroups.h index e8352fcb..4abdeb1e 100644 --- a/lib/isc/win32/include/isc/ntgroups.h +++ b/lib/isc/win32/include/isc/ntgroups.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_NTGROUPS_H #define ISC_NTGROUPS_H 1 @@ -18,10 +17,9 @@ ISC_LANG_BEGINDECLS - isc_result_t -isc_ntsecurity_getaccountgroups(char *name, char **Groups, unsigned int maxgroups, - unsigned int *total); +isc_ntsecurity_getaccountgroups(char *name, char **Groups, + unsigned int maxgroups, unsigned int *total); ISC_LANG_ENDDECLS diff --git a/lib/isc/win32/include/isc/ntpaths.h b/lib/isc/win32/include/isc/ntpaths.h index acadc36a..e1652ed2 100644 --- a/lib/isc/win32/include/isc/ntpaths.h +++ b/lib/isc/win32/include/isc/ntpaths.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /* * Windows-specific path definitions * These routines are used to set up and return system-specific path @@ -40,17 +39,17 @@ enum NtPaths { /* * Define macros to get the path of the config files */ -#define NAMED_CONFFILE isc_ntpaths_get(NAMED_CONF_PATH) -#define RNDC_CONFFILE isc_ntpaths_get(RNDC_CONF_PATH) -#define RNDC_KEYFILE isc_ntpaths_get(RNDC_KEY_PATH) +#define NAMED_CONFFILE isc_ntpaths_get(NAMED_CONF_PATH) +#define RNDC_CONFFILE isc_ntpaths_get(RNDC_CONF_PATH) +#define RNDC_KEYFILE isc_ntpaths_get(RNDC_KEY_PATH) #define SESSION_KEYFILE isc_ntpaths_get(SESSION_KEY_PATH) -#define RESOLV_CONF isc_ntpaths_get(RESOLV_CONF_PATH) +#define RESOLV_CONF isc_ntpaths_get(RESOLV_CONF_PATH) /* * Information about where the files are on disk */ -#define NAMED_LOCALSTATEDIR "/dns/bin" -#define NAMED_SYSCONFDIR "/dns/etc" +#define NAMED_LOCALSTATEDIR "/dns/bin" +#define NAMED_SYSCONFDIR "/dns/etc" ISC_LANG_BEGINDECLS diff --git a/lib/isc/win32/include/isc/offset.h b/lib/isc/win32/include/isc/offset.h index 14ef06fa..77488263 100644 --- a/lib/isc/win32/include/isc/offset.h +++ b/lib/isc/win32/include/isc/offset.h @@ -3,20 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_OFFSET_H #define ISC_OFFSET_H 1 /* * File offsets are operating-system dependent. */ -#include <limits.h> /* Required for CHAR_BIT. */ +#include <limits.h> /* Required for CHAR_BIT. */ + #include <sys/types.h> typedef _off_t isc_offset_t; diff --git a/lib/isc/win32/include/isc/once.h b/lib/isc/win32/include/isc/once.h index c005b0b0..4a4875a8 100644 --- a/lib/isc/win32/include/isc/once.h +++ b/lib/isc/win32/include/isc/once.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_ONCE_H #define ISC_ONCE_H 1 @@ -24,12 +23,15 @@ typedef struct { } isc_once_t; #define ISC_ONCE_INIT_NEEDED 0 -#define ISC_ONCE_INIT_DONE 1 +#define ISC_ONCE_INIT_DONE 1 -#define ISC_ONCE_INIT { ISC_ONCE_INIT_NEEDED, 1 } +#define ISC_ONCE_INIT \ + { \ + ISC_ONCE_INIT_NEEDED, 1 \ + } isc_result_t -isc_once_do(isc_once_t *controller, void(*function)(void)); +isc_once_do(isc_once_t *controller, void (*function)(void)); ISC_LANG_ENDDECLS diff --git a/lib/isc/win32/include/isc/platform.h.in b/lib/isc/win32/include/isc/platform.h.in index 4bab6a47..b224d72a 100644 --- a/lib/isc/win32/include/isc/platform.h.in +++ b/lib/isc/win32/include/isc/platform.h.in @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -48,16 +48,26 @@ typedef uint32_t socklen_t; #define __attribute__(attribute) /* do nothing */ -/*** - *** Network. - ***/ +/* + * Limits + */ + +#ifndef NAME_MAX +#define NAME_MAX _MAX_FNAME +#endif #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif +/*** + *** Network. + ***/ + #undef MSG_TRUNC +typedef uint16_t sa_family_t; + /* * Define if the platform has <sys/un.h>. */ diff --git a/lib/isc/win32/include/isc/stat.h b/lib/isc/win32/include/isc/stat.h index 8b7d6850..05ff22d3 100644 --- a/lib/isc/win32/include/isc/stat.h +++ b/lib/isc/win32/include/isc/stat.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STAT_H #define ISC_STAT_H 1 @@ -25,33 +24,33 @@ typedef unsigned short mode_t; * We'll just map them all to the NT equivalent */ -#define S_IREAD _S_IREAD /* read permission, owner */ -#define S_IWRITE _S_IWRITE /* write permission, owner */ -#define S_IRUSR _S_IREAD /* Owner read permission */ -#define S_IWUSR _S_IWRITE /* Owner write permission */ -#define S_IRGRP _S_IREAD /* Group read permission */ -#define S_IWGRP _S_IWRITE /* Group write permission */ -#define S_IROTH _S_IREAD /* Other read permission */ -#define S_IWOTH _S_IWRITE /* Other write permission */ +#define S_IREAD _S_IREAD /* read permission, owner */ +#define S_IWRITE _S_IWRITE /* write permission, owner */ +#define S_IRUSR _S_IREAD /* Owner read permission */ +#define S_IWUSR _S_IWRITE /* Owner write permission */ +#define S_IRGRP _S_IREAD /* Group read permission */ +#define S_IWGRP _S_IWRITE /* Group write permission */ +#define S_IROTH _S_IREAD /* Other read permission */ +#define S_IWOTH _S_IWRITE /* Other write permission */ #ifndef S_IFMT -# define S_IFMT _S_IFMT -#endif +#define S_IFMT _S_IFMT +#endif /* ifndef S_IFMT */ #ifndef S_IFDIR -# define S_IFDIR _S_IFDIR -#endif +#define S_IFDIR _S_IFDIR +#endif /* ifndef S_IFDIR */ #ifndef S_IFCHR -# define S_IFCHR _S_IFCHR -#endif +#define S_IFCHR _S_IFCHR +#endif /* ifndef S_IFCHR */ #ifndef S_IFREG -# define S_IFREG _S_IFREG -#endif +#define S_IFREG _S_IFREG +#endif /* ifndef S_IFREG */ #ifndef S_ISDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif /* ifndef S_ISDIR */ #ifndef S_ISREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) +#endif /* ifndef S_ISREG */ #endif /* ISC_STAT_H */ diff --git a/lib/isc/win32/include/isc/stdatomic.h b/lib/isc/win32/include/isc/stdatomic.h index 1d933e55..c0f9a7da 100644 --- a/lib/isc/win32/include/isc/stdatomic.h +++ b/lib/isc/win32/include/isc/stdatomic.h @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -12,38 +12,43 @@ #pragma once #define WIN32_LEAN_AND_MEAN +#include <intrin.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> +#include <uchar.h> #include <windows.h> -#include <intrin.h> +#pragma warning(disable : 4133) +#pragma warning(disable : 4090) -#define InterlockedExchangeAdd8 _InterlockedExchangeAdd8 +#define InterlockedExchangeAdd8 _InterlockedExchangeAdd8 #define InterlockedCompareExchange8 _InterlockedCompareExchange8 #pragma intrinsic(_InterlockedCompareExchange8, _InterlockedExchangeAdd8) #include <isc/util.h> +#define ATOMIC_VAR_INIT(x) x + #ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 -#endif +#define __ATOMIC_RELAXED 0 +#endif /* ifndef __ATOMIC_RELAXED */ #ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 -#endif +#define __ATOMIC_CONSUME 1 +#endif /* ifndef __ATOMIC_CONSUME */ #ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 -#endif +#define __ATOMIC_ACQUIRE 2 +#endif /* ifndef __ATOMIC_ACQUIRE */ #ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 -#endif +#define __ATOMIC_RELEASE 3 +#endif /* ifndef __ATOMIC_RELEASE */ #ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 -#endif +#define __ATOMIC_ACQ_REL 4 +#endif /* ifndef __ATOMIC_ACQ_REL */ #ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 -#endif +#define __ATOMIC_SEQ_CST 5 +#endif /* ifndef __ATOMIC_SEQ_CST */ enum memory_order { memory_order_relaxed = __ATOMIC_RELAXED, @@ -61,169 +66,396 @@ typedef enum memory_order memory_order; * you need to implement atomic_<foo>_explicitNN macros. */ -typedef bool volatile atomic_bool; -typedef int_fast8_t volatile atomic_int_fast8_t; -typedef uint_fast8_t volatile atomic_uint_fast8_t; -typedef int_fast32_t volatile atomic_int_fast32_t; -typedef uint_fast32_t volatile atomic_uint_fast32_t; -typedef int_fast64_t volatile atomic_int_fast64_t; -typedef uint_fast64_t volatile atomic_uint_fast64_t; - -#define atomic_init(obj, desired) \ - (*(obj) = (desired)) +typedef bool volatile atomic_bool; +typedef char volatile atomic_char; +typedef signed char volatile atomic_schar; +typedef unsigned char volatile atomic_uchar; +typedef short volatile atomic_short; +typedef unsigned short volatile atomic_ushort; +typedef int volatile atomic_int; +typedef unsigned int volatile atomic_uint; +typedef long volatile atomic_long; +typedef unsigned long volatile atomic_ulong; +typedef long long volatile atomic_llong; +typedef unsigned long long volatile atomic_ullong; +typedef char16_t volatile atomic_char16_t; +typedef char32_t volatile atomic_char32_t; +typedef wchar_t volatile atomic_wchar_t; +typedef int_least8_t volatile atomic_int_least8_t; +typedef uint_least8_t volatile atomic_uint_least8_t; +typedef int_least16_t volatile atomic_int_least16_t; +typedef uint_least16_t volatile atomic_uint_least16_t; +typedef int_least32_t volatile atomic_int_least32_t; +typedef uint_least32_t volatile atomic_uint_least32_t; +typedef int_least64_t volatile atomic_int_least64_t; +typedef uint_least64_t volatile atomic_uint_least64_t; +typedef int_fast8_t volatile atomic_int_fast8_t; +typedef uint_fast8_t volatile atomic_uint_fast8_t; +typedef int_fast16_t volatile atomic_int_fast16_t; +typedef uint_fast16_t volatile atomic_uint_fast16_t; +typedef int_fast32_t volatile atomic_int_fast32_t; +typedef uint_fast32_t volatile atomic_uint_fast32_t; +typedef int_fast64_t volatile atomic_int_fast64_t; +typedef uint_fast64_t volatile atomic_uint_fast64_t; +typedef intptr_t volatile atomic_intptr_t; +typedef uintptr_t volatile atomic_uintptr_t; +typedef size_t volatile atomic_size_t; +typedef ptrdiff_t volatile atomic_ptrdiff_t; +typedef intmax_t volatile atomic_intmax_t; +typedef uintmax_t volatile atomic_uintmax_t; + +#define atomic_init(obj, desired) (*(obj) = (desired)) #define atomic_store_explicit8(obj, desired, order) \ (void)InterlockedExchange8((atomic_int_fast8_t *)obj, desired) -#define atomic_store_explicit32(obj, desired, order) \ - (order == memory_order_relaxed \ - ? (void)InterlockedExchangeNoFence((atomic_int_fast32_t *)obj, desired) \ - : (order == memory_order_acquire \ - ? (void)InterlockedExchangeAcquire((atomic_int_fast32_t *)obj, desired) \ - : (void)InterlockedExchange((atomic_int_fast32_t *)obj, desired))) +#define atomic_store_explicit16(obj, desired, order) \ + (order == memory_order_relaxed \ + ? (void)InterlockedExchangeNoFence16((atomic_short *)obj, \ + desired) \ + : (order == memory_order_acquire \ + ? (void)InterlockedExchangeAcquire16( \ + (atomic_short *)obj, desired) \ + : (void)InterlockedExchange16((atomic_short *)obj, \ + desired))) + +#define atomic_store_explicit32(obj, desired, order) \ + (order == memory_order_relaxed \ + ? (void)InterlockedExchangeNoFence( \ + (atomic_int_fast32_t *)obj, desired) \ + : (order == memory_order_acquire \ + ? (void)InterlockedExchangeAcquire( \ + (atomic_int_fast32_t *)obj, desired) \ + : (void)InterlockedExchange( \ + (atomic_int_fast32_t *)obj, desired))) #ifdef _WIN64 -#define atomic_store_explicit64(obj, desired, order) \ - (order == memory_order_relaxed \ - ? (void)InterlockedExchangeNoFence64((atomic_int_fast64_t *)obj, desired) \ - : (order == memory_order_acquire \ - ? (void)InterlockedExchangeAcquire64((atomic_int_fast64_t *)obj, desired) \ - : (void)InterlockedExchange64((atomic_int_fast64_t *)obj, desired))) -#else -#define atomic_store_explicit64(obj, desired, order) \ +#define atomic_store_explicit64(obj, desired, order) \ + (order == memory_order_relaxed \ + ? (void)InterlockedExchangeNoFence64( \ + (atomic_int_fast64_t *)obj, desired) \ + : (order == memory_order_acquire \ + ? (void)InterlockedExchangeAcquire64( \ + (atomic_int_fast64_t *)obj, desired) \ + : (void)InterlockedExchange64( \ + (atomic_int_fast64_t *)obj, desired))) +#else /* ifdef _WIN64 */ +#define atomic_store_explicit64(obj, desired, order) \ (void)InterlockedExchange64((atomic_int_fast64_t *)obj, desired) -#endif +#endif /* ifdef _WIN64 */ -static inline -void +static inline void atomic_store_abort() { INSIST(0); ISC_UNREACHABLE(); } -#define atomic_store_explicit(obj, desired, order) \ - (sizeof(*(obj)) == 8 \ - ? atomic_store_explicit64(obj, desired, order) \ - : (sizeof(*(obj)) == 4 \ - ? atomic_store_explicit32(obj, desired, order) \ - : (sizeof(*(obj)) == 1 \ - ? atomic_store_explicit8(obj, desired, order) \ - : atomic_store_abort()))) +#define atomic_store_explicit(obj, desired, order) \ + (sizeof(*(obj)) == 8 \ + ? atomic_store_explicit64(obj, desired, order) \ + : (sizeof(*(obj)) == 4 \ + ? atomic_store_explicit32(obj, desired, order) \ + : (sizeof(*(obj)) == 2 \ + ? atomic_store_explicit16(obj, desired, \ + order) \ + : (sizeof(*(obj)) == 1 \ + ? atomic_store_explicit8( \ + obj, desired, \ + order) \ + : atomic_store_abort())))) #define atomic_store(obj, desired) \ atomic_store_explicit(obj, desired, memory_order_seq_cst) -#define atomic_load_explicit8(obj, order) \ - (int8_t)InterlockedOr8((atomic_int_fast8_t *)obj, 0) - -#define atomic_load_explicit32(obj, order) \ - (order == memory_order_relaxed \ - ? (int32_t)InterlockedOrNoFence((atomic_int_fast32_t *)obj, 0) \ - : (order == memory_order_acquire \ - ? (int32_t)InterlockedOrAcquire((atomic_int_fast32_t *)obj, 0) \ - : (order == memory_order_release \ - ? (int32_t)InterlockedOrRelease((atomic_int_fast32_t *)obj, 0) \ - : (int32_t)InterlockedOr((atomic_int_fast32_t *)obj, 0)))) +#define atomic_load_explicit8(obj, order) \ + (int8_t) InterlockedOr8((atomic_int_fast8_t *)obj, 0) + +#define atomic_load_explicit16(obj, order) \ + (short)InterlockedOr16((atomic_short *)obj, 0) + +#define atomic_load_explicit32(obj, order) \ + (order == memory_order_relaxed \ + ? (int32_t)InterlockedOrNoFence((atomic_int_fast32_t *)obj, \ + 0) \ + : (order == memory_order_acquire \ + ? (int32_t)InterlockedOrAcquire( \ + (atomic_int_fast32_t *)obj, 0) \ + : (order == memory_order_release \ + ? (int32_t)InterlockedOrRelease( \ + (atomic_int_fast32_t *)obj, 0) \ + : (int32_t)InterlockedOr( \ + (atomic_int_fast32_t *)obj, \ + 0)))) #ifdef _WIN64 -#define atomic_load_explicit64(obj, order) \ - (order == memory_order_relaxed \ - ? InterlockedOr64NoFence((atomic_int_fast64_t *)obj, 0) \ - : (order == memory_order_acquire \ - ? InterlockedOr64Acquire((atomic_int_fast64_t *)obj, 0) \ - : (order == memory_order_release \ - ? InterlockedOr64Release((atomic_int_fast64_t *)obj, 0) \ - : InterlockedOr64((atomic_int_fast64_t *)obj, 0)))) -#else -#define atomic_load_explicit64(obj, order) \ +#define atomic_load_explicit64(obj, order) \ + (order == memory_order_relaxed \ + ? InterlockedOr64NoFence((atomic_int_fast64_t *)obj, 0) \ + : (order == memory_order_acquire \ + ? InterlockedOr64Acquire( \ + (atomic_int_fast64_t *)obj, 0) \ + : (order == memory_order_release \ + ? InterlockedOr64Release( \ + (atomic_int_fast64_t *)obj, 0) \ + : InterlockedOr64( \ + (atomic_int_fast64_t *)obj, \ + 0)))) +#else /* ifdef _WIN64 */ +#define atomic_load_explicit64(obj, order) \ InterlockedOr64((atomic_int_fast64_t *)obj, 0) -#endif +#endif /* ifdef _WIN64 */ -static inline -int8_t +static inline int8_t atomic_load_abort() { INSIST(0); ISC_UNREACHABLE(); } -#define atomic_load_explicit(obj, order) \ - ((sizeof(*(obj)) == 8 \ - ? atomic_load_explicit64(obj, order) \ - : (sizeof(*(obj) == 4) \ - ? atomic_load_explicit32(obj, order) \ - : (sizeof(*(obj) == 1) \ - ? atomic_load_explicit8(obj, order) \ - : atomic_load_abort()))) & \ - (sizeof(*(obj)) == 8 ? 0xffffffffffffffffULL : \ - (sizeof(*(obj)) == 4 ? 0xffffffffULL : \ - (sizeof(*(obj)) == 1 ? 0xffULL : atomic_load_abort())))) - - -#define atomic_load(obj) \ - atomic_load_explicit(obj, memory_order_seq_cst) - -#define atomic_fetch_add_explicit8(obj, arg, order) \ +#define atomic_load_explicit(obj, order) \ + ((sizeof(*(obj)) == 8 \ + ? atomic_load_explicit64(obj, order) \ + : (sizeof(*(obj) == 4) \ + ? atomic_load_explicit32(obj, order) \ + : (sizeof(*(obj) == 2) \ + ? atomic_load_explicit16(obj, order) \ + : (sizeof(*(obj) == 1) \ + ? atomic_load_explicit8( \ + obj, order) \ + : atomic_load_abort())))) & \ + (sizeof(*(obj)) == 8 \ + ? 0xffffffffffffffffULL \ + : (sizeof(*(obj)) == 4 \ + ? 0xffffffffULL \ + : (sizeof(*(obj)) == 2 \ + ? 0xffffULL \ + : (sizeof(*(obj)) == 1 \ + ? 0xffULL \ + : atomic_load_abort()))))) + +#define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) + +#define atomic_fetch_add_explicit8(obj, arg, order) \ InterlockedExchangeAdd8((atomic_int_fast8_t *)obj, arg) -#define atomic_fetch_add_explicit32(obj, arg, order) \ - (order == memory_order_relaxed \ - ? InterlockedExchangeAddNoFence((atomic_int_fast32_t *)obj, arg) \ - : (order == memory_order_acquire \ - ? InterlockedExchangeAddAcquire((atomic_int_fast32_t *)obj, arg) \ - : (order == memory_order_release \ - ? InterlockedExchangeAddRelease((atomic_int_fast32_t *)obj, arg) \ - : InterlockedExchangeAdd((atomic_int_fast32_t *)obj, arg)))) +#define atomic_fetch_add_explicit16(obj, arg, order) \ + InterlockedExchangeAdd16((atomic_short *)obj, arg) + +#define atomic_fetch_add_explicit32(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedExchangeAddNoFence((atomic_int_fast32_t *)obj, \ + arg) \ + : (order == memory_order_acquire \ + ? InterlockedExchangeAddAcquire( \ + (atomic_int_fast32_t *)obj, arg) \ + : (order == memory_order_release \ + ? InterlockedExchangeAddRelease( \ + (atomic_int_fast32_t *)obj, \ + arg) \ + : InterlockedExchangeAdd( \ + (atomic_int_fast32_t *)obj, \ + arg)))) #ifdef _WIN64 -#define atomic_fetch_add_explicit64(obj, arg, order) \ - (order == memory_order_relaxed \ - ? InterlockedExchangeAddNoFence64((atomic_int_fast64_t *)obj, arg) \ - : (order == memory_order_acquire \ - ? InterlockedExchangeAddAcquire64((atomic_int_fast64_t *)obj, arg) \ - : (order == memory_order_release \ - ? InterlockedExchangeAddRelease64((atomic_int_fast64_t *)obj, arg) \ - : InterlockedExchangeAdd64((atomic_int_fast64_t *)obj, arg)))) -#else -#define atomic_fetch_add_explicit64(obj, arg, order) \ - InterlockedExchange64((atomic_int_fast64_t *)obj, arg) -#endif - -static inline -int8_t +#define atomic_fetch_add_explicit64(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedExchangeAddNoFence64((atomic_int_fast64_t *)obj, \ + arg) \ + : (order == memory_order_acquire \ + ? InterlockedExchangeAddAcquire64( \ + (atomic_int_fast64_t *)obj, arg) \ + : (order == memory_order_release \ + ? InterlockedExchangeAddRelease64( \ + (atomic_int_fast64_t *)obj, \ + arg) \ + : InterlockedExchangeAdd64( \ + (atomic_int_fast64_t *)obj, \ + arg)))) +#else /* ifdef _WIN64 */ +#define atomic_fetch_add_explicit64(obj, arg, order) \ + InterlockedExchangeAdd64((atomic_int_fast64_t *)obj, arg) +#endif /* ifdef _WIN64 */ + +static inline int8_t atomic_add_abort() { INSIST(0); ISC_UNREACHABLE(); } -#define atomic_fetch_add_explicit(obj, arg, order) \ - (sizeof(*(obj)) == 8 \ - ? atomic_fetch_add_explicit64(obj, arg, order) \ - : (sizeof(*(obj)) == 4 \ - ? atomic_fetch_add_explicit32(obj, arg, order) \ - : (sizeof(*(obj)) == 1 \ - ? atomic_fetch_add_explicit8(obj, arg, order) \ - : atomic_add_abort()))) - -#define atomic_fetch_add(obj, arg) \ +#define atomic_fetch_add_explicit(obj, arg, order) \ + (sizeof(*(obj)) == 8 \ + ? atomic_fetch_add_explicit64(obj, arg, order) \ + : (sizeof(*(obj)) == 4 \ + ? atomic_fetch_add_explicit32(obj, arg, order) \ + : (sizeof(*(obj)) == 2 \ + ? atomic_fetch_add_explicit16(obj, arg, \ + order) \ + : (sizeof(*(obj)) == 1 \ + ? atomic_fetch_add_explicit8( \ + obj, arg, order) \ + : atomic_add_abort())))) + +#define atomic_fetch_add(obj, arg) \ atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst) -#define atomic_fetch_sub_explicit(obj, arg, order) \ +#define atomic_fetch_sub_explicit(obj, arg, order) \ atomic_fetch_add_explicit(obj, -arg, order) -#define atomic_fetch_sub(obj, arg) \ +#define atomic_fetch_sub(obj, arg) \ atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst) +#define atomic_fetch_and_explicit8(obj, arg, order) \ + InterlockedAnd8((atomic_int_fast8_t *)obj, arg) + +#define atomic_fetch_and_explicit16(obj, arg, order) \ + InterlockedAnd16((atomic_short *)obj, arg) + +#define atomic_fetch_and_explicit32(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedAndNoFence((atomic_int_fast32_t *)obj, arg) \ + : (order == memory_order_acquire \ + ? InterlockedAndAcquire( \ + (atomic_int_fast32_t *)obj, arg) \ + : (order == memory_order_release \ + ? InterlockedAndRelease( \ + (atomic_int_fast32_t *)obj, \ + arg) \ + : InterlockedAnd( \ + (atomic_int_fast32_t *)obj, \ + arg)))) + +#ifdef _WIN64 +#define atomic_fetch_and_explicit64(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedAnd64NoFence((atomic_int_fast64_t *)obj, arg) \ + : (order == memory_order_acquire \ + ? InterlockedAnd64Acquire( \ + (atomic_int_fast64_t *)obj, arg) \ + : (order == memory_order_release \ + ? InterlockedAnd64Release( \ + (atomic_int_fast64_t *)obj, \ + arg) \ + : InterlockedAnd64( \ + (atomic_int_fast64_t *)obj, \ + arg)))) +#else /* ifdef _WIN64 */ +#define atomic_fetch_and_explicit64(obj, arg, order) \ + InterlockedAnd64((atomic_int_fast64_t *)obj, arg) +#endif /* ifdef _WIN64 */ + +static inline int8_t +atomic_and_abort() { + INSIST(0); + ISC_UNREACHABLE(); +} + +#define atomic_fetch_and_explicit(obj, arg, order) \ + (sizeof(*(obj)) == 8 \ + ? atomic_fetch_and_explicit64(obj, arg, order) \ + : (sizeof(*(obj)) == 4 \ + ? atomic_fetch_and_explicit32(obj, arg, order) \ + : (sizeof(*(obj)) == 2 \ + ? atomic_fetch_and_explicit16(obj, arg, \ + order) \ + : (sizeof(*(obj)) == 1 \ + ? atomic_fetch_and_explicit8( \ + obj, arg, order) \ + : atomic_and_abort())))) + +#define atomic_fetch_and(obj, arg) \ + atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst) + +#define atomic_fetch_or_explicit8(obj, arg, order) \ + InterlockedOr8((atomic_int_fast8_t *)obj, arg) + +#define atomic_fetch_or_explicit16(obj, arg, order) \ + InterlockedOr16((atomic_short *)obj, arg) + +#define atomic_fetch_or_explicit32(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedOrNoFence((atomic_int_fast32_t *)obj, arg) \ + : (order == memory_order_acquire \ + ? InterlockedOrAcquire((atomic_int_fast32_t *)obj, \ + arg) \ + : (order == memory_order_release \ + ? InterlockedOrRelease( \ + (atomic_int_fast32_t *)obj, \ + arg) \ + : InterlockedOr( \ + (atomic_int_fast32_t *)obj, \ + arg)))) + +#ifdef _WIN64 +#define atomic_fetch_or_explicit64(obj, arg, order) \ + (order == memory_order_relaxed \ + ? InterlockedOr64NoFence((atomic_int_fast64_t *)obj, arg) \ + : (order == memory_order_acquire \ + ? InterlockedOr64Acquire( \ + (atomic_int_fast64_t *)obj, arg) \ + : (order == memory_order_release \ + ? InterlockedOr64Release( \ + (atomic_int_fast64_t *)obj, \ + arg) \ + : InterlockedOr64( \ + (atomic_int_fast64_t *)obj, \ + arg)))) +#else /* ifdef _WIN64 */ +#define atomic_fetch_or_explicit64(obj, arg, order) \ + InterlockedOr64((atomic_int_fast64_t *)obj, arg) +#endif /* ifdef _WIN64 */ + +static inline int8_t +atomic_or_abort() { + INSIST(0); + ISC_UNREACHABLE(); +} + +#define atomic_fetch_or_explicit(obj, arg, order) \ + (sizeof(*(obj)) == 8 \ + ? atomic_fetch_or_explicit64(obj, arg, order) \ + : (sizeof(*(obj)) == 4 \ + ? atomic_fetch_or_explicit32(obj, arg, order) \ + : (sizeof(*(obj)) == 2 \ + ? atomic_fetch_or_explicit16(obj, arg, \ + order) \ + : (sizeof(*(obj)) == 1 \ + ? atomic_fetch_or_explicit8( \ + obj, arg, order) \ + : atomic_or_abort())))) + +#define atomic_fetch_or(obj, arg) \ + atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst) + static inline bool atomic_compare_exchange_strong_explicit8(atomic_int_fast8_t *obj, - int8_t *expected, - int8_t desired, - memory_order succ, - memory_order fail) -{ - bool __r; + int8_t *expected, int8_t desired, + memory_order succ, memory_order fail) { + bool __r; int8_t __v; - REQUIRE(succ == fail); - __v = InterlockedCompareExchange8((atomic_int_fast8_t *)obj, desired, *expected); + + UNUSED(succ); + UNUSED(fail); + + __v = InterlockedCompareExchange8((atomic_int_fast8_t *)obj, desired, + *expected); + __r = (*(expected) == __v); + if (!__r) { + *(expected) = __v; + } + return (__r); +} + +static inline bool +atomic_compare_exchange_strong_explicit16(atomic_short *obj, short *expected, + short desired, memory_order succ, + memory_order fail) { + bool __r; + short __v; + + UNUSED(succ); + UNUSED(fail); + + __v = InterlockedCompareExchange16((atomic_short *)obj, desired, + *expected); __r = (*(expected) == __v); if (!__r) { *(expected) = __v; @@ -233,25 +465,31 @@ atomic_compare_exchange_strong_explicit8(atomic_int_fast8_t *obj, static inline bool atomic_compare_exchange_strong_explicit32(atomic_int_fast32_t *obj, - int32_t *expected, - int32_t desired, + int32_t *expected, int32_t desired, memory_order succ, memory_order fail) { - bool __r; + bool __r; int32_t __v; - REQUIRE(succ == fail); + + UNUSED(succ); + UNUSED(fail); + switch (succ) { case memory_order_relaxed: - __v = InterlockedCompareExchangeNoFence((atomic_int_fast32_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeNoFence( + (atomic_int_fast32_t *)obj, desired, *expected); break; case memory_order_acquire: - __v = InterlockedCompareExchangeAcquire((atomic_int_fast32_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeAcquire( + (atomic_int_fast32_t *)obj, desired, *expected); break; case memory_order_release: - __v = InterlockedCompareExchangeRelease((atomic_int_fast32_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeRelease( + (atomic_int_fast32_t *)obj, desired, *expected); break; default: - __v = InterlockedCompareExchange((atomic_int_fast32_t *)obj, desired, *expected); + __v = InterlockedCompareExchange((atomic_int_fast32_t *)obj, + desired, *expected); break; } __r = (*(expected) == __v); @@ -263,31 +501,38 @@ atomic_compare_exchange_strong_explicit32(atomic_int_fast32_t *obj, static inline bool atomic_compare_exchange_strong_explicit64(atomic_int_fast64_t *obj, - int64_t *expected, - int64_t desired, + int64_t *expected, int64_t desired, memory_order succ, memory_order fail) { - bool __r; + bool __r; int64_t __v; - REQUIRE(succ == fail); + + UNUSED(succ); + UNUSED(fail); + #ifdef _WIN64 switch (succ) { case memory_order_relaxed: - __v = InterlockedCompareExchangeNoFence64((atomic_int_fast64_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeNoFence64( + (atomic_int_fast64_t *)obj, desired, *expected); break; case memory_order_acquire: - __v = InterlockedCompareExchangeAcquire64((atomic_int_fast64_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeAcquire64( + (atomic_int_fast64_t *)obj, desired, *expected); break; case memory_order_release: - __v = InterlockedCompareExchangeRelease64((atomic_int_fast64_t *)obj, desired, *expected); + __v = InterlockedCompareExchangeRelease64( + (atomic_int_fast64_t *)obj, desired, *expected); break; default: - __v = InterlockedCompareExchange64((atomic_int_fast64_t *)obj, desired, *expected); + __v = InterlockedCompareExchange64((atomic_int_fast64_t *)obj, + desired, *expected); break; } -#else - __v = InterlockedCompareExchange64((atomic_int_fast64_t *)obj, desired, *expected); -#endif +#else /* ifdef _WIN64 */ + __v = InterlockedCompareExchange64((atomic_int_fast64_t *)obj, desired, + *expected); +#endif /* ifdef _WIN64 */ __r = (*(expected) == __v); if (!__r) { *(expected) = __v; @@ -295,41 +540,63 @@ atomic_compare_exchange_strong_explicit64(atomic_int_fast64_t *obj, return (__r); } -static inline -bool +static inline bool atomic_compare_exchange_abort() { INSIST(0); ISC_UNREACHABLE(); } -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, \ - succ, fail) \ - (sizeof(*(obj)) == 8 \ - ? atomic_compare_exchange_strong_explicit64(obj, expected, \ - desired, \ - succ, fail) \ - : (sizeof(*(obj)) == 4 \ - ? atomic_compare_exchange_strong_explicit32(obj, expected, \ - desired, \ - succ, fail) \ - : (sizeof(*(obj)) == 1 \ - ? atomic_compare_exchange_strong_explicit8(obj, expected, \ - desired, \ - succ, fail) \ - : atomic_compare_exchange_abort()))) - -#define atomic_compare_exchange_strong(obj, expected, desired, \ - succ, fail) \ +#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) \ + (sizeof(*(obj)) == 8 \ + ? atomic_compare_exchange_strong_explicit64( \ + obj, expected, desired, succ, fail) \ + : (sizeof(*(obj)) == 4 \ + ? atomic_compare_exchange_strong_explicit32( \ + obj, expected, desired, succ, fail) \ + : (sizeof(*(obj)) == 2 \ + ? atomic_compare_exchange_strong_explicit16( \ + obj, expected, desired, succ, \ + fail) \ + : (sizeof(*(obj)) == 1 \ + ? atomic_compare_exchange_strong_explicit8( \ + obj, expected, \ + desired, succ, \ + fail) \ + : atomic_compare_exchange_abort())))) + +#define atomic_compare_exchange_strong(obj, expected, desired) \ atomic_compare_exchange_strong_explicit(obj, expected, desired, \ - memory_order_seq_cst, \ + memory_order_seq_cst, \ memory_order_seq_cst) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, \ - succ, fail) \ - atomic_compare_exchange_strong_explicit(obj, expected, desired, \ - succ, fail) +#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ + fail) \ + atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ + fail) -#define atomic_compare_exchange_weak(obj, expected, desired) \ - atomic_compare_exchange_weak_explicit(obj, expected, desired, \ - memory_order_seq_cst, \ +#define atomic_compare_exchange_weak(obj, expected, desired) \ + atomic_compare_exchange_weak_explicit(obj, expected, desired, \ + memory_order_seq_cst, \ memory_order_seq_cst) + +static inline bool +atomic_exchange_abort() { + INSIST(0); + ISC_UNREACHABLE(); +} + +#define atomic_exchange_explicit(obj, desired, order) \ + (sizeof(*(obj)) == 8 \ + ? InterlockedExchange64(obj, desired) \ + : (sizeof(*(obj)) == 4 \ + ? InterlockedExchange(obj, desired) \ + : (sizeof(*(obj)) == 2 \ + ? InterlockedExchange16(obj, desired) \ + : (sizeof(*(obj)) == 1 \ + ? InterlockedExchange8( \ + obj, desired) \ + : atomic_exchange_abort())))) + +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) diff --git a/lib/isc/win32/include/isc/stdtime.h b/lib/isc/win32/include/isc/stdtime.h index 9ad2e99d..b5875c48 100644 --- a/lib/isc/win32/include/isc/stdtime.h +++ b/lib/isc/win32/include/isc/stdtime.h @@ -3,18 +3,19 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_STDTIME_H #define ISC_STDTIME_H 1 -#include <isc/lang.h> #include <inttypes.h> +#include <stdlib.h> + +#include <isc/lang.h> /* * It's public information that 'isc_stdtime_t' is an unsigned integral type. @@ -35,6 +36,20 @@ isc_stdtime_get(isc_stdtime_t *t); * 't' is a valid pointer. */ +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen); +/* + * Convert 't' into a null-terminated string of the form + * "Wed Jun 30 21:49:08 1993". Store the string in the 'out' + * buffer. + * + * Requires: + * + * 't' is a valid time. + * 'out' is a valid pointer. + * 'outlen' is at least 26. + */ + #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. diff --git a/lib/isc/win32/include/isc/syslog.h b/lib/isc/win32/include/isc/syslog.h index 66431e5c..2839148d 100644 --- a/lib/isc/win32/include/isc/syslog.h +++ b/lib/isc/win32/include/isc/syslog.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_SYSLOG_H #define ISC_SYSLOG_H 1 diff --git a/lib/isc/win32/include/isc/thread.h b/lib/isc/win32/include/isc/thread.h index 25b83af0..d689eac4 100644 --- a/lib/isc/win32/include/isc/thread.h +++ b/lib/isc/win32/include/isc/thread.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_THREAD_H #define ISC_THREAD_H 1 @@ -23,54 +22,58 @@ */ /* check handle for NULL and INVALID_HANDLE */ -inline BOOL IsValidHandle( HANDLE hHandle) { - return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE)); +inline BOOL +IsValidHandle(HANDLE hHandle) { + return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE)); } /* validate wait return codes... */ -inline BOOL WaitSucceeded( DWORD dwWaitResult, DWORD dwHandleCount) { - return ((dwWaitResult >= WAIT_OBJECT_0) && - (dwWaitResult < WAIT_OBJECT_0 + dwHandleCount)); +inline BOOL +WaitSucceeded(DWORD dwWaitResult, DWORD dwHandleCount) { + return ((dwWaitResult >= WAIT_OBJECT_0) && + (dwWaitResult < WAIT_OBJECT_0 + dwHandleCount)); } -inline BOOL WaitAbandoned( DWORD dwWaitResult, DWORD dwHandleCount) { - return ((dwWaitResult >= WAIT_ABANDONED_0) && - (dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount)); +inline BOOL +WaitAbandoned(DWORD dwWaitResult, DWORD dwHandleCount) { + return ((dwWaitResult >= WAIT_ABANDONED_0) && + (dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount)); } -inline BOOL WaitTimeout( DWORD dwWaitResult) { - return (dwWaitResult == WAIT_TIMEOUT); +inline BOOL +WaitTimeout(DWORD dwWaitResult) { + return (dwWaitResult == WAIT_TIMEOUT); } -inline BOOL WaitFailed( DWORD dwWaitResult) { - return (dwWaitResult == WAIT_FAILED); +inline BOOL +WaitFailed(DWORD dwWaitResult) { + return (dwWaitResult == WAIT_FAILED); } /* compute object indices for waits... */ -inline DWORD WaitSucceededIndex( DWORD dwWaitResult) { - return (dwWaitResult - WAIT_OBJECT_0); +inline DWORD +WaitSucceededIndex(DWORD dwWaitResult) { + return (dwWaitResult - WAIT_OBJECT_0); } -inline DWORD WaitAbandonedIndex( DWORD dwWaitResult) { - return (dwWaitResult - WAIT_ABANDONED_0); +inline DWORD +WaitAbandonedIndex(DWORD dwWaitResult) { + return (dwWaitResult - WAIT_ABANDONED_0); } - - typedef HANDLE isc_thread_t; -typedef DWORD isc_threadresult_t; +typedef DWORD isc_threadresult_t; typedef void * isc_threadarg_t; -typedef isc_threadresult_t (WINAPI *isc_threadfunc_t)(isc_threadarg_t); -typedef DWORD isc_thread_key_t; +typedef isc_threadresult_t(WINAPI *isc_threadfunc_t)(isc_threadarg_t); #define isc_thread_self (unsigned long)GetCurrentThreadId ISC_LANG_BEGINDECLS -isc_result_t +void isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *); -isc_result_t +void isc_thread_join(isc_thread_t, isc_threadresult_t *); void @@ -82,20 +85,14 @@ isc_thread_setname(isc_thread_t, const char *); isc_result_t isc_thread_setaffinity(int cpu); -int -isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)); - -int -isc_thread_key_delete(isc_thread_key_t key); - -void * -isc_thread_key_getspecific(isc_thread_key_t); - -int -isc_thread_key_setspecific(isc_thread_key_t key, void *value); - #define isc_thread_yield() Sleep(0) +#if HAVE___DECLSPEC_THREAD +#define ISC_THREAD_LOCAL static __declspec(thread) +#else /* if HAVE___DECLSPEC_THREAD */ +#error "Thread-local storage support is required!" +#endif /* if HAVE___DECLSPEC_THREAD */ + ISC_LANG_ENDDECLS #endif /* ISC_THREAD_H */ diff --git a/lib/isc/win32/include/isc/time.h b/lib/isc/win32/include/isc/time.h index 25406d24..71fda164 100644 --- a/lib/isc/win32/include/isc/time.h +++ b/lib/isc/win32/include/isc/time.h @@ -3,24 +3,49 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_TIME_H #define ISC_TIME_H 1 +#include <errno.h> #include <inttypes.h> #include <stdbool.h> +#include <time.h> #include <windows.h> #include <isc/lang.h> #include <isc/types.h> /*** + *** POSIX Shims + ***/ + +inline struct tm * +gmtime_r(const time_t *clock, struct tm *result) { + errno_t ret = gmtime_s(result, clock); + if (ret != 0) { + errno = ret; + return (NULL); + } + return (result); +} + +inline struct tm * +localtime_r(const time_t *clock, struct tm *result) { + errno_t ret = localtime_s(result, clock); + if (ret != 0) { + errno = ret; + return (NULL); + } + return (result); +} + +/*** *** Intervals ***/ @@ -34,7 +59,7 @@ struct isc_interval { int64_t interval; }; -LIBISC_EXTERNAL_DATA extern const isc_interval_t * const isc_interval_zero; +LIBISC_EXTERNAL_DATA extern const isc_interval_t *const isc_interval_zero; /* * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially @@ -46,8 +71,8 @@ LIBISC_EXTERNAL_DATA extern const isc_interval_t * const isc_interval_zero; ISC_LANG_BEGINDECLS void -isc_interval_set(isc_interval_t *i, - unsigned int seconds, unsigned int nanoseconds); +isc_interval_set(isc_interval_t *i, unsigned int seconds, + unsigned int nanoseconds); /* * Set 'i' to a value representing an interval of 'seconds' seconds and * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and @@ -84,7 +109,7 @@ struct isc_time { FILETIME absolute; }; -LIBISC_EXTERNAL_DATA extern const isc_time_t * const isc_time_epoch; +LIBISC_EXTERNAL_DATA extern const isc_time_t *const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); @@ -320,6 +345,20 @@ isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len); */ void +isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssss" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + +void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', @@ -348,10 +387,24 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len); */ void +isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssssZ" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + +void isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', - * using the format "yyyymmddhhmmsssss" userful for file timestamping. + * using the format "yyyymmddhhmmsssss" useful for file timestamping. * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * diff --git a/lib/isc/win32/include/isc/win32os.h b/lib/isc/win32/include/isc/win32os.h index bc18c403..3a97ddc9 100644 --- a/lib/isc/win32/include/isc/win32os.h +++ b/lib/isc/win32/include/isc/win32os.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef ISC_WIN32OS_H #define ISC_WIN32OS_H 1 @@ -24,7 +23,7 @@ ISC_LANG_BEGINDECLS int isc_win32os_versioncheck(unsigned int major, unsigned int minor, - unsigned int updatemajor, unsigned int updateminor); + unsigned int updatemajor, unsigned int updateminor); /* * Checks the current version of the operating system with the diff --git a/lib/isc/win32/include/pkcs11/Makefile.in b/lib/isc/win32/include/pkcs11/Makefile.in deleted file mode 100644 index e9a85d43..00000000 --- a/lib/isc/win32/include/pkcs11/Makefile.in +++ /dev/null @@ -1,26 +0,0 @@ -# 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 http://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -HEADERS = cryptoki.h -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/pkcs11 || exit 1; \ - done diff --git a/lib/isc/win32/include/pkcs11/cryptoki.h b/lib/isc/win32/include/pkcs11/cryptoki.h deleted file mode 100644 index 2a681c49..00000000 --- a/lib/isc/win32/include/pkcs11/cryptoki.h +++ /dev/null @@ -1,66 +0,0 @@ -/* cryptoki.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This is a sample file containing the top level include directives
- * for building Win32 Cryptoki libraries and applications.
- */
-
-#ifndef ___CRYPTOKI_H_INC___
-#define ___CRYPTOKI_H_INC___
-
-#pragma pack(push, cryptoki, 1)
-
-/* Specifies that the function is a DLL entry point. */
-#define CK_IMPORT_SPEC __declspec(dllimport)
-
-/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
- * not define it in applications.
- */
-#ifdef CRYPTOKI_EXPORTS
-/* Specified that the function is an exported DLL entry point. */
-#define CK_EXPORT_SPEC __declspec(dllexport)
-#else
-#define CK_EXPORT_SPEC CK_IMPORT_SPEC
-#endif
-
-/* Ensures the calling convention for Win32 builds */
-#define CK_CALL_SPEC __cdecl
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
- returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
- returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
- returnType (CK_CALL_SPEC CK_PTR name)
-
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#include <pkcs11/pkcs11.h>
-
-#pragma pack(pop, cryptoki)
-
-#endif /* ___CRYPTOKI_H_INC___ */
diff --git a/lib/isc/win32/interfaceiter.c b/lib/isc/win32/interfaceiter.c index 6884221b..f11ebd71 100644 --- a/lib/isc/win32/interfaceiter.c +++ b/lib/isc/win32/interfaceiter.c @@ -3,27 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /* * Note that this code will need to be revisited to support IPv6 Interfaces. * For now we just iterate through IPv4 interfaces. */ - -#include <config.h> -#include <winsock2.h> -#include <ws2tcpip.h> -#include <sys/types.h> - +#include <errno.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> -#include <errno.h> +#include <sys/types.h> +#include <winsock2.h> +#include <ws2tcpip.h> #include <isc/interfaceiter.h> #include <isc/mem.h> @@ -34,7 +30,8 @@ #include <isc/types.h> #include <isc/util.h> -void InitSockets(void); +void +InitSockets(void); /* Common utility functions */ @@ -47,53 +44,50 @@ void InitSockets(void); * not have a valid address family). */ - -#define IFITER_MAGIC 0x49464954U /* IFIT. */ -#define VALID_IFITER(t) ((t) != NULL && (t)->magic == IFITER_MAGIC) +#define IFITER_MAGIC 0x49464954U /* IFIT. */ +#define VALID_IFITER(t) ((t) != NULL && (t)->magic == IFITER_MAGIC) struct isc_interfaceiter { - unsigned int magic; /* Magic number. */ - isc_mem_t *mctx; - SOCKET socket; - INTERFACE_INFO IFData; /* Current Interface Info. */ - int numIF; /* Current Interface count. */ - int v4IF; /* Number of IPv4 Interfaces */ - INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */ - unsigned int buf4size; /* Bytes allocated. */ - INTERFACE_INFO *pos4; /* Current offset in IF List */ - SOCKET_ADDRESS_LIST *buf6; /* Buffer for WSAIoctl data. */ - unsigned int buf6size; /* Bytes allocated. */ - unsigned int pos6; /* Which entry to process. */ - bool v6loop; /* See IPv6 loop address. */ - bool pos6zero; /* Done pos6 == 0. */ - isc_interface_t current; /* Current interface data. */ - isc_result_t result; /* Last result code. */ + unsigned int magic; /* Magic number. */ + isc_mem_t *mctx; + SOCKET socket; + INTERFACE_INFO IFData; /* Current Interface Info. */ + int numIF; /* Current Interface count. */ + int v4IF; /* Number of IPv4 Interfaces */ + INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */ + unsigned int buf4size; /* Bytes allocated. */ + INTERFACE_INFO *pos4; /* Current offset in IF List */ + SOCKET_ADDRESS_LIST *buf6; /* Buffer for WSAIoctl data. */ + unsigned int buf6size; /* Bytes allocated. */ + unsigned int pos6; /* Which entry to process. */ + bool v6loop; /* See IPv6 loop address. */ + bool pos6zero; /* Done pos6 == 0. */ + isc_interface_t current; /* Current interface data. */ + isc_result_t result; /* Last result code. */ }; - /* * Size of buffer for SIO_GET_INTERFACE_LIST, in number of interfaces. * We assume no sane system will have more than than 1K of IP addresses on * all of its adapters. */ -#define IFCONF_SIZE_INITIAL 16 -#define IFCONF_SIZE_INCREMENT 64 -#define IFCONF_SIZE_MAX 1040 +#define IFCONF_SIZE_INITIAL 16 +#define IFCONF_SIZE_INCREMENT 64 +#define IFCONF_SIZE_MAX 1040 static void get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) { dst->family = family; switch (family) { case AF_INET: - memmove(&dst->type.in, - &((struct sockaddr_in *) src)->sin_addr, + memmove(&dst->type.in, &((struct sockaddr_in *)src)->sin_addr, sizeof(struct in_addr)); break; - case AF_INET6: + case AF_INET6: memmove(&dst->type.in6, - &((struct sockaddr_in6 *) src)->sin6_addr, + &((struct sockaddr_in6 *)src)->sin6_addr, sizeof(struct in6_addr)); - dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id; + dst->zone = ((struct sockaddr_in6 *)src)->sin6_scope_id; break; default: INSIST(0); @@ -114,8 +108,6 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); - if (iter == NULL) - return (ISC_R_NOMEMORY); InitSockets(); @@ -139,12 +131,12 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { iter->socket = socket(AF_INET, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); - if (error == WSAEAFNOSUPPORT) + if (error == WSAEAFNOSUPPORT) { goto inet6_only; + } strerror_r(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "making interface scan socket: %s", - strbuf); + "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } @@ -153,26 +145,23 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { * Get the interface configuration, allocating more memory if * necessary. */ - iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO); + iter->buf4size = IFCONF_SIZE_INITIAL * sizeof(INTERFACE_INFO); for (;;) { iter->buf4 = isc_mem_get(mctx, iter->buf4size); - if (iter->buf4 == NULL) { - result = ISC_R_NOMEMORY; - goto alloc_failure; - } - if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST, - 0, 0, iter->buf4, iter->buf4size, - &bytesReturned, 0, 0) == SOCKET_ERROR) + if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST, 0, 0, + iter->buf4, iter->buf4size, &bytesReturned, 0, + 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; strerror_r(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "get interface configuration: %s", - strbuf); + "get interface configuration: " + "%s", + strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } @@ -187,10 +176,12 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { * case and retry. */ if (bytesReturned > 0 && - (bytesReturned < iter->buf4size)) + (bytesReturned < iter->buf4size)) { break; + } } - if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) { + if (iter->buf4size >= IFCONF_SIZE_MAX * sizeof(INTERFACE_INFO)) + { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); @@ -200,19 +191,19 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_mem_put(mctx, iter->buf4, iter->buf4size); iter->buf4size += IFCONF_SIZE_INCREMENT * - sizeof(INTERFACE_INFO); + sizeof(INTERFACE_INFO); } /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ - iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO); + iter->v4IF = bytesReturned / sizeof(INTERFACE_INFO); /* We don't need the socket any more, so close it */ closesocket(iter->socket); - inet6_only: +inet6_only: /* * Create an unbound datagram socket to do the * SIO_ADDRESS_LIST_QUERY WSAIoctl on. @@ -220,12 +211,12 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { iter->socket = socket(AF_INET6, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); - if (error == WSAEAFNOSUPPORT) + if (error == WSAEAFNOSUPPORT) { goto inet_only; + } strerror_r(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "making interface scan socket: %s", - strbuf); + "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } @@ -235,18 +226,14 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { * necessary. */ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) + - IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS); + IFCONF_SIZE_INITIAL * sizeof(SOCKET_ADDRESS); for (;;) { iter->buf6 = isc_mem_get(mctx, iter->buf6size); - if (iter->buf6 == NULL) { - result = ISC_R_NOMEMORY; - goto ioctl_failure; - } - if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY, - 0, 0, iter->buf6, iter->buf6size, - &bytesReturned, 0, 0) == SOCKET_ERROR) + if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY, 0, 0, + iter->buf6, iter->buf6size, &bytesReturned, 0, + 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { @@ -261,10 +248,12 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { /* * EINVAL. Retry with a bigger buffer. */ - } else + } else { break; + } - if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) { + if (iter->buf6size >= IFCONF_SIZE_MAX * sizeof(SOCKET_ADDRESS)) + { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); @@ -274,28 +263,28 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_mem_put(mctx, iter->buf6, iter->buf6size); iter->buf6size += IFCONF_SIZE_INCREMENT * - sizeof(SOCKET_ADDRESS); + sizeof(SOCKET_ADDRESS); } closesocket(iter->socket); - inet_only: +inet_only: iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); - ioctl6_failure: +ioctl6_failure: isc_mem_put(mctx, iter->buf6, iter->buf6size); - ioctl_failure: - if (iter->buf4 != NULL) +ioctl_failure: + if (iter->buf4 != NULL) { isc_mem_put(mctx, iter->buf4, iter->buf4size); + } + if (iter->socket != INVALID_SOCKET) { + (void)closesocket(iter->socket); + } - alloc_failure: - if (iter->socket != INVALID_SOCKET) - (void) closesocket(iter->socket); - - socket_failure: +socket_failure: isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } @@ -329,8 +318,9 @@ internal_current(isc_interfaceiter_t *iter) { iter->current.flags = 0; flags = iter->IFData.iiFlags; - if ((flags & IFF_UP) != 0) + if ((flags & IFF_UP) != 0) { iter->current.flags |= INTERFACE_F_UP; + } if ((flags & IFF_POINTTOPOINT) != 0) { iter->current.flags |= INTERFACE_F_POINTTOPOINT; @@ -351,12 +341,13 @@ internal_current(isc_interfaceiter_t *iter) { */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { get_addr(AF_INET, &iter->current.dstaddress, - (struct sockaddr *)&(iter->IFData.iiBroadcastAddress)); + (struct sockaddr *)&(iter->IFData.iiBroadcastAddress)); } - if (ifNamed == FALSE) + if (ifNamed == FALSE) { snprintf(iter->current.name, sizeof(iter->current.name), - "TCP/IP Interface %d", iter->numIF); + "TCP/IP Interface %d", iter->numIF); + } /* * Get the network mask. @@ -379,8 +370,9 @@ internal_current6(isc_interfaceiter_t *iter) { iter->current.af = AF_INET6; if (!iter->pos6zero) { - if (iter->pos6 == 0U) + if (iter->pos6 == 0U) { iter->pos6zero = true; + } get_addr(AF_INET6, &iter->current.address, iter->buf6->Address[iter->pos6].lpSockaddr); @@ -396,19 +388,21 @@ internal_current6(isc_interfaceiter_t *iter) { for (i = 0; i < 16; i++) iter->current.netmask.type.in6.s6_addr[i] = 0xff; iter->current.netmask.family = AF_INET6; - if (IN6_IS_ADDR_LOOPBACK(&iter->current.address.type.in6)) - iter->v6loop = true; + if (IN6_IS_ADDR_LOOPBACK(&iter->current.address.type.in6)) { + iter->v6loop = true; + } } else { /* * See if we can bind to the ::1 and if so return ::1. */ struct sockaddr_in6 sin6; - iter->v6loop = true; /* So we don't loop forever. */ + iter->v6loop = true; /* So we don't loop forever. */ fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd == INVALID_SOCKET) + if (fd == INVALID_SOCKET) { return (ISC_R_IGNORE); + } memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr.s6_addr[15] = 1; @@ -420,12 +414,13 @@ internal_current6(isc_interfaceiter_t *iter) { iter->current.flags = INTERFACE_F_UP | INTERFACE_F_LOOPBACK; snprintf(iter->current.name, sizeof(iter->current.name), - "TCP/IPv6 Loopback Interface"); + "TCP/IPv6 Loopback Interface"); for (i = 0; i < 16; i++) { - if (i != 15) + if (i != 15) { iter->current.address.type.in6.s6_addr[i] = 0; - else + } else { iter->current.address.type.in6.s6_addr[i] = 1; + } iter->current.netmask.type.in6.s6_addr[i] = 0xff; } iter->current.address.family = AF_INET6; @@ -443,8 +438,9 @@ internal_current6(isc_interfaceiter_t *iter) { */ static isc_result_t internal_next(isc_interfaceiter_t *iter) { - if (iter->numIF >= iter->v4IF) + if (iter->numIF >= iter->v4IF) { return (ISC_R_NOMORE); + } /* * The first one needs to be set up to point to the last @@ -453,12 +449,14 @@ internal_next(isc_interfaceiter_t *iter) { * the list in reverse order */ - if (iter->numIF == 0) + if (iter->numIF == 0) { iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF)); + } iter->pos4--; - if (&(iter->pos4) < &(iter->buf4)) + if (&(iter->pos4) < &(iter->buf4)) { return (ISC_R_NOMORE); + } memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO)); memmove(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO)); @@ -469,16 +467,17 @@ internal_next(isc_interfaceiter_t *iter) { static isc_result_t internal_next6(isc_interfaceiter_t *iter) { - if (iter->pos6 == 0U && iter->v6loop) + if (iter->pos6 == 0U && iter->v6loop) { return (ISC_R_NOMORE); - if (iter->pos6 != 0U) + } + if (iter->pos6 != 0U) { iter->pos6--; + } return (ISC_R_SUCCESS); } isc_result_t -isc_interfaceiter_current(isc_interfaceiter_t *iter, - isc_interface_t *ifdata) { +isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata) { REQUIRE(iter->result == ISC_R_SUCCESS); memmove(ifdata, &iter->current, sizeof(*ifdata)); return (ISC_R_SUCCESS); @@ -486,7 +485,6 @@ isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { - REQUIRE(VALID_IFITER(iter)); if (iter->buf6 != NULL) { @@ -509,17 +507,21 @@ isc_interfaceiter_next(isc_interfaceiter_t *iter) { result = internal_next(iter); if (result == ISC_R_NOMORE) { result = internal_next6(iter); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { break; + } result = internal_current6(iter); - if (result == ISC_R_IGNORE) + if (result == ISC_R_IGNORE) { continue; + } break; - } else if (result != ISC_R_SUCCESS) + } else if (result != ISC_R_SUCCESS) { break; + } result = internal_current(iter); - if (result != ISC_R_IGNORE) + if (result != ISC_R_IGNORE) { break; + } } iter->result = result; return (result); @@ -530,14 +532,16 @@ isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; + *iterp = NULL; REQUIRE(VALID_IFITER(iter)); - if (iter->buf4 != NULL) + if (iter->buf4 != NULL) { isc_mem_put(iter->mctx, iter->buf4, iter->buf4size); - if (iter->buf6 != NULL) + } + if (iter->buf6 != NULL) { isc_mem_put(iter->mctx, iter->buf6, iter->buf6size); + } iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); - *iterp = NULL; } diff --git a/lib/isc/win32/ipv6.c b/lib/isc/win32/ipv6.c index 3e0eb37e..ad93c122 100644 --- a/lib/isc/win32/ipv6.c +++ b/lib/isc/win32/ipv6.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <isc/net.h> #include <isc/platform.h> diff --git a/lib/isc/win32/libgen.h b/lib/isc/win32/libgen.h index e74740f6..227fd187 100644 --- a/lib/isc/win32/libgen.h +++ b/lib/isc/win32/libgen.h @@ -3,17 +3,18 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef LIBGEN_H #define LIBGEN_H 1 -char *basename(const char *); -char *dirname(const char *); +char * +basename(const char *); +char * +dirname(const char *); -#endif +#endif /* ifndef LIBGEN_H */ diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 4b66b3c9..fd67ae8e 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -24,9 +24,10 @@ isc_app_start isc_app_unblock isc_appctx_create isc_appctx_destroy -isc_appctx_setsocketmgr -isc_appctx_settaskmgr -isc_appctx_settimermgr +isc_astack_destroy +isc_astack_new +isc_astack_pop +isc_astack_trypush isc__buffer_activeregion isc__buffer_add isc__buffer_availableregion @@ -60,6 +61,12 @@ isc__mem_reallocate isc__mem_strdup isc__mempool_get isc__mempool_put +isc__md_md5 +isc__md_sha1 +isc__md_sha224 +isc__md_sha256 +isc__md_sha384 +isc__md_sha512 isc_socket_accept isc_socket_attach isc_socket_bind @@ -121,9 +128,6 @@ isc_app_start isc_app_unblock isc_appctx_create isc_appctx_destroy -isc_appctx_setsocketmgr -isc_appctx_settaskmgr -isc_appctx_settimermgr isc_assertion_failed isc_assertion_setcallback isc_assertion_typetotext @@ -234,8 +238,8 @@ isc_fsaccess_add isc_fsaccess_changeowner isc_fsaccess_remove isc_fsaccess_set -isc_hash_function -isc_hash_function_reverse +isc_hash32 +isc_hash64 isc_hash_get_initializer isc_hash_set_initializer isc_heap_create @@ -249,6 +253,15 @@ isc_heap_insert isc_hex_decodestring isc_hex_tobuffer isc_hex_totext +isc_hp_clear +isc_hp_clear_one +isc_hp_destroy +isc_hp_init +isc_hp_protect +isc_hp_protect_ptr +isc_hp_protect_release +isc_hp_new +isc_hp_retire isc_hmac isc_hmac_new isc_hmac_free @@ -259,6 +272,13 @@ isc_hmac_final isc_hmac_get_md_type isc_hmac_get_size isc_hmac_get_block_size +isc_hp_new +isc_hp_destroy +isc_hp_clear +isc_hp_protect +isc_hp_protect_ptr +isc_hp_protect_release +isc_hp_retire isc_ht_add isc_ht_count isc_ht_delete @@ -274,6 +294,7 @@ isc_ht_iter_first isc_ht_iter_next isc_httpd_addheader isc_httpd_addheaderuint +isc_httpd_endheaders isc_httpd_response isc_httpd_setfinishhook isc_httpdmgr_addurl @@ -337,7 +358,6 @@ isc_log_write isc_log_write1 isc_logconfig_create isc_logconfig_destroy -isc_logconfig_get isc_logconfig_use isc_logfile_roll isc_md_new @@ -355,7 +375,6 @@ isc_md isc_mem_attach isc_mem_checkdestroyed isc_mem_create -isc_mem_createx isc_mem_destroy isc_mem_detach isc_mem_getname @@ -425,6 +444,40 @@ isc_netaddr_setzone isc_netaddr_totext isc_netaddr_unspec isc_netscope_pton +isc_nmhandle_attach +isc_nmhandle_detach +isc_nmhandle_getdata +isc_nmhandle_getextra +isc_nmhandle_is_stream +isc_nmhandle_netmgr +isc_nmhandle_localaddr +isc_nmhandle_peeraddr +isc_nmhandle_setdata +isc_nm_cancelread +isc_nm_closedown +isc_nm_destroy +isc_nm_detach +isc_nm_listentcpdns +isc_nm_listentcp +isc_nm_listenudp +isc_nm_maxudp +isc_nm_pauseread +isc_nm_read +isc_nm_resumeread +isc_nm_send +isc_nm_setstats +isc_nm_start +isc_nm_stoplistening +isc_nm_tcpconnect +isc_nm_tcp_gettimeouts +isc_nm_tcp_settimeouts +isc_nm_tcpdns_keepalive +isc_nm_tcpdns_sequential +isc_nm_tid +isc_nmsocket_close +isc__nm_acquire_interlocked +isc__nm_drop_interlocked +isc__nm_acquire_interlocked_force isc_nonce_buf isc_ntpaths_get isc_ntpaths_init @@ -446,17 +499,20 @@ isc_portset_isset isc_portset_nports isc_portset_remove isc_portset_removerange +isc_queue_enqueue +isc_queue_dequeue +isc_queue_destroy +isc_queue_new isc_quota_attach +isc_quota_attach_cb +isc_quota_cb_init isc_quota_destroy isc_quota_detach -isc_quota_force isc_quota_getmax isc_quota_getsoft isc_quota_getused isc_quota_init isc_quota_max -isc_quota_release -isc_quota_reserve isc_quota_soft isc_radix_create isc_radix_destroy @@ -496,12 +552,16 @@ isc_rwlock_lock isc_rwlock_trylock isc_rwlock_tryupgrade isc_rwlock_unlock +isc_safe_memequal +isc_safe_memwipe isc_serial_eq isc_serial_ge isc_serial_gt isc_serial_le isc_serial_lt isc_serial_ne +isc_halfsiphash24 +isc_siphash24 isc_sockaddr_any isc_sockaddr_any6 isc_sockaddr_anyofpf @@ -514,6 +574,7 @@ isc_sockaddr_fromin isc_sockaddr_fromin6 isc_sockaddr_fromnetaddr isc_sockaddr_frompath +isc_sockaddr_fromsockaddr isc_sockaddr_getport isc_sockaddr_hash isc_sockaddr_isexperimental @@ -539,9 +600,11 @@ isc_stats_create isc_stats_decrement isc_stats_detach isc_stats_dump +isc_stats_get_counter isc_stats_increment isc_stats_ncounters isc_stats_set +isc_stats_update_if_greater isc_stdio_close isc_stdio_flush isc_stdio_open @@ -551,6 +614,7 @@ isc_stdio_sync isc_stdio_tell isc_stdio_write isc_stdtime_get +isc_stdtime_tostring isc_string_strerror_r isc_symtab_count isc_symtab_create @@ -570,6 +634,7 @@ isc_task_exiting isc_task_getcurrenttime isc_task_getcurrenttimex isc_task_onshutdown +isc_task_pause isc_task_privilege isc_task_purge isc_task_purgeevent @@ -581,6 +646,7 @@ isc_task_sendtoanddetach isc_task_setname isc_task_setprivilege isc_task_shutdown +isc_task_unpause isc_task_unsend isc_taskmgr_create isc_taskmgr_createinctx @@ -603,17 +669,17 @@ isc_taskpool_setprivilege isc_taskpool_size isc_thread_create isc_thread_join -isc_thread_key_create -isc_thread_key_delete -isc_thread_key_getspecific -isc_thread_key_setspecific isc_thread_setaffinity isc_thread_setconcurrency isc_thread_setname isc_time_add isc_time_compare isc_time_formatISO8601 +isc_time_formatISO8601L +isc_time_formatISO8601Lms +isc_time_formatISO8601Lus isc_time_formatISO8601ms +isc_time_formatISO8601us isc_time_formathttptimestamp isc_time_formatshorttimestamp isc_time_formattimestamp @@ -640,6 +706,8 @@ isc_timermgr_destroy isc_timermgr_poke isc_tm_timegm isc_tm_strptime +isc_utf8_bom +isc_utf8_valid isc_win32os_versioncheck openlog @IF PKCS11 diff --git a/lib/isc/win32/libisc.vcxproj.filters.in b/lib/isc/win32/libisc.vcxproj.filters.in index b58ff4f1..e72cf040 100644 --- a/lib/isc/win32/libisc.vcxproj.filters.in +++ b/lib/isc/win32/libisc.vcxproj.filters.in @@ -35,6 +35,9 @@ <ClInclude Include="..\include\isc\assertions.h"> <Filter>Library Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\isc\astack.h"> + <Filter>Library Header Files</Filter> + </ClInclude> <ClInclude Include="..\include\isc\atomic.h"> <Filter>Library Header Files</Filter> </ClInclude> @@ -68,6 +71,9 @@ <ClInclude Include="..\include\isc\crc64.h"> <Filter>Library Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\isc\endian.h"> + <Filter>Library Header Files</Filter> + </ClInclude> <ClInclude Include="..\include\isc\errno.h"> <Filter>Library Header Files</Filter> </ClInclude> @@ -101,6 +107,9 @@ <ClInclude Include="..\include\isc\hmac.h"> <Filter>Library Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\isc\hp.h"> + <Filter>Library Header Files</Filter> + </ClInclude> <ClInclude Include="..\include\isc\ht.h"> <Filter>Library Header Files</Filter> </ClInclude> @@ -212,6 +221,9 @@ <ClInclude Include="..\include\isc\serial.h"> <Filter>Library Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\isc\siphash.h"> + <Filter>Library Header Files</Filter> + </ClInclude> <ClInclude Include="..\include\isc\sockaddr.h"> <Filter>Library Header Files</Filter> </ClInclude> @@ -251,13 +263,13 @@ <ClInclude Include="..\include\isc\types.h"> <Filter>Library Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\isc\util.h"> + <ClInclude Include="..\include\isc\utf8.h"> <Filter>Library Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\isc\version.h"> + <ClInclude Include="..\include\isc\util.h"> <Filter>Library Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\isc\xml.h"> + <ClInclude Include="..\include\isc\version.h"> <Filter>Library Header Files</Filter> </ClInclude> @IF PKCS11 @@ -276,12 +288,6 @@ <ClInclude Include="..\include\pkcs11\pkcs11.h"> <Filter>Pkcs11 Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\pkcs11\pkcs11f.h"> - <Filter>Pkcs11 Header Files</Filter> - </ClInclude> - <ClInclude Include="..\include\pkcs11\pkcs11t.h"> - <Filter>Pkcs11 Header Files</Filter> - </ClInclude> @END PKCS11 <ClInclude Include="include\isc\bind_registry.h"> <Filter>Win32 Header Files</Filter> @@ -361,11 +367,6 @@ <ClInclude Include="unistd.h"> <Filter>Win32 Header Files</Filter> </ClInclude> -@IF PKCS11 - <ClInclude Include="include\pkcs11\cryptoki.h"> - <Filter>Win32 Header Files</Filter> - </ClInclude> -@END PKCS11 <ClInclude Include="..\..\..\config.h"> <Filter>Library Header Files</Filter> </ClInclude> @@ -374,9 +375,6 @@ </ClInclude> </ItemGroup> <ItemGroup> - <ClCompile Include="app.c"> - <Filter>Win32 Source Files</Filter> - </ClCompile> <ClCompile Include="condition.c"> <Filter>Win32 Source Files</Filter> </ClCompile> @@ -454,9 +452,15 @@ <ClCompile Include="..\aes.c"> <Filter>Win32 Source Files</Filter> </ClCompile> + <ClCompile Include="..\app.c"> + <Filter>Win32 Source Files</Filter> + </ClCompile> <ClCompile Include="..\assertions.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\astack.c"> + <Filter>Library Source Files</Filter> + </ClCompile> <ClCompile Include="..\backtrace.c"> <Filter>Library Source Files</Filter> </ClCompile> @@ -508,6 +512,9 @@ <ClCompile Include="..\hmac.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\hp.c"> + <Filter>Library Source Files</Filter> + </ClCompile> <ClCompile Include="..\ht.c"> <Filter>Library Source Files</Filter> </ClCompile> @@ -556,6 +563,9 @@ <ClCompile Include="..\portset.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\queue.c"> + <Filter>Library Source Files</Filter> + </ClCompile> <ClCompile Include="..\quota.c"> <Filter>Library Source Files</Filter> </ClCompile> @@ -580,9 +590,15 @@ <ClCompile Include="..\rwlock.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\safe.c"> + <Filter>Library Source Files</Filter> + </ClCompile> <ClCompile Include="..\serial.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\siphash.c"> + <Filter>Library Source Files</Filter> + </ClCompile> <ClCompile Include="..\sockaddr.c"> <Filter>Library Source Files</Filter> </ClCompile> @@ -607,6 +623,9 @@ <ClCompile Include="..\tm.c"> <Filter>Library Source Files</Filter> </ClCompile> + <ClCompile Include="..\utf8.c"> + <Filter>Library Source Files</Filter> + </ClCompile> @IF PKCS11 <ClCompile Include="..\pk11.c"> <Filter>Library Source Files</Filter> diff --git a/lib/isc/win32/libisc.vcxproj.in b/lib/isc/win32/libisc.vcxproj.in index 01d3ba26..3221ab0c 100644 --- a/lib/isc/win32/libisc.vcxproj.in +++ b/lib/isc/win32/libisc.vcxproj.in @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="@TOOLS_VERSION@" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|@PLATFORM@"> <Configuration>Debug</Configuration> @@ -14,18 +14,21 @@ <ProjectGuid>{3840E563-D180-4761-AA9C-E6155F02EAFF}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>libisc</RootNamespace> + @WINDOWS_TARGET_PLATFORM_VERSION@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@PLATFORM@'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <CharacterSet>MultiByte</CharacterSet> + @PLATFORM_TOOLSET@ </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|@PLATFORM@'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>MultiByte</CharacterSet> + @PLATFORM_TOOLSET@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -41,24 +44,29 @@ <LinkIncremental>true</LinkIncremental> <OutDir>..\..\..\Build\$(Configuration)\</OutDir> <IntDir>.\$(Configuration)\</IntDir> + <IntDirSharingDetected>None</IntDirSharingDetected> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|@PLATFORM@'"> <LinkIncremental>false</LinkIncremental> <OutDir>..\..\..\Build\$(Configuration)\</OutDir> <IntDir>.\$(Configuration)\</IntDir> + <IntDirSharingDetected>None</IntDirSharingDetected> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@PLATFORM@'"> <ClCompile> <PrecompiledHeader> </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>false</TreatWarningAsError> <Optimization>Disabled</Optimization> @IF PKCS11 <PreprocessorDefinitions>BIND9;@PK11_LIB_LOCATION@WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles> + <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @ELSE PKCS11 <PreprocessorDefinitions>BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles> + <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @END PKCS11 <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeaderOutputFile>.\$(Configuration)\$(TargetName).pch</PrecompiledHeaderOutputFile> @@ -72,7 +80,7 @@ <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>@OPENSSL_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>@OPENSSL_LIB@@LIBUV_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile> <ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary> </Link> @@ -82,6 +90,13 @@ if NOT Exist ..\Build mkdir ..\Build if NOT Exist ..\Build\Debug mkdir ..\Build\Debug +echo Copying documentation. + +copy ..\*.md ..\Build\Debug +copy ..\CHANGES* ..\Build\Debug +copy ..\COPYRIGHT ..\Build\Debug +copy ..\LICENSE ..\Build\Debug + echo Copying COPYRIGHT notice. copy ..\COPYRIGHT ..\Build\Debug @@ -91,6 +106,9 @@ echo Copying the OpenSSL DLL and LICENSE. copy @OPENSSL_DLL@ ..\Build\Debug\ copy @OPENSSL_PATH@\LICENSE ..\Build\Debug\OpenSSL-LICENSE +echo Copying libuv DLL. +copy @LIBUV_DLL@ ..\Build\Debug\ + @IF LIBXML2 echo Copying the libxml DLL. @@ -107,12 +125,6 @@ copy @K5SPRT_DLL@ ..\Build\Debug\ copy @WSHELP_DLL@ ..\Build\Debug\ @END GSSAPI -@IF GEOIPLEGACY -echo Copying the GeoIP DLL. - -copy @GEOIP_DLL@ ..\Build\Debug\ -@END GEOIPLEGACY - @IF IDNKIT echo Copying the IDN kit DLL. @@ -140,7 +152,8 @@ copy InstallFiles ..\Build\Debug\ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|@PLATFORM@'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> + <WarningLevel>Level1</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> <PrecompiledHeader> </PrecompiledHeader> <Optimization>MaxSpeed</Optimization> @@ -148,10 +161,12 @@ copy InstallFiles ..\Build\Debug\ <IntrinsicFunctions>@INTRINSIC@</IntrinsicFunctions> @IF PKCS11 <PreprocessorDefinitions>BIND9;@PK11_LIB_LOCATION@WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles> + <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @ELSE PKCS11 <PreprocessorDefinitions>BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles> + <AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @END PKCS11 <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <WholeProgramOptimization>false</WholeProgramOptimization> @@ -168,7 +183,7 @@ copy InstallFiles ..\Build\Debug\ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>@OPENSSL_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>@OPENSSL_LIB@@LIBUV_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile> <ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary> <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> @@ -179,65 +194,21 @@ copy InstallFiles ..\Build\Debug\ if NOT Exist ..\Build mkdir ..\Build if NOT Exist ..\Build\Release mkdir ..\Build\Release -echo Copying the ARM and the Installation Notes. +echo Copying documentation. +copy ..\*.md ..\Build\Release +copy ..\CHANGES* ..\Build\Release copy ..\COPYRIGHT ..\Build\Release -copy ..\README ..\Build\Release -copy ..\HISTORY ..\Build\Release -copy readme1st.txt ..\Build\Release -copy index.html ..\Build\Release -copy ..\doc\arm\*.html ..\Build\Release -copy ..\doc\arm\notes.pdf ..\Build\Release -copy ..\doc\arm\Bv9ARM.pdf ..\Build\Release -copy ..\CHANGES ..\Build\Release -if Exist ..\CHANGES.SE copy ..\CHANGES.SE ..\Build\Release -copy ..\FAQ ..\Build\Release - -echo Copying the standalone manual pages. - -copy ..\bin\named\named.html ..\Build\Release -copy ..\bin\named\named.conf.html ..\Build\Release -copy ..\bin\rndc\*.html ..\Build\Release -copy ..\bin\confgen\*.html ..\Build\Release -copy ..\bin\dig\*.html ..\Build\Release -copy ..\bin\delv\*.html ..\Build\Release -copy ..\bin\nsupdate\*.html ..\Build\Release -copy ..\bin\check\*.html ..\Build\Release -copy ..\bin\dnssec\dnssec-keygen.html ..\Build\Release -copy ..\bin\dnssec\dnssec-signzone.html ..\Build\Release -copy ..\bin\dnssec\dnssec-dsfromkey.html ..\Build\Release -copy ..\bin\dnssec\dnssec-keyfromlabel.html ..\Build\Release -copy ..\bin\dnssec\dnssec-settime.html ..\Build\Release -copy ..\bin\dnssec\dnssec-revoke.html ..\Build\Release -copy ..\bin\dnssec\dnssec-verify.html ..\Build\Release -copy ..\bin\dnssec\dnssec-importkey.html ..\Build\Release -@IF PYTHON -copy ..\bin\python\dnssec-checkds.html ..\Build\Release -copy ..\bin\python\dnssec-coverage.html ..\Build\Release -copy ..\bin\python\dnssec-keymgr.html ..\Build\Release -@END PYTHON -@IF PKCS11 -copy ..\bin\pkcs11\pkcs11-keygen.html ..\Build\Release -copy ..\bin\pkcs11\pkcs11-list.html ..\Build\Release -copy ..\bin\pkcs11\pkcs11-destroy.html ..\Build\Release -copy ..\bin\pkcs11\pkcs11-tokens.html ..\Build\Release -@END PKCS11 -copy ..\bin\tools\arpaname.html ..\Build\Release -copy ..\bin\tools\named-journalprint.html ..\Build\Release -copy ..\bin\tools\named-rrchecker.html ..\Build\Release -copy ..\bin\tools\nsec3hash.html ..\Build\Release -copy ..\bin\tools\mdig.html ..\Build\Release - -echo Copying the migration notes. - -copy ..\doc\misc\migration ..\Build\Release -copy ..\doc\misc\migration-4to9 ..\Build\Release +copy ..\LICENSE ..\Build\Release echo Copying the OpenSSL DLL and LICENSE. copy @OPENSSL_DLL@ ..\Build\Release\ copy @OPENSSL_PATH@\LICENSE ..\Build\Release\OpenSSL-LICENSE +echo Copying libuv DLL. +copy @LIBUV_DLL@ ..\Build\Release\ + @IF LIBXML2 echo Copying the libxml DLL. @@ -254,12 +225,6 @@ copy @K5SPRT_DLL@ ..\Build\Release\ copy @WSHELP_DLL@ ..\Build\Release\ @END GSSAPI -@IF GEOIPLEGACY -echo Copying the GeoIP DLL. - -copy @GEOIP_DLL@ ..\Build\Release\ -@END GEOIPLEGACY - @IF IDNKIT echo Copying the IDN kit DLL. @@ -293,6 +258,7 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\include\isc\aes.h" /> <ClInclude Include="..\include\isc\app.h" /> <ClInclude Include="..\include\isc\assertions.h" /> + <ClInclude Include="..\include\isc\astack.h" /> <ClInclude Include="..\include\isc\atomic.h" /> <ClInclude Include="..\include\isc\backtrace.h" /> <ClInclude Include="..\include\isc\base32.h" /> @@ -304,6 +270,7 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\include\isc\commandline.h" /> <ClInclude Include="..\include\isc\counter.h" /> <ClInclude Include="..\include\isc\crc64.h" /> + <ClInclude Include="..\include\isc\endian.h" /> <ClInclude Include="..\include\isc\errno.h" /> <ClInclude Include="..\include\isc\error.h" /> <ClInclude Include="..\include\isc\event.h" /> @@ -315,6 +282,7 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\include\isc\heap.h" /> <ClInclude Include="..\include\isc\hex.h" /> <ClInclude Include="..\include\isc\hmac.h" /> + <ClInclude Include="..\include\isc\hp.h" /> <ClInclude Include="..\include\isc\ht.h" /> <ClInclude Include="..\include\isc\httpd.h" /> <ClInclude Include="..\include\isc\interfaceiter.h" /> @@ -353,6 +321,7 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\include\isc\rwlock.h" /> <ClInclude Include="..\include\isc\safe.h" /> <ClInclude Include="..\include\isc\serial.h" /> + <ClInclude Include="..\include\isc\siphash.h" /> <ClInclude Include="..\include\isc\sockaddr.h" /> <ClInclude Include="..\include\isc\socket.h" /> <ClInclude Include="..\include\isc\stats.h" /> @@ -366,17 +335,15 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\include\isc\timer.h" /> <ClInclude Include="..\include\isc\tm.h" /> <ClInclude Include="..\include\isc\types.h" /> + <ClInclude Include="..\include\isc\utf8.h" /> <ClInclude Include="..\include\isc\util.h" /> <ClInclude Include="..\include\isc\version.h" /> - <ClInclude Include="..\include\isc\xml.h" /> @IF PKCS11 <ClInclude Include="..\include\pk11\constants.h" /> <ClInclude Include="..\include\pk11\internal.h" /> <ClInclude Include="..\include\pk11\pk11.h" /> <ClInclude Include="..\include\pk11\result.h" /> <ClInclude Include="..\include\pkcs11\pkcs11.h" /> - <ClInclude Include="..\include\pkcs11\pkcs11f.h" /> - <ClInclude Include="..\include\pkcs11\pkcs11t.h" /> @END PKCS11 <ClInclude Include="errno2result.h" /> <ClInclude Include="include\isc\bindevt.h" /> @@ -404,14 +371,13 @@ copy InstallFiles ..\Build\Release\ <ClInclude Include="..\openssl_shim.h" /> <ClInclude Include="syslog.h" /> <ClInclude Include="unistd.h" /> -@IF PKCS11 - <ClInclude Include="include\pkcs11\cryptoki.h" /> -@END PKCS11 <ClInclude Include="..\..\versions.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="..\aes.c" /> + <ClCompile Include="..\app.c" /> <ClCompile Include="..\assertions.c" /> + <ClCompile Include="..\astack.c" /> <ClCompile Include="..\backtrace-emptytbl.c" /> <ClCompile Include="..\backtrace.c" /> <ClCompile Include="..\base32.c" /> @@ -429,6 +395,7 @@ copy InstallFiles ..\Build\Release\ <ClCompile Include="..\heap.c" /> <ClCompile Include="..\hex.c" /> <ClCompile Include="..\hmac.c" /> + <ClCompile Include="..\hp.c" /> <ClCompile Include="..\ht.c" /> <ClCompile Include="..\httpd.c" /> <ClCompile Include="..\iterated_hash.c" /> @@ -440,12 +407,19 @@ copy InstallFiles ..\Build\Release\ <ClCompile Include="..\mem.c" /> <ClCompile Include="..\mutexblock.c" /> <ClCompile Include="..\netaddr.c" /> + <ClCompile Include="..\netmgr\netmgr.c" /> + <ClCompile Include="..\netmgr\tcp.c" /> + <ClCompile Include="..\netmgr\udp.c" /> + <ClCompile Include="..\netmgr\uverr2result.c" /> + <ClCompile Include="..\netmgr\uv-compat.c" /> + <ClCompile Include="..\netmgr\tcpdns.c" /> <ClCompile Include="..\netscope.c" /> <ClCompile Include="..\nonce.c" /> <ClCompile Include="..\openssl_shim.c" /> <ClCompile Include="..\parseint.c" /> <ClCompile Include="..\pool.c" /> <ClCompile Include="..\portset.c" /> + <ClCompile Include="..\queue.c" /> <ClCompile Include="..\quota.c" /> <ClCompile Include="..\radix.c" /> <ClCompile Include="..\random.c" /> @@ -454,7 +428,9 @@ copy InstallFiles ..\Build\Release\ <ClCompile Include="..\region.c" /> <ClCompile Include="..\result.c" /> <ClCompile Include="..\rwlock.c" /> + <ClCompile Include="..\safe.c" /> <ClCompile Include="..\serial.c" /> + <ClCompile Include="..\siphash.c" /> <ClCompile Include="..\sockaddr.c" /> <ClCompile Include="..\stats.c" /> <ClCompile Include="..\string.c" /> @@ -463,11 +439,11 @@ copy InstallFiles ..\Build\Release\ <ClCompile Include="..\taskpool.c" /> <ClCompile Include="..\timer.c" /> <ClCompile Include="..\tm.c" /> + <ClCompile Include="..\utf8.c" /> @IF PKCS11 <ClCompile Include="..\pk11.c" /> <ClCompile Include="..\pk11_result.c" /> @END PKCS11 - <ClCompile Include="app.c" /> <ClCompile Include="condition.c" /> <ClCompile Include="dir.c" /> <ClCompile Include="DLLMain.c" /> diff --git a/lib/isc/win32/libisc.vcxproj.user b/lib/isc/win32/libisc.vcxproj.user index 695b5c78..ace9a86a 100644 --- a/lib/isc/win32/libisc.vcxproj.user +++ b/lib/isc/win32/libisc.vcxproj.user @@ -1,3 +1,3 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> </Project>
\ No newline at end of file diff --git a/lib/isc/win32/meminfo.c b/lib/isc/win32/meminfo.c index 51077f6e..3f3f8530 100644 --- a/lib/isc/win32/meminfo.c +++ b/lib/isc/win32/meminfo.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <inttypes.h> #include <windows.h> diff --git a/lib/isc/win32/net.c b/lib/isc/win32/net.c index 120eb149..36ab3638 100644 --- a/lib/isc/win32/net.c +++ b/lib/isc/win32/net.c @@ -3,15 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <errno.h> #include <unistd.h> @@ -33,21 +30,22 @@ * The last resort defaults: use all non well known port space */ #ifndef ISC_NET_PORTRANGELOW -#define ISC_NET_PORTRANGELOW 1024 -#endif /* ISC_NET_PORTRANGELOW */ +#define ISC_NET_PORTRANGELOW 32768 +#endif /* ISC_NET_PORTRANGELOW */ #ifndef ISC_NET_PORTRANGEHIGH #define ISC_NET_PORTRANGEHIGH 65535 -#endif /* ISC_NET_PORTRANGEHIGH */ +#endif /* ISC_NET_PORTRANGEHIGH */ -static isc_once_t once = ISC_ONCE_INIT; -static isc_once_t once_ipv6only = ISC_ONCE_INIT; -static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; -static isc_result_t ipv4_result = ISC_R_NOTFOUND; -static isc_result_t ipv6_result = ISC_R_NOTFOUND; -static isc_result_t ipv6only_result = ISC_R_NOTFOUND; -static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; +static isc_once_t once = ISC_ONCE_INIT; +static isc_once_t once_ipv6only = ISC_ONCE_INIT; +static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; +static isc_result_t ipv4_result = ISC_R_NOTFOUND; +static isc_result_t ipv6_result = ISC_R_NOTFOUND; +static isc_result_t ipv6only_result = ISC_R_NOTFOUND; +static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; -void InitSockets(void); +void +InitSockets(void); static isc_result_t try_proto(int domain) { @@ -66,8 +64,7 @@ try_proto(int domain) { default: strerror_r(errval, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", - strbuf); + "socket() failed: %s", strbuf); return (ISC_R_UNEXPECTED); } } @@ -112,7 +109,7 @@ try_ipv6only(void) { SOCKET s; int on; char strbuf[ISC_STRERRORSIZE]; -#endif +#endif /* ifdef IPV6_V6ONLY */ isc_result_t result; result = isc_net_probeipv6(); @@ -124,13 +121,12 @@ try_ipv6only(void) { #ifndef IPV6_V6ONLY ipv6only_result = ISC_R_NOTFOUND; return; -#else +#else /* ifndef IPV6_V6ONLY */ /* check for TCP sockets */ s = socket(PF_INET6, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; @@ -149,8 +145,7 @@ try_ipv6only(void) { s = socket(PF_INET6, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; @@ -173,8 +168,8 @@ close: static void initialize_ipv6only(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6only, - try_ipv6only) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&once_ipv6only, try_ipv6only) == + ISC_R_SUCCESS); } #ifdef __notyet__ @@ -201,8 +196,7 @@ try_ipv6pktinfo(void) { s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == INVALID_SOCKET) { strerror_r(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", + UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() failed: %s", strbuf); ipv6pktinfo_result = ISC_R_UNEXPECTED; return; @@ -210,11 +204,11 @@ try_ipv6pktinfo(void) { #ifdef IPV6_RECVPKTINFO optname = IPV6_RECVPKTINFO; -#else +#else /* ifdef IPV6_RECVPKTINFO */ optname = IPV6_PKTINFO; -#endif +#endif /* ifdef IPV6_RECVPKTINFO */ on = 1; - if (setsockopt(s, IPPROTO_IPV6, optname, (const char *) &on, + if (setsockopt(s, IPPROTO_IPV6, optname, (const char *)&on, sizeof(on)) < 0) { ipv6pktinfo_result = ISC_R_NOTFOUND; goto close; @@ -229,8 +223,8 @@ close: static void initialize_ipv6pktinfo(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, - try_ipv6pktinfo) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, try_ipv6pktinfo) == + ISC_R_SUCCESS); } #endif /* __notyet__ */ @@ -261,35 +255,39 @@ isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { *high = ISC_NET_PORTRANGEHIGH; } - return (ISC_R_SUCCESS); /* we currently never fail in this function */ + return (ISC_R_SUCCESS); /* we currently never fail in this function */ } void isc_net_disableipv4(void) { initialize(); - if (ipv4_result == ISC_R_SUCCESS) + if (ipv4_result == ISC_R_SUCCESS) { ipv4_result = ISC_R_DISABLED; + } } void isc_net_disableipv6(void) { initialize(); - if (ipv6_result == ISC_R_SUCCESS) + if (ipv6_result == ISC_R_SUCCESS) { ipv6_result = ISC_R_DISABLED; + } } void isc_net_enableipv4(void) { initialize(); - if (ipv4_result == ISC_R_DISABLED) + if (ipv4_result == ISC_R_DISABLED) { ipv4_result = ISC_R_SUCCESS; + } } void isc_net_enableipv6(void) { initialize(); - if (ipv6_result == ISC_R_DISABLED) + if (ipv6_result == ISC_R_DISABLED) { ipv6_result = ISC_R_SUCCESS; + } } unsigned int diff --git a/lib/isc/win32/netdb.h b/lib/isc/win32/netdb.h index a9398c8f..3f699753 100644 --- a/lib/isc/win32/netdb.h +++ b/lib/isc/win32/netdb.h @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef NETDB_H #define NETDB_H 1 @@ -22,17 +21,17 @@ #if _MSC_VER < 1600 struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* Length of ai_addr */ - char *ai_canonname; /* Canonical name for hostname */ - struct sockaddr *ai_addr; /* Binary address */ - struct addrinfo *ai_next; /* Next structure in linked list */ + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and + * IPv6 */ + size_t ai_addrlen; /* Length of ai_addr */ + char *ai_canonname; /* Canonical name for hostname */ + struct sockaddr *ai_addr; /* Binary address */ + struct addrinfo *ai_next; /* Next structure in linked list */ }; -#endif - +#endif /* if _MSC_VER < 1600 */ /* * Undefine all \#defines we are interested in as <netdb.h> may or may not have @@ -44,66 +43,66 @@ struct addrinfo { * (left in extern int h_errno). */ -#undef NETDB_INTERNAL -#undef NETDB_SUCCESS -#undef HOST_NOT_FOUND -#undef TRY_AGAIN -#undef NO_RECOVERY -#undef NO_DATA -#undef NO_ADDRESS - -#define NETDB_INTERNAL -1 /* see errno */ -#define NETDB_SUCCESS 0 /* no problem */ -#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ -#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ -#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ -#define NO_DATA 4 /* Valid name, no data record of requested type */ -#define NO_ADDRESS NO_DATA /* no address, look for MX record */ +#undef NETDB_INTERNAL +#undef NETDB_SUCCESS +#undef HOST_NOT_FOUND +#undef TRY_AGAIN +#undef NO_RECOVERY +#undef NO_DATA +#undef NO_ADDRESS + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define NO_DATA 4 /* Valid name, no data record of requested type */ +#define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo() */ -#undef EAI_ADDRFAMILY -#undef EAI_AGAIN -#undef EAI_BADFLAGS -#undef EAI_FAIL -#undef EAI_FAMILY -#undef EAI_MEMORY -#undef EAI_NODATA -#undef EAI_NONAME -#undef EAI_SERVICE -#undef EAI_SOCKTYPE -#undef EAI_SYSTEM -#undef EAI_BADHINTS -#undef EAI_PROTOCOL -#undef EAI_MAX - -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 +#undef EAI_ADDRFAMILY +#undef EAI_AGAIN +#undef EAI_BADFLAGS +#undef EAI_FAIL +#undef EAI_FAMILY +#undef EAI_MEMORY +#undef EAI_NODATA +#undef EAI_NONAME +#undef EAI_SERVICE +#undef EAI_SOCKTYPE +#undef EAI_SYSTEM +#undef EAI_BADHINTS +#undef EAI_PROTOCOL +#undef EAI_MAX + +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 +#define EAI_PROTOCOL 13 +#define EAI_MAX 14 /* * Flag values for getaddrinfo() */ -#undef AI_PASSIVE -#undef AI_CANONNAME -#undef AI_NUMERICHOST +#undef AI_PASSIVE +#undef AI_CANONNAME +#undef AI_NUMERICHOST -#define AI_PASSIVE 0x00000001 -#define AI_CANONNAME 0x00000002 -#define AI_NUMERICHOST 0x00000004 +#define AI_PASSIVE 0x00000001 +#define AI_CANONNAME 0x00000002 +#define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() @@ -113,70 +112,69 @@ struct addrinfo { #undef AI_ADDRCONFIG #undef AI_DEFAULT -#define AI_V4MAPPED 0x00000008 -#define AI_ALL 0x00000010 -#define AI_ADDRCONFIG 0x00000020 -#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) +#define AI_V4MAPPED 0x00000008 +#define AI_ALL 0x00000010 +#define AI_ADDRCONFIG 0x00000020 +#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG) /* * Constants for getnameinfo() */ -#undef NI_MAXHOST -#undef NI_MAXSERV +#undef NI_MAXHOST +#undef NI_MAXSERV -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 /* * Flag values for getnameinfo() */ -#undef NI_NOFQDN -#undef NI_NUMERICHOST -#undef NI_NAMEREQD -#undef NI_NUMERICSERV -#undef NI_DGRAM -#undef NI_NUMERICSCOPE - -#define NI_NOFQDN 0x00000001 -#define NI_NUMERICHOST 0x00000002 -#define NI_NAMEREQD 0x00000004 -#define NI_NUMERICSERV 0x00000008 -#define NI_DGRAM 0x00000010 -#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/ +#undef NI_NOFQDN +#undef NI_NUMERICHOST +#undef NI_NAMEREQD +#undef NI_NUMERICSERV +#undef NI_DGRAM +#undef NI_NUMERICSCOPE + +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/ /* * Structures for getrrsetbyname() */ struct rdatainfo { - unsigned int rdi_length; - unsigned char *rdi_data; + unsigned int rdi_length; + unsigned char *rdi_data; }; struct rrsetinfo { - unsigned int rri_flags; - int rri_rdclass; - int rri_rdtype; - unsigned int rri_ttl; - unsigned int rri_nrdatas; - unsigned int rri_nsigs; - char *rri_name; - struct rdatainfo *rri_rdatas; - struct rdatainfo *rri_sigs; + unsigned int rri_flags; + int rri_rdclass; + int rri_rdtype; + unsigned int rri_ttl; + unsigned int rri_nrdatas; + unsigned int rri_nsigs; + char *rri_name; + struct rdatainfo *rri_rdatas; + struct rdatainfo *rri_sigs; }; /* * Flags for getrrsetbyname() */ -#define RRSET_VALIDATED 0x00000001 - /* Set was dnssec validated */ +#define RRSET_VALIDATED 0x00000001 +/* Set was dnssec validated */ /* * Return codes for getrrsetbyname() */ -#define ERRSET_SUCCESS 0 -#define ERRSET_NOMEMORY 1 -#define ERRSET_FAIL 2 -#define ERRSET_INVAL 3 - +#define ERRSET_SUCCESS 0 +#define ERRSET_NOMEMORY 1 +#define ERRSET_FAIL 2 +#define ERRSET_INVAL 3 #endif /* NETDB_H */ diff --git a/lib/isc/win32/ntgroups.c b/lib/isc/win32/ntgroups.c index 217243ca..7b605849 100644 --- a/lib/isc/win32/ntgroups.c +++ b/lib/isc/win32/ntgroups.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - /* * The NT Groups have two groups that are not well documented and are * not normally seen: None and Everyone. A user account belongs to @@ -32,15 +30,25 @@ */ #define _CRT_SECURE_NO_DEPRECATE 1 -#include <windows.h> +/* clang-format off */ #include <assert.h> +#include <windows.h> #include <lm.h> +/* clang-format on */ #include <isc/ntgroups.h> #include <isc/result.h> #define MAX_NAME_LENGTH 256 +#define CHECK(op) \ + do { \ + result = (op); \ + if (result != ISC_R_SUCCESS) { \ + goto cleanup; \ + } \ + } while (0) + isc_result_t isc_ntsecurity_getaccountgroups(char *username, char **GroupList, unsigned int maxgroups, @@ -58,10 +66,15 @@ isc_ntsecurity_getaccountgroups(char *username, char **GroupList, NET_API_STATUS nStatus; size_t retlen; wchar_t user[MAX_NAME_LENGTH]; + isc_result_t result; + + *totalGroups = 0; retlen = mbstowcs(user, username, MAX_NAME_LENGTH); + if (retlen == (size_t)(-1)) { + return (ISC_R_FAILURE); + } - *totalGroups = 0; /* * Call the NetUserGetLocalGroups function * specifying information level 0. @@ -70,24 +83,22 @@ isc_ntsecurity_getaccountgroups(char *username, char **GroupList, * function should also return the names of the local * groups in which the user is indirectly a member. */ - nStatus = NetUserGetLocalGroups(NULL, - user, - dwLevel, - dwFlags, - (LPBYTE *) &pBuf, - dwPrefMaxLen, - &dwEntriesRead, - &dwTotalEntries); + nStatus = NetUserGetLocalGroups(NULL, user, dwLevel, dwFlags, + (LPBYTE *)&pBuf, dwPrefMaxLen, + &dwEntriesRead, &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { - if (nStatus == ERROR_ACCESS_DENIED) + if (nStatus == ERROR_ACCESS_DENIED) { return (ISC_R_NOPERM); - if (nStatus == ERROR_MORE_DATA) + } + if (nStatus == ERROR_MORE_DATA) { return (ISC_R_NOSPACE); - if (nStatus == NERR_UserNotFound) + } + if (nStatus == NERR_UserNotFound) { dwEntriesRead = 0; + } } if (pBuf != NULL) { @@ -95,51 +106,58 @@ isc_ntsecurity_getaccountgroups(char *username, char **GroupList, /* * Loop through the entries */ - for (i = 0; - (i < dwEntriesRead && *totalGroups < maxgroups); i++) { + for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); + i++) { assert(pTmpLBuf != NULL); - if (pTmpLBuf == NULL) + if (pTmpLBuf == NULL) { break; + } retlen = wcslen(pTmpLBuf->lgrui0_name); - GroupList[*totalGroups] = (char *) malloc(retlen +1); - if (GroupList[*totalGroups] == NULL) - return (ISC_R_NOMEMORY); + GroupList[*totalGroups] = (char *)malloc(retlen + 1); + if (GroupList[*totalGroups] == NULL) { + CHECK(ISC_R_NOMEMORY); + } retlen = wcstombs(GroupList[*totalGroups], - pTmpLBuf->lgrui0_name, retlen); + pTmpLBuf->lgrui0_name, retlen); + if (retlen == (size_t)(-1)) { + free(GroupList[*totalGroups]); + CHECK(ISC_R_FAILURE); + } GroupList[*totalGroups][retlen] = '\0'; - if (strcmp(GroupList[*totalGroups], "None") == 0) + if (strcmp(GroupList[*totalGroups], "None") == 0) { free(GroupList[*totalGroups]); - else + } else { (*totalGroups)++; + } pTmpLBuf++; } } /* Free the allocated memory. */ - if (pBuf != NULL) + /* cppcheck-suppress duplicateCondition */ + if (pBuf != NULL) { NetApiBufferFree(pBuf); - + } /* * Call the NetUserGetGroups function, specifying level 0. */ - nStatus = NetUserGetGroups(NULL, - user, - dwLevel, - (LPBYTE*)&pgrpBuf, - dwPrefMaxLen, - &dwEntriesRead, - &dwTotalEntries); + nStatus = NetUserGetGroups(NULL, user, dwLevel, (LPBYTE *)&pgrpBuf, + dwPrefMaxLen, &dwEntriesRead, + &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { - if (nStatus == ERROR_ACCESS_DENIED) + if (nStatus == ERROR_ACCESS_DENIED) { return (ISC_R_NOPERM); - if (nStatus == ERROR_MORE_DATA) + } + if (nStatus == ERROR_MORE_DATA) { return (ISC_R_NOSPACE); - if (nStatus == NERR_UserNotFound) + } + if (nStatus == NERR_UserNotFound) { dwEntriesRead = 0; + } } if (pgrpBuf != NULL) { @@ -147,32 +165,47 @@ isc_ntsecurity_getaccountgroups(char *username, char **GroupList, /* * Loop through the entries */ - for (i = 0; - (i < dwEntriesRead && *totalGroups < maxgroups); i++) { + for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); + i++) { assert(pTmpBuf != NULL); - if (pTmpBuf == NULL) + if (pTmpBuf == NULL) { break; + } retlen = wcslen(pTmpBuf->grui0_name); - GroupList[*totalGroups] = (char *) malloc(retlen +1); - if (GroupList[*totalGroups] == NULL) - return (ISC_R_NOMEMORY); + GroupList[*totalGroups] = (char *)malloc(retlen + 1); + if (GroupList[*totalGroups] == NULL) { + CHECK(ISC_R_NOMEMORY); + } retlen = wcstombs(GroupList[*totalGroups], - pTmpBuf->grui0_name, retlen); + pTmpBuf->grui0_name, retlen); + if (retlen == (size_t)(-1)) { + free(GroupList[*totalGroups]); + CHECK(ISC_R_FAILURE); + } GroupList[*totalGroups][retlen] = '\0'; - if (strcmp(GroupList[*totalGroups], "None") == 0) + if (strcmp(GroupList[*totalGroups], "None") == 0) { free(GroupList[*totalGroups]); - else + } else { (*totalGroups)++; + } pTmpBuf++; } } /* * Free the allocated memory. */ - if (pgrpBuf != NULL) + /* cppcheck-suppress duplicateCondition */ + if (pgrpBuf != NULL) { NetApiBufferFree(pgrpBuf); + } return (ISC_R_SUCCESS); + +cleanup: + while (--(*totalGroups) > 0) { + free(GroupList[*totalGroups]); + } + return (result); } diff --git a/lib/isc/win32/ntpaths.c b/lib/isc/win32/ntpaths.c index 6e9b9184..a68d59f1 100644 --- a/lib/isc/win32/ntpaths.c +++ b/lib/isc/win32/ntpaths.c @@ -3,13 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /* * This module fetches the required path information that is specific * to NT systems which can have its configuration and system files @@ -18,8 +17,6 @@ * file locations are stored in the registry. */ -#include <config.h> - #include <isc/bind_registry.h> #include <isc/ntpaths.h> #include <isc/string.h> @@ -50,15 +47,20 @@ isc_ntpaths_init(void) { BOOL keyFound = TRUE; memset(namedBase, 0, sizeof(namedBase)); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, BIND_SUBKEY, 0, KEY_READ, &hKey) - != ERROR_SUCCESS) + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, BIND_SUBKEY, 0, KEY_READ, &hKey) != + ERROR_SUCCESS) + { keyFound = FALSE; + } if (keyFound == TRUE) { /* Get the named directory */ if (RegQueryValueEx(hKey, "InstallDir", NULL, NULL, - (LPBYTE)namedBase, &baseLen) != ERROR_SUCCESS) + (LPBYTE)namedBase, + &baseLen) != ERROR_SUCCESS) + { keyFound = FALSE; + } RegCloseKey(hKey); } @@ -96,8 +98,7 @@ isc_ntpaths_init(void) { /* Added to avoid an assert on NULL value */ strlcpy(resolv_confFile, namedBase, sizeof(resolv_confFile)); - strlcat(resolv_confFile, "\\etc\\resolv.conf", - sizeof(resolv_confFile)); + strlcat(resolv_confFile, "\\etc\\resolv.conf", sizeof(resolv_confFile)); strlcpy(bind_keysFile, namedBase, sizeof(bind_keysFile)); strlcat(bind_keysFile, "\\etc\\bind.keys", sizeof(bind_keysFile)); @@ -107,8 +108,9 @@ isc_ntpaths_init(void) { char * isc_ntpaths_get(int ind) { - if (!Initialized) + if (!Initialized) { isc_ntpaths_init(); + } switch (ind) { case NAMED_CONF_PATH: diff --git a/lib/isc/win32/once.c b/lib/isc/win32/once.c index baf178d6..6e7f4102 100644 --- a/lib/isc/win32/once.c +++ b/lib/isc/win32/once.c @@ -3,26 +3,23 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <windows.h> -#include <isc/once.h> #include <isc/assertions.h> +#include <isc/once.h> #include <isc/util.h> isc_result_t -isc_once_do(isc_once_t *controller, void(*function)(void)) { +isc_once_do(isc_once_t *controller, void (*function)(void)) { REQUIRE(controller != NULL && function != NULL); if (controller->status == ISC_ONCE_INIT_NEEDED) { - if (InterlockedDecrement(&controller->counter) == 0) { if (controller->status == ISC_ONCE_INIT_NEEDED) { function(); diff --git a/lib/isc/win32/os.c b/lib/isc/win32/os.c index f06bcd54..e865fa69 100644 --- a/lib/isc/win32/os.c +++ b/lib/isc/win32/os.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <windows.h> #include <isc/os.h> @@ -20,8 +18,9 @@ static SYSTEM_INFO SystemInfo; static void initialize_action(void) { - if (bInit) + if (bInit) { return; + } GetSystemInfo(&SystemInfo); bInit = TRUE; @@ -32,8 +31,9 @@ isc_os_ncpus(void) { long ncpus; initialize_action(); ncpus = SystemInfo.dwNumberOfProcessors; - if (ncpus <= 0) + if (ncpus <= 0) { ncpus = 1; + } return ((unsigned int)ncpus); } diff --git a/lib/isc/win32/pk11_api.c b/lib/isc/win32/pk11_api.c index 7626b616..ed0d5264 100644 --- a/lib/isc/win32/pk11_api.c +++ b/lib/isc/win32/pk11_api.c @@ -3,19 +3,16 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /*! \file */ /* missing code for WIN32 */ -#include <config.h> - #include <string.h> #include <windows.h> @@ -27,8 +24,8 @@ #include <isc/thread.h> #include <isc/util.h> -#include <pk11/pk11.h> #include <pk11/internal.h> +#include <pk11/pk11.h> char * getpass(const char *prompt) { @@ -45,11 +42,11 @@ getpass(const char *prompt) { GetConsoleMode(h, &mode); SetConsoleMode(h, ENABLE_PROCESSED_INPUT); - for (cnt = 0; cnt < sizeof(buf) - 1; cnt++) - { + for (cnt = 0; cnt < sizeof(buf) - 1; cnt++) { ReadFile(h, buf + cnt, 1, &cc, NULL); - if (buf[cnt] == '\r') + if (buf[cnt] == '\r') { break; + } fputc('*', stdout); fflush(stderr); fflush(stdout); @@ -71,31 +68,36 @@ pkcs_C_Initialize(CK_VOID_PTR pReserved) { CK_C_Initialize sym; const char *lib_name = pk11_get_lib_name(); - if (hPK11 != NULL) + if (hPK11 != NULL) { return (CKR_LIBRARY_ALREADY_INITIALIZED); + } - if (lib_name == NULL) + if (lib_name == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - /* Visual Studio convertion issue... */ - if (*lib_name == ' ') + } + /* Visual Studio conversion issue... */ + if (*lib_name == ' ') { lib_name++; + } hPK11 = LoadLibraryA(lib_name); if (hPK11 == NULL) { const DWORD err = GetLastError(); snprintf(loaderrmsg, sizeof(loaderrmsg), - "LoadLibraryA(\"%s\") failed with 0x%X\n", - lib_name, err); + "LoadLibraryA(\"%s\") failed with 0x%X\n", lib_name, + err); return (CKR_LIBRARY_FAILED_TO_LOAD); } sym = (CK_C_Initialize)GetProcAddress(hPK11, "C_Initialize"); - if (sym == NULL) + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(pReserved); + } + return ((*sym)(pReserved)); } -char *pk11_get_load_error_message(void) { +char * +pk11_get_load_error_message(void) { return (loaderrmsg); } @@ -104,80 +106,85 @@ pkcs_C_Finalize(CK_VOID_PTR pReserved) { CK_C_Finalize sym; CK_RV rv; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); + } sym = (CK_C_Finalize)GetProcAddress(hPK11, "C_Finalize"); - if (sym == NULL) + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); + } rv = (*sym)(pReserved); - if ((rv == CKR_OK) && (FreeLibrary(hPK11) == 0)) + if ((rv == CKR_OK) && (FreeLibrary(hPK11) == 0)) { return (CKR_LIBRARY_FAILED_TO_LOAD); + } hPK11 = NULL; return (rv); } CK_RV -pkcs_C_GetSlotList(CK_BBOOL tokenPresent, - CK_SLOT_ID_PTR pSlotList, - CK_ULONG_PTR pulCount) -{ +pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount) { static CK_C_GetSlotList sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_GetSlotList)GetProcAddress(hPK11, "C_GetSlotList"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(tokenPresent, pSlotList, pulCount); + } + return ((*sym)(tokenPresent, pSlotList, pulCount)); } CK_RV -pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, - CK_TOKEN_INFO_PTR pInfo) -{ +pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { static CK_C_GetTokenInfo sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_GetTokenInfo)GetProcAddress(hPK11, - "C_GetTokenInfo"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_GetTokenInfo)GetProcAddress(hPK11, "C_" + "GetTokenInfo"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, pInfo); + } + return ((*sym)(slotID, pInfo)); } CK_RV -pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, - CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) -{ +pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo) { static CK_C_GetMechanismInfo sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_GetMechanismInfo)GetProcAddress(hPK11, - "C_GetMechanismInfo"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_GetMechanismInfo)GetProcAddress(hPK11, "C_" + "GetMechanis" + "mInfo"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, type, pInfo); + } + return ((*sym)(slotID, type, pInfo)); } CK_RV -pkcs_C_OpenSession(CK_SLOT_ID slotID, - CK_FLAGS flags, - CK_VOID_PTR pApplication, - CK_RV (*Notify) (CK_SESSION_HANDLE hSession, - CK_NOTIFICATION event, - CK_VOID_PTR pApplication), - CK_SESSION_HANDLE_PTR phSession) -{ +pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, + CK_RV (*Notify)(CK_SESSION_HANDLE hSession, + CK_NOTIFICATION event, + CK_VOID_PTR pApplication), + CK_SESSION_HANDLE_PTR phSession) { static CK_C_OpenSession sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { hPK11 = LoadLibraryA(pk11_get_lib_name()); + } if (hPK11 == NULL) { const DWORD err = GetLastError(); snprintf(loaderrmsg, sizeof(loaderrmsg), @@ -185,489 +192,513 @@ pkcs_C_OpenSession(CK_SLOT_ID slotID, pk11_get_lib_name(), err); return (CKR_LIBRARY_FAILED_TO_LOAD); } - if (sym == NULL) + if (sym == NULL) { sym = (CK_C_OpenSession)GetProcAddress(hPK11, "C_OpenSession"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(slotID, flags, pApplication, Notify, phSession); + } + return ((*sym)(slotID, flags, pApplication, Notify, phSession)); } CK_RV pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) { static CK_C_CloseSession sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_CloseSession)GetProcAddress(hPK11, - "C_CloseSession"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_CloseSession)GetProcAddress(hPK11, "C_" + "CloseSession"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + } + return ((*sym)(hSession)); } CK_RV -pkcs_C_Login(CK_SESSION_HANDLE hSession, - CK_USER_TYPE userType, - CK_CHAR_PTR pPin, - CK_ULONG usPinLen) -{ +pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_CHAR_PTR pPin, CK_ULONG usPinLen) { static CK_C_Login sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_Login)GetProcAddress(hPK11, "C_Login"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, userType, pPin, usPinLen); + } + return ((*sym)(hSession, userType, pPin, usPinLen)); } CK_RV pkcs_C_Logout(CK_SESSION_HANDLE hSession) { static CK_C_Logout sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_Logout)GetProcAddress(hPK11, "C_Logout"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + } + return ((*sym)(hSession)); } CK_RV -pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount, - CK_OBJECT_HANDLE_PTR phObject) -{ +pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) { static CK_C_CreateObject sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_CreateObject)GetProcAddress(hPK11, - "C_CreateObject"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_CreateObject)GetProcAddress(hPK11, "C_" + "CreateObject"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pTemplate, usCount, phObject); + } + return ((*sym)(hSession, pTemplate, usCount, phObject)); } CK_RV pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { static CK_C_DestroyObject sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_DestroyObject)GetProcAddress(hPK11, - "C_DestroyObject"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_DestroyObject)GetProcAddress(hPK11, "C_" + "DestroyObjec" + "t"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject); + } + return ((*sym)(hSession, hObject)); } CK_RV -pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount) -{ +pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_GetAttributeValue sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_GetAttributeValue)GetProcAddress(hPK11, - "C_GetAttributeValue"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_GetAttributeValue)GetProcAddress(hPK11, "C_" + "GetAttribu" + "teValue"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject, pTemplate, usCount); + } + return ((*sym)(hSession, hObject, pTemplate, usCount)); } CK_RV -pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount) -{ +pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_SetAttributeValue sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_SetAttributeValue)GetProcAddress(hPK11, - "C_SetAttributeValue"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_SetAttributeValue)GetProcAddress(hPK11, "C_" + "SetAttribu" + "teValue"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, hObject, pTemplate, usCount); + } + return ((*sym)(hSession, hObject, pTemplate, usCount)); } CK_RV -pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG usCount) -{ +pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG usCount) { static CK_C_FindObjectsInit sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_FindObjectsInit)GetProcAddress(hPK11, - "C_FindObjectsInit"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_FindObjectsInit)GetProcAddress(hPK11, "C_" + "FindObjectsI" + "nit"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pTemplate, usCount); + } + return ((*sym)(hSession, pTemplate, usCount)); } CK_RV -pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE_PTR phObject, - CK_ULONG usMaxObjectCount, - CK_ULONG_PTR pusObjectCount) -{ +pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) { static CK_C_FindObjects sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_FindObjects)GetProcAddress(hPK11, "C_FindObjects"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount); + } + return ((*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount)); } CK_RV pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { static CK_C_FindObjectsFinal sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_FindObjectsFinal)GetProcAddress(hPK11, - "C_FindObjectsFinal"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_FindObjectsFinal)GetProcAddress(hPK11, "C_" + "FindObjects" + "Final"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession); + } + return ((*sym)(hSession)); } CK_RV -pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ +pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { static CK_C_EncryptInit sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_EncryptInit)GetProcAddress(hPK11, "C_EncryptInit"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV -pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pEncryptedData, - CK_ULONG_PTR pulEncryptedDataLen) -{ +pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen) { static CK_C_Encrypt sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_Encrypt)GetProcAddress(hPK11, "C_Encrypt"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, - pEncryptedData, pulEncryptedDataLen); + } + return ((*sym)(hSession, pData, ulDataLen, pEncryptedData, + pulEncryptedDataLen)); } CK_RV -pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism) -{ +pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { static CK_C_DigestInit sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_DigestInit)GetProcAddress(hPK11, "C_DigestInit"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism); + } + return ((*sym)(hSession, pMechanism)); } CK_RV -pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ +pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { static CK_C_DigestUpdate sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_DigestUpdate)GetProcAddress(hPK11, - "C_DigestUpdate"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_DigestUpdate)GetProcAddress(hPK11, "C_" + "DigestUpdate"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV -pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ +pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) { static CK_C_DigestFinal sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_DigestFinal)GetProcAddress(hPK11, "C_DigestFinal"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pDigest, pulDigestLen); + } + return ((*sym)(hSession, pDigest, pulDigestLen)); } CK_RV -pkcs_C_SignInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ +pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { static CK_C_SignInit sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_SignInit)GetProcAddress(hPK11, "C_SignInit"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV -pkcs_C_Sign(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ +pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_Sign sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_Sign)GetProcAddress(hPK11, "C_Sign"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, pSignature, pulSignatureLen); + } + return ((*sym)(hSession, pData, ulDataLen, pSignature, + pulSignatureLen)); } CK_RV -pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ +pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { static CK_C_SignUpdate sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_SignUpdate)GetProcAddress(hPK11, "C_SignUpdate"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV -pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ +pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) { static CK_C_SignFinal sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_SignFinal)GetProcAddress(hPK11, "C_SignFinal"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSignature, pulSignatureLen); + } + return ((*sym)(hSession, pSignature, pulSignatureLen)); } CK_RV -pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ +pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { static CK_C_VerifyInit sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_VerifyInit)GetProcAddress(hPK11, "C_VerifyInit"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, hKey); + } + return ((*sym)(hSession, pMechanism, hKey)); } CK_RV -pkcs_C_Verify(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ +pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_Verify sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_Verify)GetProcAddress(hPK11, "C_Verify"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen); + } + return ((*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen)); } CK_RV -pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ +pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { static CK_C_VerifyUpdate sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_VerifyUpdate)GetProcAddress(hPK11, - "C_VerifyUpdate"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_VerifyUpdate)GetProcAddress(hPK11, "C_" + "VerifyUpdate"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pPart, ulPartLen); + } + return ((*sym)(hSession, pPart, ulPartLen)); } CK_RV -pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ +pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) { static CK_C_VerifyFinal sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_VerifyFinal)GetProcAddress(hPK11, "C_VerifyFinal"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSignature, ulSignatureLen); + } + return ((*sym)(hSession, pSignature, ulSignatureLen)); } CK_RV -pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey) -{ +pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey) { static CK_C_GenerateKey sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_GenerateKey)GetProcAddress(hPK11, "C_GenerateKey"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pMechanism, pTemplate, ulCount, phKey); + } + return ((*sym)(hSession, pMechanism, pTemplate, ulCount, phKey)); } CK_RV -pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG usPublicKeyAttributeCount, - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG usPrivateKeyAttributeCount, - CK_OBJECT_HANDLE_PTR phPrivateKey, - CK_OBJECT_HANDLE_PTR phPublicKey) -{ +pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG usPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG usPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPrivateKey, + CK_OBJECT_HANDLE_PTR phPublicKey) { static CK_C_GenerateKeyPair sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_GenerateKeyPair)GetProcAddress(hPK11, - "C_GenerateKeyPair"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_GenerateKeyPair)GetProcAddress(hPK11, "C_" + "GenerateKeyP" + "air"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, - pMechanism, - pPublicKeyTemplate, - usPublicKeyAttributeCount, - pPrivateKeyTemplate, - usPrivateKeyAttributeCount, - phPrivateKey, - phPublicKey); + } + return ((*sym)(hSession, pMechanism, pPublicKeyTemplate, + usPublicKeyAttributeCount, pPrivateKeyTemplate, + usPrivateKeyAttributeCount, phPrivateKey, phPublicKey)); } CK_RV -pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey) -{ +pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_DeriveKey sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_DeriveKey)GetProcAddress(hPK11, "C_DeriveKey"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, - pMechanism, - hBaseKey, - pTemplate, - ulAttributeCount, - phKey); + } + return ((*sym)(hSession, pMechanism, hBaseKey, pTemplate, + ulAttributeCount, phKey)); } CK_RV -pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSeed, - CK_ULONG ulSeedLen) -{ +pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen) { static CK_C_SeedRandom sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) + } + if (sym == NULL) { sym = (CK_C_SeedRandom)GetProcAddress(hPK11, "C_SeedRandom"); - if (sym == NULL) + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, pSeed, ulSeedLen); + } + return ((*sym)(hSession, pSeed, ulSeedLen)); } CK_RV -pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR RandomData, - CK_ULONG ulRandomLen) -{ +pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, + CK_ULONG ulRandomLen) { static CK_C_GenerateRandom sym = NULL; - if (hPK11 == NULL) + if (hPK11 == NULL) { return (CKR_LIBRARY_FAILED_TO_LOAD); - if (sym == NULL) - sym = (CK_C_GenerateRandom)GetProcAddress(hPK11, - "C_GenerateRandom"); - if (sym == NULL) + } + if (sym == NULL) { + sym = (CK_C_GenerateRandom)GetProcAddress(hPK11, "C_" + "GenerateRando" + "m"); + } + if (sym == NULL) { return (CKR_SYMBOL_RESOLUTION_FAILED); - return (*sym)(hSession, RandomData, ulRandomLen); + } + return ((*sym)(hSession, RandomData, ulRandomLen)); } diff --git a/lib/isc/win32/resource.c b/lib/isc/win32/resource.c index 0fbc9a41..8da2b48d 100644 --- a/lib/isc/win32/resource.c +++ b/lib/isc/win32/resource.c @@ -3,15 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <stdio.h> #include <isc/platform.h> @@ -25,35 +22,37 @@ * Windows limits the maximum number of open files to 2048 */ -#define WIN32_MAX_OPEN_FILES 2048 +#define WIN32_MAX_OPEN_FILES 2048 isc_result_t isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { isc_resourcevalue_t rlim_value; int wresult; - if (resource != isc_resource_openfiles) + if (resource != isc_resource_openfiles) { return (ISC_R_NOTIMPLEMENTED); + } - - if (value == ISC_RESOURCE_UNLIMITED) + if (value == ISC_RESOURCE_UNLIMITED) { rlim_value = WIN32_MAX_OPEN_FILES; - else + } else { rlim_value = min(value, WIN32_MAX_OPEN_FILES); + } - wresult = _setmaxstdio((int) rlim_value); + wresult = _setmaxstdio((int)rlim_value); - if (wresult > 0) + if (wresult > 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { - - if (resource != isc_resource_openfiles) + if (resource != isc_resource_openfiles) { return (ISC_R_NOTIMPLEMENTED); + } *value = WIN32_MAX_OPEN_FILES; return (ISC_R_SUCCESS); diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 2dd95798..ede300ba 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - /* This code uses functions which are only available on Server 2003 and * higher, and Windows XP and higher. * @@ -31,19 +29,19 @@ #include <sys/types.h> #ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ -#endif +#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ +#endif /* ifndef _WINSOCKAPI_ */ #include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <io.h> +#include <process.h> #include <stdbool.h> #include <stddef.h> -#include <inttypes.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <io.h> -#include <fcntl.h> -#include <process.h> #include <isc/app.h> #include <isc/buffer.h> @@ -57,6 +55,7 @@ #include <isc/os.h> #include <isc/platform.h> #include <isc/print.h> +#include <isc/refcount.h> #include <isc/region.h> #include <isc/socket.h> #include <isc/stats.h> @@ -68,7 +67,19 @@ #include <isc/util.h> #include <isc/win32os.h> +/* clang-format off */ +/* U Can't Touch This */ #include <mswsock.h> +/* clang-format on */ + +#ifdef HAVE_JSON_C +#include <json_object.h> +#endif /* HAVE_JSON_C */ + +#ifdef HAVE_LIBXML2 +#include <libxml/xmlwriter.h> +#define ISC_XMLCHAR (const xmlChar *) +#endif /* HAVE_LIBXML2 */ #include "errno2result.h" @@ -94,10 +105,13 @@ LPFN_GETACCEPTEXSOCKADDRS ISCGetAcceptExSockaddrs; */ #ifdef ISC_SOCKET_CONSISTENCY_CHECKS #define CONSISTENT(sock) consistent(sock) -#else -#define CONSISTENT(sock) do {} while (0) -#endif -static void consistent(isc_socket_t *sock); +#else /* ifdef ISC_SOCKET_CONSISTENCY_CHECKS */ +#define CONSISTENT(sock) \ + do { \ + } while (0) +#endif /* ifdef ISC_SOCKET_CONSISTENCY_CHECKS */ +static void +consistent(isc_socket_t *sock); /* * Define this macro to control the behavior of connection @@ -107,19 +121,16 @@ static void consistent(isc_socket_t *sock); * or later. */ #ifndef SIO_UDP_CONNRESET -#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) -#endif +#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12) +#endif /* ifndef SIO_UDP_CONNRESET */ /* * Define what the possible "soft" errors can be. These are non-fatal returns * of various network related functions, like recv() and so on. */ -#define SOFT_ERROR(e) ((e) == WSAEINTR || \ - (e) == WSAEWOULDBLOCK || \ - (e) == EWOULDBLOCK || \ - (e) == EINTR || \ - (e) == EAGAIN || \ - (e) == 0) +#define SOFT_ERROR(e) \ + ((e) == WSAEINTR || (e) == WSAEWOULDBLOCK || (e) == EWOULDBLOCK || \ + (e) == EINTR || (e) == EAGAIN || (e) == 0) /* * Pending errors are not really errors and should be @@ -127,12 +138,14 @@ static void consistent(isc_socket_t *sock); */ #define PENDING_ERROR(e) ((e) == WSA_IO_PENDING || (e) == 0) -#define DOIO_SUCCESS 0 /* i/o ok, event sent */ -#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ -#define DOIO_HARD 2 /* i/o error, event sent */ -#define DOIO_EOF 3 /* EOF, no event sent */ -#define DOIO_PENDING 4 /* status when i/o is in process */ -#define DOIO_NEEDMORE 5 /* IO was processed, but we need more due to minimum */ +#define DOIO_SUCCESS 0 /* i/o ok, event sent */ +#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ +#define DOIO_HARD 2 /* i/o error, event sent */ +#define DOIO_EOF 3 /* EOF, no event sent */ +#define DOIO_PENDING 4 /* status when i/o is in process */ +#define DOIO_NEEDMORE \ + 5 /* IO was processed, but we need more due to minimum \ + */ #define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x) @@ -143,35 +156,34 @@ static void consistent(isc_socket_t *sock); * DLVL(50) -- Event tracing, including receiving/sending completion events. * DLVL(20) -- Socket creation/destruction. */ -#define TRACE_LEVEL 90 -#define CORRECTNESS_LEVEL 70 -#define IOEVENT_LEVEL 60 -#define EVENT_LEVEL 50 -#define CREATION_LEVEL 20 - -#define TRACE DLVL(TRACE_LEVEL) -#define CORRECTNESS DLVL(CORRECTNESS_LEVEL) -#define IOEVENT DLVL(IOEVENT_LEVEL) -#define EVENT DLVL(EVENT_LEVEL) -#define CREATION DLVL(CREATION_LEVEL) +#define TRACE_LEVEL 90 +#define CORRECTNESS_LEVEL 70 +#define IOEVENT_LEVEL 60 +#define EVENT_LEVEL 50 +#define CREATION_LEVEL 20 + +#define TRACE DLVL(TRACE_LEVEL) +#define CORRECTNESS DLVL(CORRECTNESS_LEVEL) +#define IOEVENT DLVL(IOEVENT_LEVEL) +#define EVENT DLVL(EVENT_LEVEL) +#define CREATION DLVL(CREATION_LEVEL) typedef isc_event_t intev_t; /* * Socket State */ -enum { - SOCK_INITIALIZED, /* Socket Initialized */ - SOCK_OPEN, /* Socket opened but nothing yet to do */ - SOCK_DATA, /* Socket sending or receiving data */ - SOCK_LISTEN, /* TCP Socket listening for connects */ - SOCK_ACCEPT, /* TCP socket is waiting to accept */ - SOCK_CONNECT, /* TCP Socket connecting */ - SOCK_CLOSED, /* Socket has been closed */ +enum { SOCK_INITIALIZED, /* Socket Initialized */ + SOCK_OPEN, /* Socket opened but nothing yet to do */ + SOCK_DATA, /* Socket sending or receiving data */ + SOCK_LISTEN, /* TCP Socket listening for connects */ + SOCK_ACCEPT, /* TCP socket is waiting to accept */ + SOCK_CONNECT, /* TCP Socket connecting */ + SOCK_CLOSED, /* Socket has been closed */ }; -#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') -#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC) +#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') +#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC) /* * IPv6 control information. If the socket is an IPv6 socket we want @@ -179,8 +191,8 @@ enum { * set them on outgoing packets. */ #ifndef USE_CMSG -#define USE_CMSG 1 -#endif +#define USE_CMSG 1 +#endif /* ifndef USE_CMSG */ /* * We really don't want to try and use these control messages. Win32 @@ -193,19 +205,19 @@ enum { * Used value-result for recvmsg, value only for sendmsg. */ struct msghdr { - SOCKADDR_STORAGE to_addr; /* UDP send/recv address */ - int to_addr_len; /* length of the address */ - WSABUF *msg_iov; /* scatter/gather array */ - u_int msg_iovlen; /* # elements in msg_iov */ - void *msg_control; /* ancillary data, see below */ - u_int msg_controllen; /* ancillary data buffer len */ - u_int msg_totallen; /* total length of this message */ + SOCKADDR_STORAGE to_addr; /* UDP send/recv address */ + int to_addr_len; /* length of the address */ + WSABUF *msg_iov; /* scatter/gather array */ + u_int msg_iovlen; /* # elements in msg_iov */ + void *msg_control; /* ancillary data, see below */ + u_int msg_controllen; /* ancillary data buffer len */ + u_int msg_totallen; /* total length of this message */ } msghdr; /* * The size to raise the receive buffer to. */ -#define RCVBUFSIZE (32*1024) +#define RCVBUFSIZE (32 * 1024) /* * The number of times a send operation is repeated if the result @@ -215,21 +227,21 @@ struct msghdr { struct isc_socket { /* Not locked. */ - unsigned int magic; - isc_socketmgr_t *manager; - isc_mutex_t lock; - isc_sockettype_t type; + unsigned int magic; + isc_socketmgr_t *manager; + isc_mutex_t lock; + isc_sockettype_t type; /* Pointers to scatter/gather buffers */ - WSABUF iov[ISC_SOCKET_MAXSCATTERGATHER]; + WSABUF iov[ISC_SOCKET_MAXSCATTERGATHER]; /* Locked by socket lock. */ - ISC_LINK(isc_socket_t) link; - unsigned int references; /* EXTERNAL references */ - SOCKET fd; /* file handle */ - int pf; /* protocol family */ - char name[16]; - void * tag; + ISC_LINK(isc_socket_t) link; + isc_refcount_t references; /* EXTERNAL references */ + SOCKET fd; /* file handle */ + int pf; /* protocol family */ + char name[16]; + void *tag; /* * Each recv() call uses this buffer. It is a per-socket receive @@ -239,36 +251,48 @@ struct isc_socket { * calls. It also allows us to read-ahead in some cases. */ struct { - SOCKADDR_STORAGE from_addr; // UDP send/recv address - int from_addr_len; // length of the address - char *base; // the base of the buffer - char *consume_position; // where to start copying data from next - unsigned int len; // the actual size of this buffer - unsigned int remaining; // the number of bytes remaining + SOCKADDR_STORAGE from_addr; /* UDP send/recv address */ + int from_addr_len; /* length of the address */ + char *base; /* the base of the buffer */ + char *consume_position; /* where to start + * copying data from + * next */ + unsigned int len; /* the actual size of this buffer */ + unsigned int remaining; /* the number of bytes + * remaining */ } recvbuf; - ISC_LIST(isc_socketevent_t) send_list; - ISC_LIST(isc_socketevent_t) recv_list; - ISC_LIST(isc_socket_newconnev_t) accept_list; - ISC_LIST(isc_socket_connev_t) connect_list; - - isc_sockaddr_t address; /* remote address */ - - unsigned int listener : 1, /* listener socket */ - connected : 1, - pending_connect : 1, /* connect pending */ - bound : 1, /* bound to local addr */ - dupped : 1; /* created by isc_socket_dup() */ - unsigned int pending_iocp; /* Should equal the counters below. Debug. */ - unsigned int pending_recv; /* Number of outstanding recv() calls. */ - unsigned int pending_send; /* Number of outstanding send() calls. */ - unsigned int pending_accept; /* Number of outstanding accept() calls. */ - unsigned int state; /* Socket state. Debugging and consistency checking. */ - int state_lineno; /* line which last touched state */ + ISC_LIST(isc_socketevent_t) send_list; + ISC_LIST(isc_socketevent_t) recv_list; + ISC_LIST(isc_socket_newconnev_t) accept_list; + ISC_LIST(isc_socket_connev_t) connect_list; + + isc_sockaddr_t address; /* remote address */ + + unsigned int listener : 1, /* listener socket */ + connected : 1, pending_connect : 1, /* connect + * pending */ + bound : 1, /* bound to local addr */ + dupped : 1; /* created by isc_socket_dup() */ + unsigned int pending_iocp; /* Should equal the counters below. + * Debug. */ + unsigned int pending_recv; /* Number of outstanding recv() calls. + * */ + unsigned int pending_send; /* Number of outstanding send() calls. + * */ + unsigned int pending_accept; /* Number of outstanding accept() + * calls. */ + unsigned int state; /* Socket state. Debugging and consistency + * checking. + */ + int state_lineno; /* line which last touched state */ }; -#define _set_state(sock, _state) do { (sock)->state = (_state); (sock)->state_lineno = __LINE__; } while (0) - +#define _set_state(sock, _state) \ + do { \ + (sock)->state = (_state); \ + (sock)->state_lineno = __LINE__; \ + } while (0) /* * I/O Completion ports Info structures @@ -276,16 +300,16 @@ struct isc_socket { static HANDLE hHeapHandle = NULL; typedef struct IoCompletionInfo { - OVERLAPPED overlapped; - isc_socketevent_t *dev; /* send()/recv() done event */ - isc_socket_connev_t *cdev; /* connect() done event */ - isc_socket_newconnev_t *adev; /* accept() done event */ - void *acceptbuffer; - DWORD received_bytes; - int request_type; - struct msghdr messagehdr; - void *buf; - unsigned int buflen; + OVERLAPPED overlapped; + isc_socketevent_t *dev; /* send()/recv() done event */ + isc_socket_connev_t *cdev; /* connect() done event */ + isc_socket_newconnev_t *adev; /* accept() done event */ + void *acceptbuffer; + DWORD received_bytes; + int request_type; + struct msghdr messagehdr; + void *buf; + unsigned int buflen; } IoCompletionInfo; /* @@ -295,64 +319,74 @@ typedef struct IoCompletionInfo { */ #define MAX_IOCPTHREADS 20 -#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) +#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') +#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) struct isc_socketmgr { /* Not locked. */ - unsigned int magic; - isc_mem_t *mctx; - isc_mutex_t lock; - isc_stats_t *stats; + unsigned int magic; + isc_mem_t *mctx; + isc_mutex_t lock; + isc_stats_t *stats; /* Locked by manager lock. */ - ISC_LIST(isc_socket_t) socklist; - bool bShutdown; - isc_condition_t shutdown_ok; - HANDLE hIoCompletionPort; - int maxIOCPThreads; - HANDLE hIOCPThreads[MAX_IOCPTHREADS]; - DWORD dwIOCPThreadIds[MAX_IOCPTHREADS]; + ISC_LIST(isc_socket_t) socklist; + bool bShutdown; + isc_condition_t shutdown_ok; + HANDLE hIoCompletionPort; + int maxIOCPThreads; + HANDLE hIOCPThreads[MAX_IOCPTHREADS]; + DWORD dwIOCPThreadIds[MAX_IOCPTHREADS]; + size_t maxudp; /* * Debugging. * Modified by InterlockedIncrement() and InterlockedDecrement() */ - LONG totalSockets; - LONG iocp_total; + LONG totalSockets; + LONG iocp_total; }; -enum { - SOCKET_RECV, - SOCKET_SEND, - SOCKET_ACCEPT, - SOCKET_CONNECT -}; +enum { SOCKET_RECV, SOCKET_SEND, SOCKET_ACCEPT, SOCKET_CONNECT }; /* * send() and recv() iovec counts */ -#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) -#define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) - -static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, - isc_sockettype_t type, - isc_socket_t **socketp, - isc_socket_t *dup_socket); -static isc_threadresult_t WINAPI SocketIoThread(LPVOID ThreadContext); -static void maybe_free_socket(isc_socket_t **, int); -static void free_socket(isc_socket_t **, int); -static bool senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev); -static bool acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev); -static bool connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev); -static void send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev); -static void send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev); -static void send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev); -static void send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev); -static void send_recvdone_abort(isc_socket_t *sock, isc_result_t result); -static void send_connectdone_abort(isc_socket_t *sock, isc_result_t result); -static void queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev); -static void queue_receive_request(isc_socket_t *sock); +#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) +#define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) + +static isc_result_t +socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp, isc_socket_t *dup_socket); +static isc_threadresult_t WINAPI +SocketIoThread(LPVOID ThreadContext); +static void +maybe_free_socket(isc_socket_t **, int); +static void +free_socket(isc_socket_t **, int); +static bool +senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev); +static bool +acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev); +static bool +connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev); +static void +send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev); +static void +send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev); +static void +send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev); +static void +send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev); +static void +send_recvdone_abort(isc_socket_t *sock, isc_result_t result); +static void +send_connectdone_abort(isc_socket_t *sock, isc_result_t result); +static void +queue_receive_event(isc_socket_t *sock, isc_task_t *task, + isc_socketevent_t *dev); +static void +queue_receive_request(isc_socket_t *sock); /* * This is used to dump the contents of the sock structure @@ -371,21 +405,22 @@ sock_dump(isc_socket_t *sock) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_result_t result; - result = isc_socket_getpeername(sock, &addr); + result = isc_socket_getpeername(sock,&addr); if (result == ISC_R_SUCCESS) { - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - printf("Remote Socket: %s\n", socktext); + isc_sockaddr_format(&addr,socktext,sizeof(socktext)); + printf("Remote Socket: %s\n",socktext); } - result = isc_socket_getsockname(sock, &addr); + result = isc_socket_getsockname(sock,&addr); if (result == ISC_R_SUCCESS) { - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - printf("This Socket: %s\n", socktext); + isc_sockaddr_format(&addr,socktext,sizeof(socktext)); + printf("This Socket: %s\n",socktext); } -#endif +#endif /* if 0 */ printf("\n\t\tSock Dump\n"); printf("\t\tfd: %Iu\n", sock->fd); - printf("\t\treferences: %u\n", sock->references); + printf("\t\treferences: %" PRIuFAST32 "\n", + isc_refcount_current(&sock->references)); printf("\t\tpending_accept: %u\n", sock->pending_accept); printf("\t\tconnecting: %u\n", sock->pending_connect); printf("\t\tconnected: %u\n", sock->connected); @@ -438,8 +473,8 @@ signal_iocompletionport_exit(isc_socketmgr_t *manager) { REQUIRE(VALID_MANAGER(manager)); for (i = 0; i < manager->maxIOCPThreads; i++) { - if (!PostQueuedCompletionStatus(manager->hIoCompletionPort, - 0, 0, 0)) { + if (!PostQueuedCompletionStatus(manager->hIoCompletionPort, 0, + 0, 0)) { errval = GetLastError(); strerror_r(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, @@ -464,15 +499,14 @@ iocompletionport_createthreads(int total_threads, isc_socketmgr_t *manager) { * We need at least one */ for (i = 0; i < total_threads; i++) { - manager->hIOCPThreads[i] = CreateThread(NULL, 0, SocketIoThread, - manager, 0, - &manager->dwIOCPThreadIds[i]); + manager->hIOCPThreads[i] = + CreateThread(NULL, 0, SocketIoThread, manager, 0, + &manager->dwIOCPThreadIds[i]); if (manager->hIOCPThreads[i] == NULL) { errval = GetLastError(); strerror_r(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, - "Can't create IOCP thread: %s", - strbuf); + "Can't create IOCP thread: %s", strbuf); } } } @@ -501,14 +535,14 @@ iocompletionport_init(isc_socketmgr_t *manager) { /* Now Create the Completion Port */ manager->hIoCompletionPort = CreateIoCompletionPort( - INVALID_HANDLE_VALUE, NULL, - 0, manager->maxIOCPThreads); + INVALID_HANDLE_VALUE, NULL, 0, manager->maxIOCPThreads); if (manager->hIoCompletionPort == NULL) { errval = GetLastError(); strerror_r(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, - "CreateIoCompletionPort() failed during initialization: %s", - strbuf); + "CreateIoCompletionPort() failed during " + "initialization: %s", + strbuf); } /* @@ -518,8 +552,8 @@ iocompletionport_init(isc_socketmgr_t *manager) { } /* - * Associate a socket with an IO Completion Port. This allows us to queue events for it - * and have our worker pool of threads process them. + * Associate a socket with an IO Completion Port. This allows us to queue + * events for it and have our worker pool of threads process them. */ void iocompletionport_update(isc_socket_t *sock) { @@ -529,15 +563,16 @@ iocompletionport_update(isc_socket_t *sock) { REQUIRE(VALID_SOCKET(sock)); hiocp = CreateIoCompletionPort((HANDLE)sock->fd, - sock->manager->hIoCompletionPort, (ULONG_PTR)sock, 0); + sock->manager->hIoCompletionPort, + (ULONG_PTR)sock, 0); if (hiocp == NULL) { DWORD errval = GetLastError(); strerror_r(errval, strbuf, sizeof(strbuf)); - isc_log_write(isc_lctx, - ISC_LOGCATEGORY_GENERAL, + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "iocompletionport_update: failed to open io completion port: %s", + "iocompletionport_update: failed to open io " + "completion port: %s", strbuf); /* XXXMLG temporary hack to make failures detected. @@ -545,7 +580,8 @@ iocompletionport_update(isc_socket_t *sock) { * exit here. */ FATAL_ERROR(__FILE__, __LINE__, - "CreateIoCompletionPort() failed during initialization: %s", + "CreateIoCompletionPort() failed during " + "initialization: %s", strbuf); } @@ -562,7 +598,6 @@ iocompletionport_update(isc_socket_t *sock) { */ void socket_close(isc_socket_t *sock) { - REQUIRE(sock != NULL); if (sock->fd != INVALID_SOCKET) { @@ -605,22 +640,21 @@ initialise(void) { */ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); INSIST(sock != INVALID_SOCKET); - err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, - &GUIDConnectEx, sizeof(GUIDConnectEx), - &ISCConnectEx, sizeof(ISCConnectEx), - &dwBytes, NULL, NULL); + err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &GUIDConnectEx, + sizeof(GUIDConnectEx), &ISCConnectEx, + sizeof(ISCConnectEx), &dwBytes, NULL, NULL); INSIST(err == 0); - err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, - &GUIDAcceptEx, sizeof(GUIDAcceptEx), - &ISCAcceptEx, sizeof(ISCAcceptEx), - &dwBytes, NULL, NULL); + err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &GUIDAcceptEx, + sizeof(GUIDAcceptEx), &ISCAcceptEx, sizeof(ISCAcceptEx), + &dwBytes, NULL, NULL); INSIST(err == 0); - err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, - &GUIDGetAcceptExSockaddrs, sizeof(GUIDGetAcceptExSockaddrs), - &ISCGetAcceptExSockaddrs, sizeof(ISCGetAcceptExSockaddrs), - &dwBytes, NULL, NULL); + err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, + &GUIDGetAcceptExSockaddrs, + sizeof(GUIDGetAcceptExSockaddrs), + &ISCGetAcceptExSockaddrs, + sizeof(ISCGetAcceptExSockaddrs), &dwBytes, NULL, NULL); INSIST(err == 0); closesocket(sock); @@ -633,16 +667,16 @@ initialise(void) { */ void InitSockets(void) { - RUNTIME_CHECK(isc_once_do(&initialise_once, - initialise) == ISC_R_SUCCESS); - if (!initialised) + RUNTIME_CHECK(isc_once_do(&initialise_once, initialise) == + ISC_R_SUCCESS); + if (!initialised) { exit(1); + } } int internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo, - struct msghdr *messagehdr, int flags, int *Error) -{ + struct msghdr *messagehdr, int flags, int *Error) { int Result; DWORD BytesSent; DWORD Flags = flags; @@ -650,10 +684,9 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo, *Error = 0; Result = WSASendTo(sock->fd, messagehdr->msg_iov, - messagehdr->msg_iovlen, &BytesSent, - Flags, (SOCKADDR *)&messagehdr->to_addr, - messagehdr->to_addr_len, (LPWSAOVERLAPPED)lpo, - NULL); + messagehdr->msg_iovlen, &BytesSent, Flags, + (SOCKADDR *)&messagehdr->to_addr, + messagehdr->to_addr_len, (LPWSAOVERLAPPED)lpo, NULL); total_sent = (int)BytesSent; @@ -665,7 +698,7 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo, case WSA_IO_INCOMPLETE: case WSA_WAIT_IO_COMPLETION: case WSA_IO_PENDING: - case NO_ERROR: /* Strange, but okay */ + case NO_ERROR: /* Strange, but okay */ sock->pending_iocp++; sock->pending_send++; break; @@ -679,10 +712,11 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo, sock->pending_send++; } - if (lpo != NULL) + if (lpo != NULL) { return (0); - else + } else { return (total_sent); + } } static void @@ -696,15 +730,16 @@ queue_receive_request(isc_socket_t *sock) { IoCompletionInfo *lpo = NULL; isc_result_t isc_result; - retry: +retry: need_retry = false; /* * If we already have a receive pending, do nothing. */ if (sock->pending_recv > 0) { - if (lpo != NULL) + if (lpo != NULL) { HeapFree(hHeapHandle, 0, lpo); + } return; } @@ -712,8 +747,9 @@ queue_receive_request(isc_socket_t *sock) { * If no one is waiting, do nothing. */ if (ISC_LIST_EMPTY(sock->recv_list)) { - if (lpo != NULL) + if (lpo != NULL) { HeapFree(hHeapHandle, 0, lpo); + } return; } @@ -728,18 +764,18 @@ queue_receive_request(isc_socket_t *sock) { HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); - } else + } else { ZeroMemory(lpo, sizeof(IoCompletionInfo)); + } lpo->request_type = SOCKET_RECV; sock->recvbuf.from_addr_len = sizeof(sock->recvbuf.from_addr); Error = 0; - Result = WSARecvFrom((SOCKET)sock->fd, iov, 1, - &NumBytes, &Flags, + Result = WSARecvFrom((SOCKET)sock->fd, iov, 1, &NumBytes, &Flags, (SOCKADDR *)&sock->recvbuf.from_addr, - &sock->recvbuf.from_addr_len, - (LPWSAOVERLAPPED)lpo, NULL); + &sock->recvbuf.from_addr_len, (LPWSAOVERLAPPED)lpo, + NULL); /* Check for errors. */ if (Result == SOCKET_ERROR) { @@ -764,10 +800,12 @@ queue_receive_request(isc_socket_t *sock) { default: isc_result = isc__errno2result(Error); - if (isc_result == ISC_R_UNEXPECTED) + if (isc_result == ISC_R_UNEXPECTED) { UNEXPECTED_ERROR(__FILE__, __LINE__, - "WSARecvFrom: Windows error code: %d, isc result %d", - Error, isc_result); + "WSARecvFrom: Windows error " + "code: %d, isc result %d", + Error, isc_result); + } send_recvdone_abort(sock, isc_result); HeapFree(hHeapHandle, 0, lpo); lpo = NULL; @@ -784,45 +822,45 @@ queue_receive_request(isc_socket_t *sock) { } socket_log(__LINE__, sock, NULL, IOEVENT, - "queue_io_request: fd %d result %d error %d", - sock->fd, Result, Error); + "queue_io_request: fd %d result %d error %d", sock->fd, + Result, Error); CONSISTENT(sock); - if (need_retry) + if (need_retry) { goto retry; + } } static void manager_log(isc_socketmgr_t *sockmgr, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, ...) -{ + isc_logmodule_t *module, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; - if (!isc_log_wouldlog(isc_lctx, level)) + if (!isc_log_wouldlog(isc_lctx, level)) { return; + } va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); - isc_log_write(isc_lctx, category, module, level, - "sockmgr %p: %s", sockmgr, msgbuf); + isc_log_write(isc_lctx, category, module, level, "sockmgr %p: %s", + sockmgr, msgbuf); } static void socket_log(int lineno, isc_socket_t *sock, const isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) -{ + const char *fmt, ...) { char msgbuf[2048]; char peerbuf[256]; va_list ap; - - if (!isc_log_wouldlog(isc_lctx, level)) + if (!isc_log_wouldlog(isc_lctx, level)) { return; + } va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); @@ -834,10 +872,9 @@ socket_log(int lineno, isc_socket_t *sock, const isc_sockaddr_t *address, } else { isc_sockaddr_format(address, peerbuf, sizeof(peerbuf)); isc_log_write(isc_lctx, category, module, level, - "socket %p line %d %s: %s", sock, lineno, - peerbuf, msgbuf); + "socket %p line %d %s: %s", sock, lineno, peerbuf, + msgbuf); } - } /* @@ -855,8 +892,8 @@ make_nonblock(SOCKET fd) { if (ret == -1) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "ioctlsocket(%d, FIOBIO, %d): %s", - fd, flags, strbuf); + "ioctlsocket(%d, FIOBIO, %d): %s", fd, flags, + strbuf); return (ISC_R_UNEXPECTED); } @@ -877,21 +914,22 @@ make_nonblock(SOCKET fd) { isc_result_t connection_reset_fix(SOCKET fd) { DWORD dwBytesReturned = 0; - BOOL bNewBehavior = FALSE; + BOOL bNewBehavior = FALSE; DWORD status; - if (isc_win32os_versioncheck(5, 0, 0, 0) < 0) + if (isc_win32os_versioncheck(5, 0, 0, 0) < 0) { return (ISC_R_SUCCESS); /* NT 4.0 has no problem */ - + } /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */ status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior, - sizeof(bNewBehavior), NULL, 0, - &dwBytesReturned, NULL, NULL); - if (status != SOCKET_ERROR) + sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, + NULL); + if (status != SOCKET_ERROR) { return (ISC_R_SUCCESS); - else { + } else { UNEXPECTED_ERROR(__FILE__, __LINE__, - "WSAIoctl(SIO_UDP_CONNRESET, oldBehaviour) failed"); + "WSAIoctl(SIO_UDP_CONNRESET, oldBehaviour) " + "failed"); return (ISC_R_UNEXPECTED); } } @@ -908,8 +946,7 @@ connection_reset_fix(SOCKET fd) { static void build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, char *cmsg, WSABUF *iov, - IoCompletionInfo *lpo) -{ + IoCompletionInfo *lpo) { unsigned int iovcount; size_t write_count; @@ -928,10 +965,10 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, lpo->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count); RUNTIME_CHECK(lpo->buf != NULL); - socket_log(__LINE__, sock, NULL, TRACE, - "alloc_buffer %p %d", lpo->buf, write_count); + socket_log(__LINE__, sock, NULL, TRACE, "alloc_buffer %p %d", lpo->buf, + write_count); - memmove(lpo->buf,(dev->region.base + dev->n), write_count); + memmove(lpo->buf, (dev->region.base + dev->n), write_count); lpo->buflen = (unsigned int)write_count; iov[0].buf = lpo->buf; iov[0].len = (u_long)write_count; @@ -944,13 +981,13 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, static void set_dev_address(const isc_sockaddr_t *address, isc_socket_t *sock, - isc_socketevent_t *dev) -{ + isc_socketevent_t *dev) { if (sock->type == isc_sockettype_udp) { - if (address != NULL) + if (address != NULL) { dev->address = *address; - else + } else { dev->address = sock->address; + } } else if (sock->type == isc_sockettype_tcp) { INSIST(address == NULL); dev->address = sock->address; @@ -967,17 +1004,15 @@ destroy_socketevent(isc_event_t *event) { static isc_socketevent_t * allocate_socketevent(isc_mem_t *mctx, isc_socket_t *sock, isc_eventtype_t eventtype, isc_taskaction_t action, - void *arg) -{ + void *arg) { isc_socketevent_t *ev; ev = (isc_socketevent_t *)isc_event_allocate(mctx, sock, eventtype, - action, arg, - sizeof(*ev)); - if (ev == NULL) - return (NULL); + action, arg, sizeof(*ev)); - ev->result = ISC_R_IOERROR; // XXXMLG temporary change to detect failure to set + ev->result = ISC_R_IOERROR; /* XXXMLG temporary change to detect failure + */ + /* to set */ ISC_LINK_INIT(ev, ev_link); ev->region.base = NULL; ev->n = 0; @@ -999,10 +1034,10 @@ dump_msg(struct msghdr *msg, isc_socket_t *sock) { printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen); printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen); for (i = 0; i < (unsigned int)msg->msg_iovlen; i++) - printf("\t\t%u\tbase %p, len %u\n", i, - msg->msg_iov[i].buf, msg->msg_iov[i].len); + printf("\t\t%u\tbase %p, len %u\n", i, msg->msg_iov[i].buf, + msg->msg_iov[i].len); } -#endif +#endif /* if defined(ISC_SOCKET_DEBUG) */ /* * map the error code @@ -1010,70 +1045,77 @@ dump_msg(struct msghdr *msg, isc_socket_t *sock) { int map_socket_error(isc_socket_t *sock, int windows_errno, int *isc_errno, char *errorstring, size_t bufsize) { - int doreturn; switch (windows_errno) { case WSAECONNREFUSED: *isc_errno = ISC_R_CONNREFUSED; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAENETUNREACH: case ERROR_NETWORK_UNREACHABLE: *isc_errno = ISC_R_NETUNREACH; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case ERROR_PORT_UNREACHABLE: case ERROR_HOST_UNREACHABLE: case WSAEHOSTUNREACH: *isc_errno = ISC_R_HOSTUNREACH; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAENETDOWN: *isc_errno = ISC_R_NETDOWN; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAEHOSTDOWN: *isc_errno = ISC_R_HOSTDOWN; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAEACCES: *isc_errno = ISC_R_NOPERM; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAECONNRESET: case WSAENETRESET: case WSAECONNABORTED: case WSAEDISCON: *isc_errno = ISC_R_CONNECTIONRESET; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case WSAENOTCONN: *isc_errno = ISC_R_NOTCONNECTED; - if (sock->connected) + if (sock->connected) { doreturn = DOIO_HARD; - else + } else { doreturn = DOIO_SOFT; + } break; case ERROR_OPERATION_ABORTED: case ERROR_CONNECTION_ABORTED: @@ -1126,19 +1168,30 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) { sock->recvbuf.from_addr_len); if (isc_sockaddr_getport(&dev->address) == 0) { if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { - socket_log(__LINE__, sock, &dev->address, IOEVENT, + socket_log(__LINE__, sock, &dev->address, + IOEVENT, "dropping source port zero packet"); } sock->recvbuf.remaining = 0; return; } + /* + * Simulate a firewall blocking UDP responses bigger than + * 'maxudp' bytes. + */ + if (sock->manager->maxudp != 0 && + sock->recvbuf.remaining > sock->manager->maxudp) + { + sock->recvbuf.remaining = 0; + return; + } } else if (sock->type == isc_sockettype_tcp) { dev->address = sock->address; } copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining); - memmove(dev->region.base + dev->n, - sock->recvbuf.consume_position, copylen); + memmove(dev->region.base + dev->n, sock->recvbuf.consume_position, + copylen); sock->recvbuf.consume_position += copylen; sock->recvbuf.remaining -= copylen; dev->n += copylen; @@ -1149,8 +1202,9 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) { * 1k of space, we will toss the remaining 3k of data. TCP * will keep the extra data around and use it for later requests. */ - if (sock->type == isc_sockettype_udp) + if (sock->type == isc_sockettype_udp) { sock->recvbuf.remaining = 0; + } } /* @@ -1158,18 +1212,19 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) { * As each done event is filled, send it along its way. */ static void -completeio_recv(isc_socket_t *sock) -{ +completeio_recv(isc_socket_t *sock) { isc_socketevent_t *dev; /* * If we are in the process of filling our buffer, we cannot * touch it yet, so don't. */ - if (sock->pending_recv > 0) + if (sock->pending_recv > 0) { return; + } - while (sock->recvbuf.remaining > 0 && !ISC_LIST_EMPTY(sock->recv_list)) { + while (sock->recvbuf.remaining > 0 && !ISC_LIST_EMPTY(sock->recv_list)) + { dev = ISC_LIST_HEAD(sock->recv_list); /* @@ -1203,24 +1258,25 @@ completeio_recv(isc_socket_t *sock) */ static int completeio_send(isc_socket_t *sock, isc_socketevent_t *dev, - struct msghdr *messagehdr, int cc, int send_errno) -{ + struct msghdr *messagehdr, int cc, int send_errno) { char strbuf[ISC_STRERRORSIZE]; if (send_errno != 0) { - if (SOFT_ERROR(send_errno)) + if (SOFT_ERROR(send_errno)) { return (DOIO_SOFT); + } - return (map_socket_error(sock, send_errno, &dev->result, - strbuf, sizeof(strbuf))); + return (map_socket_error(sock, send_errno, &dev->result, strbuf, + sizeof(strbuf))); } /* * If we write less than we expected, update counters, poke. */ dev->n += cc; - if (cc != messagehdr->msg_totallen) + if (cc != messagehdr->msg_totallen) { return (DOIO_SOFT); + } /* * Exactly what we wanted to write. We're done with this @@ -1232,16 +1288,25 @@ completeio_send(isc_socket_t *sock, isc_socketevent_t *dev, static int startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, - int *send_errno) -{ + int *send_errno) { char *cmsg = NULL; char strbuf[ISC_STRERRORSIZE]; IoCompletionInfo *lpo; int status; struct msghdr *mh; - lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, - HEAP_ZERO_MEMORY, + /* + * Simulate a firewall blocking UDP responses bigger than + * 'maxudp' bytes. + */ + if (sock->type == isc_sockettype_udp && sock->manager->maxudp != 0 && + dev->region.length - dev->n > sock->manager->maxudp) + { + *nbytes = dev->region.length - dev->n; + return (DOIO_SUCCESS); + } + + lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); lpo->request_type = SOCKET_SEND; @@ -1274,7 +1339,8 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { strerror_r(*send_errno, strbuf, sizeof(strbuf)); socket_log(__LINE__, sock, NULL, IOEVENT, - "startio_send: internal_sendmsg(%d) %d bytes, err %d/%s", + "startio_send: internal_sendmsg(%d) %d " + "bytes, err %d/%s", sock->fd, *nbytes, *send_errno, strbuf); } status = DOIO_HARD; @@ -1282,7 +1348,7 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, } dev->result = ISC_R_SUCCESS; status = DOIO_SOFT; - done: +done: _set_state(sock, SOCK_DATA); return (status); } @@ -1294,26 +1360,22 @@ use_min_mtu(isc_socket_t *sock) { if (sock->pf == AF_INET6) { int on = 1; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)); + (void *)&on, sizeof(on)); } -#else +#else /* ifdef IPV6_USE_MIN_MTU */ UNUSED(sock); -#endif +#endif /* ifdef IPV6_USE_MIN_MTU */ } static isc_result_t allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, isc_socket_t **socketp) { isc_socket_t *sock; - isc_result_t result; sock = isc_mem_get(manager->mctx, sizeof(*sock)); - if (sock == NULL) - return (ISC_R_NOMEMORY); - sock->magic = 0; - sock->references = 0; + isc_refcount_init(&sock->references, 0); sock->manager = manager; sock->type = type; @@ -1337,37 +1399,27 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, sock->pending_connect = 0; sock->bound = 0; sock->dupped = 0; - memset(sock->name, 0, sizeof(sock->name)); // zero the name field + memset(sock->name, 0, sizeof(sock->name)); /* zero the name field */ _set_state(sock, SOCK_INITIALIZED); sock->recvbuf.len = 65536; sock->recvbuf.consume_position = sock->recvbuf.base; sock->recvbuf.remaining = 0; - sock->recvbuf.base = isc_mem_get(manager->mctx, sock->recvbuf.len); // max buffer size - if (sock->recvbuf.base == NULL) { - result = ISC_R_NOMEMORY; - goto error; - } + sock->recvbuf.base = isc_mem_get(manager->mctx, + sock->recvbuf.len); /* max buffer */ + /* size */ /* * Initialize the lock. */ isc_mutex_init(&sock->lock); - socket_log(__LINE__, sock, NULL, EVENT, - "allocated"); + socket_log(__LINE__, sock, NULL, EVENT, "allocated"); sock->magic = SOCKET_MAGIC; *socketp = sock; return (ISC_R_SUCCESS); - - error: - if (sock->recvbuf.base != NULL) - isc_mem_put(manager->mctx, sock->recvbuf.base, sock->recvbuf.len); - isc_mem_put(manager->mctx, sock, sizeof(*sock)); - - return (result); } /* @@ -1375,15 +1427,15 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, */ static void consistent(isc_socket_t *sock) { - isc_socketevent_t *dev; isc_socket_newconnev_t *nev; unsigned int count; char *crash_reason; bool crash = false; - REQUIRE(sock->pending_iocp == sock->pending_recv + sock->pending_send - + sock->pending_accept + sock->pending_connect); + REQUIRE(sock->pending_iocp == sock->pending_recv + sock->pending_send + + sock->pending_accept + + sock->pending_connect); dev = ISC_LIST_HEAD(sock->send_list); count = 0; @@ -1411,14 +1463,14 @@ consistent(isc_socket_t *sock) { socket_log(__LINE__, sock, NULL, CREATION, "SOCKET INCONSISTENT: %s", crash_reason); sock_dump(sock); - INSIST(crash == false); + INSIST(!crash); } } /* * Maybe free the socket. * - * This function will verify tht the socket is no longer in use in any way, + * This function will verify that the socket is no longer in use in any way, * either internally or externally. This is the only place where this * check is to be made; if some bit of code believes that IT is done with * the socket (e.g., some reference counter reaches zero), it should call @@ -1438,17 +1490,14 @@ maybe_free_socket(isc_socket_t **socketp, int lineno) { INSIST(VALID_SOCKET(sock)); CONSISTENT(sock); - if (sock->pending_iocp > 0 - || sock->pending_recv > 0 - || sock->pending_send > 0 - || sock->pending_accept > 0 - || sock->references > 0 - || sock->pending_connect == 1 - || !ISC_LIST_EMPTY(sock->recv_list) - || !ISC_LIST_EMPTY(sock->send_list) - || !ISC_LIST_EMPTY(sock->accept_list) - || !ISC_LIST_EMPTY(sock->connect_list) - || sock->fd != INVALID_SOCKET) { + if (sock->pending_iocp > 0 || sock->pending_recv > 0 || + sock->pending_send > 0 || sock->pending_accept > 0 || + isc_refcount_current(&sock->references) > 0 || + sock->pending_connect == 1 || !ISC_LIST_EMPTY(sock->recv_list) || + !ISC_LIST_EMPTY(sock->send_list) || + !ISC_LIST_EMPTY(sock->accept_list) || + !ISC_LIST_EMPTY(sock->connect_list) || sock->fd != INVALID_SOCKET) + { UNLOCK(&sock->lock); return; } @@ -1468,23 +1517,26 @@ free_socket(isc_socket_t **sockp, int lineno) { */ manager = sock->manager; socket_log(__LINE__, sock, NULL, CREATION, - "freeing socket line %d fd %d lock %p semaphore %p", - lineno, sock->fd, &sock->lock, sock->lock.LockSemaphore); + "freeing socket line %d fd %d lock %p semaphore %p", lineno, + sock->fd, &sock->lock, sock->lock.LockSemaphore); sock->magic = 0; isc_mutex_destroy(&sock->lock); - if (sock->recvbuf.base != NULL) + if (sock->recvbuf.base != NULL) { isc_mem_put(manager->mctx, sock->recvbuf.base, sock->recvbuf.len); + } LOCK(&manager->lock); - if (ISC_LINK_LINKED(sock, link)) + if (ISC_LINK_LINKED(sock, link)) { ISC_LIST_UNLINK(manager->socklist, sock, link); + } isc_mem_put(manager->mctx, sock, sizeof(*sock)); - if (ISC_LIST_EMPTY(manager->socklist)) + if (ISC_LIST_EMPTY(manager->socklist)) { SIGNAL(&manager->shutdown_ok); + } UNLOCK(&manager->lock); } @@ -1496,17 +1548,16 @@ free_socket(isc_socket_t **sockp, int lineno) { */ static isc_result_t socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, - isc_socket_t **socketp, isc_socket_t *dup_socket) -{ + isc_socket_t **socketp, isc_socket_t *dup_socket) { isc_socket_t *sock = NULL; isc_result_t result; #if defined(USE_CMSG) int on = 1; -#endif +#endif /* if defined(USE_CMSG) */ #if defined(SO_RCVBUF) socklen_t optlen; int size; -#endif +#endif /* if defined(SO_RCVBUF) */ int socket_errno; char strbuf[ISC_STRERRORSIZE]; @@ -1514,13 +1565,15 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, REQUIRE(socketp != NULL && *socketp == NULL); #ifndef SOCK_RAW - if (type == isc_sockettype_raw) + if (type == isc_sockettype_raw) { return (ISC_R_NOTIMPLEMENTED); -#endif + } +#endif /* ifndef SOCK_RAW */ result = allocate_socket(manager, type, &sock); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } sock->pf = pf; switch (type) { @@ -1529,13 +1582,13 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, if (sock->fd != INVALID_SOCKET) { result = connection_reset_fix(sock->fd); if (result != ISC_R_SUCCESS) { - socket_log(__LINE__, sock, - NULL, EVENT, - "closed %d %d %d " - "con_reset_fix_failed", - sock->pending_recv, - sock->pending_send, - sock->references); + socket_log(__LINE__, sock, NULL, EVENT, + "closed %d %d %" PRIuFAST32 " " + "con_reset_fix_failed", + sock->pending_recv, + sock->pending_send, + isc_refcount_current( + &sock->references)); closesocket(sock->fd); _set_state(sock, SOCK_CLOSED); sock->fd = INVALID_SOCKET; @@ -1551,11 +1604,12 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, case isc_sockettype_raw: sock->fd = socket(pf, SOCK_RAW, 0); #ifdef PF_ROUTE - if (pf == PF_ROUTE) + if (pf == PF_ROUTE) { sock->bound = 1; -#endif + } +#endif /* ifdef PF_ROUTE */ break; -#endif +#endif /* ifdef SOCK_RAW */ } if (sock->fd == INVALID_SOCKET) { @@ -1575,8 +1629,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, default: strerror_r(socket_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", - strbuf); + "socket() failed: %s", strbuf); return (ISC_R_UNEXPECTED); } } @@ -1584,9 +1637,9 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { socket_log(__LINE__, sock, NULL, EVENT, - "closed %d %d %d make_nonblock_failed", - sock->pending_recv, sock->pending_send, - sock->references); + "closed %d %d %" PRIuFAST32 " make_nonblock_failed", + sock->pending_recv, sock->pending_send, + isc_refcount_current(&sock->references)); closesocket(sock->fd); sock->fd = INVALID_SOCKET; free_socket(&sock, __LINE__); @@ -1600,23 +1653,25 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, #if defined(USE_CMSG) || defined(SO_RCVBUF) if (type == isc_sockettype_udp) { - #if defined(USE_CMSG) #ifdef IPV6_RECVPKTINFO /* 2292bis */ - if ((pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, - (char *)&on, sizeof(on)) < 0)) { + if ((pf == AF_INET6) && + (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, + (char *)&on, sizeof(on)) < 0)) + { strerror_r(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_RECVPKTINFO) failed: %s", + "setsockopt(%d, IPV6_RECVPKTINFO) " + "failed: %s", sock->fd, strbuf); } -#else +#else /* ifdef IPV6_RECVPKTINFO */ /* 2292 */ - if ((pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, - (char *)&on, sizeof(on)) < 0)) { + if ((pf == AF_INET6) && + (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, + (char *)&on, sizeof(on)) < 0)) + { strerror_r(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_PKTINFO) %s: %s", @@ -1626,21 +1681,21 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, #endif /* defined(USE_CMSG) */ #if defined(SO_RCVBUF) - optlen = sizeof(size); - if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, - (char *)&size, &optlen) >= 0 && - size < RCVBUFSIZE) { - size = RCVBUFSIZE; - (void)setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, - (char *)&size, sizeof(size)); - } -#endif - + optlen = sizeof(size); + if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&size, + &optlen) >= 0 && + size < RCVBUFSIZE) + { + size = RCVBUFSIZE; + (void)setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, + (char *)&size, sizeof(size)); + } +#endif /* if defined(SO_RCVBUF) */ } #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */ _set_state(sock, SOCK_OPEN); - sock->references = 1; + isc_refcount_init(&sock->references, 1); *socketp = sock; iocompletionport_update(sock); @@ -1648,7 +1703,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, if (dup_socket) { #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(sock, true); -#endif +#endif /* ifndef ISC_ALLOW_MAPPED */ if (dup_socket->bound) { isc_sockaddr_t local; @@ -1677,16 +1732,15 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, InterlockedIncrement(&manager->totalSockets); UNLOCK(&manager->lock); - socket_log(__LINE__, sock, NULL, CREATION, - "created %u type %u", sock->fd, type); + socket_log(__LINE__, sock, NULL, CREATION, "created %u type %u", + sock->fd, type); return (ISC_R_SUCCESS); } isc_result_t isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, - isc_socket_t **socketp) -{ + isc_socket_t **socketp) { return (socket_create(manager, pf, type, socketp, NULL)); } @@ -1695,8 +1749,8 @@ isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); - return (socket_create(sock->manager, sock->pf, sock->type, - socketp, sock)); + return (socket_create(sock->manager, sock->pf, sock->type, socketp, + sock)); } isc_result_t @@ -1716,9 +1770,10 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { LOCK(&sock->lock); CONSISTENT(sock); - sock->references++; UNLOCK(&sock->lock); + isc_refcount_increment0(&sock->references); + *socketp = sock; } @@ -1729,30 +1784,29 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { void isc_socket_detach(isc_socket_t **socketp) { isc_socket_t *sock; + uint32_t references; REQUIRE(socketp != NULL); sock = *socketp; + *socketp = NULL; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); - REQUIRE(sock->references > 0); - sock->references--; + + references = isc_refcount_decrement(&sock->references); socket_log(__LINE__, sock, NULL, EVENT, - "detach_socket %d %d %d", - sock->pending_recv, sock->pending_send, - sock->references); + "detach_socket %d %d %" PRIuFAST32, sock->pending_recv, + sock->pending_send, isc_refcount_current(&sock->references)); - if (sock->references == 0 && sock->fd != INVALID_SOCKET) { + if (references == 1 && sock->fd != INVALID_SOCKET) { closesocket(sock->fd); sock->fd = INVALID_SOCKET; _set_state(sock, SOCK_CLOSED); } - maybe_free_socket(&sock, __LINE__); - - *socketp = NULL; + maybe_free_socket(&sock, __LINE__); /* Also unlocks the socket lock */ } isc_result_t @@ -1779,8 +1833,9 @@ send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) { task = (*dev)->ev_sender; (*dev)->ev_sender = sock; - if (ISC_LINK_LINKED(*dev, ev_link)) + if (ISC_LINK_LINKED(*dev, ev_link)) { ISC_LIST_DEQUEUE(sock->recv_list, *dev, ev_link); + } if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) != 0) { isc_task_sendanddetach(&task, (isc_event_t **)dev); @@ -1803,8 +1858,9 @@ send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) { task = (*dev)->ev_sender; (*dev)->ev_sender = sock; - if (ISC_LINK_LINKED(*dev, ev_link)) + if (ISC_LINK_LINKED(*dev, ev_link)) { ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link); + } if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) != 0) { isc_task_sendanddetach(&task, (isc_event_t **)dev); @@ -1827,8 +1883,9 @@ send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev) { task = (*adev)->ev_sender; (*adev)->ev_sender = sock; - if (ISC_LINK_LINKED(*adev, ev_link)) + if (ISC_LINK_LINKED(*adev, ev_link)) { ISC_LIST_DEQUEUE(sock->accept_list, *adev, ev_link); + } isc_task_sendanddetach(&task, (isc_event_t **)adev); @@ -1847,8 +1904,9 @@ send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev) { task = (*cdev)->ev_sender; (*cdev)->ev_sender = sock; - if (ISC_LINK_LINKED(*cdev, ev_link)) + if (ISC_LINK_LINKED(*cdev, ev_link)) { ISC_LIST_DEQUEUE(sock->connect_list, *cdev, ev_link); + } isc_task_sendanddetach(&task, (isc_event_t **)cdev); @@ -1877,8 +1935,7 @@ internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { LOCK(&sock->lock); CONSISTENT(sock); - socket_log(__LINE__, sock, NULL, TRACE, - "internal_accept called"); + socket_log(__LINE__, sock, NULL, TRACE, "internal_accept called"); INSIST(sock->listener); @@ -1892,8 +1949,9 @@ internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { /* * If the event is no longer in the list we can just return. */ - if (!acceptdone_is_active(sock, adev)) + if (!acceptdone_is_active(sock, adev)) { goto done; + } nsock = adev->newsocket; @@ -1906,10 +1964,10 @@ internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { * Extract the addresses from the socket, copy them into the structure, * and return the new socket. */ - ISCGetAcceptExSockaddrs(lpo->acceptbuffer, 0, - sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, - (LPSOCKADDR *)&localaddr, &localaddr_len, - (LPSOCKADDR *)&remoteaddr, &remoteaddr_len); + ISCGetAcceptExSockaddrs( + lpo->acceptbuffer, 0, sizeof(SOCKADDR_STORAGE) + 16, + sizeof(SOCKADDR_STORAGE) + 16, (LPSOCKADDR *)&localaddr, + &localaddr_len, (LPSOCKADDR *)&remoteaddr, &remoteaddr_len); memmove(&adev->address.type, remoteaddr, remoteaddr_len); adev->address.length = remoteaddr_len; nsock->address = adev->address; @@ -1942,8 +2000,7 @@ internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { UNLOCK(&nsock->manager->lock); socket_log(__LINE__, sock, &nsock->address, CREATION, - "accepted_connection new_socket %p fd %d", - nsock, nsock->fd); + "accepted_connection new_socket %p fd %d", nsock, nsock->fd); adev->result = result; send_acceptdone_event(sock, &adev); @@ -2011,7 +2068,10 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) { * Translate other errors into ISC_R_* flavors. */ switch (connect_errno) { -#define ERROR_MATCH(a, b) case a: result = b; break; +#define ERROR_MATCH(a, b) \ + case a: \ + result = b; \ + break; ERROR_MATCH(WSAEACCES, ISC_R_NOPERM); ERROR_MATCH(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(WSAEAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); @@ -2082,12 +2142,12 @@ send_connectdone_abort(isc_socket_t *sock, isc_result_t result) { * Take the data we received in our private buffer, and if any recv() calls on * our list are satisfied, send the corresponding done event. * - * If we need more data (there are still items on the recv_list after we consume all - * our data) then arrange for another system recv() call to fill our buffers. + * If we need more data (there are still items on the recv_list after we consume + * all our data) then arrange for another system recv() call to fill our + * buffers. */ static void -internal_recv(isc_socket_t *sock, int nbytes) -{ +internal_recv(isc_socket_t *sock, int nbytes) { INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -2097,9 +2157,11 @@ internal_recv(isc_socket_t *sock, int nbytes) "internal_recv: %d bytes received", nbytes); /* - * If we got here, the I/O operation succeeded. However, we might still have removed this - * event from our notification list (or never placed it on it due to immediate completion.) - * Handle the reference counting here, and handle the cancellation event just after. + * If we got here, the I/O operation succeeded. However, we might + * still have removed this event from our notification list (or never + * placed it on it due to immediate completion.) + * Handle the reference counting here, and handle the cancellation + * event just after. */ INSIST(sock->pending_iocp > 0); sock->pending_iocp--; @@ -2107,13 +2169,15 @@ internal_recv(isc_socket_t *sock, int nbytes) sock->pending_recv--; /* - * The only way we could have gotten here is that our I/O has successfully completed. - * Update our pointers, and move on. The only odd case here is that we might not - * have received enough data on a TCP stream to satisfy the minimum requirements. If - * this is the case, we will re-issue the recv() call for what we need. + * The only way we could have gotten here is that our I/O has + * successfully completed. Update our pointers, and move on. + * The only odd case here is that we might not have received + * enough data on a TCP stream to satisfy the minimum requirements. + * If this is the case, we will re-issue the recv() call for what + * we need. * - * We do check for a recv() of 0 bytes on a TCP stream. This means the remote end - * has closed. + * We do check for a recv() of 0 bytes on a TCP stream. This + * means the remote end has closed. */ if (nbytes == 0 && sock->type == isc_sockettype_tcp) { send_recvdone_abort(sock, ISC_R_EOF); @@ -2131,15 +2195,16 @@ internal_recv(isc_socket_t *sock, int nbytes) queue_receive_request(sock); /* - * Unlock and/or destroy if we are the last thing this socket has left to do. + * Unlock and/or destroy if we are the last thing this socket has left + * to do. */ maybe_free_socket(&sock, __LINE__); } static void internal_send(isc_socket_t *sock, isc_socketevent_t *dev, - struct msghdr *messagehdr, int nbytes, int send_errno, IoCompletionInfo *lpo) -{ + struct msghdr *messagehdr, int nbytes, int send_errno, + IoCompletionInfo *lpo) { /* * Find out what socket this is and lock it. */ @@ -2152,8 +2217,8 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, "internal_send: task got socket event %p", dev); if (lpo->buf != NULL) { - socket_log(__LINE__, sock, NULL, TRACE, - "free_buffer %p", lpo->buf); + socket_log(__LINE__, sock, NULL, TRACE, "free_buffer %p", + lpo->buf); HeapFree(hHeapHandle, 0, lpo->buf); lpo->buf = NULL; @@ -2166,8 +2231,9 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, sock->pending_send--; /* If the event is no longer in the list we can just return */ - if (!senddone_is_active(sock, dev)) + if (!senddone_is_active(sock, dev)) { goto done; + } /* * Set the error code and send things on its way. @@ -2181,7 +2247,7 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, break; } - done: +done: maybe_free_socket(&sock, __LINE__); } @@ -2190,91 +2256,93 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, * Using these ensures we will not double-send an event. */ static bool -senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev) -{ +senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev) { isc_socketevent_t *ldev; ldev = ISC_LIST_HEAD(sock->send_list); - while (ldev != NULL && ldev != dev) + while (ldev != NULL && ldev != dev) { ldev = ISC_LIST_NEXT(ldev, ev_link); + } return (ldev == NULL ? false : true); } static bool -acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev) -{ +acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev) { isc_socket_newconnev_t *ldev; ldev = ISC_LIST_HEAD(sock->accept_list); - while (ldev != NULL && ldev != dev) + while (ldev != NULL && ldev != dev) { ldev = ISC_LIST_NEXT(ldev, ev_link); + } return (ldev == NULL ? false : true); } static bool -connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev) -{ +connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev) { isc_socket_connev_t *cdev; cdev = ISC_LIST_HEAD(sock->connect_list); - while (cdev != NULL && cdev != dev) + while (cdev != NULL && cdev != dev) { cdev = ISC_LIST_NEXT(cdev, ev_link); + } return (cdev == NULL ? false : true); } -// -// The Windows network stack seems to have two very distinct paths depending -// on what is installed. Specifically, if something is looking at network -// connections (like an anti-virus or anti-malware application, such as -// McAfee products) Windows may return additional error conditions which -// were not previously returned. -// -// One specific one is when a TCP SYN scan is used. In this situation, -// Windows responds with the SYN-ACK, but the scanner never responds with -// the 3rd packet, the ACK. Windows consiers this a partially open connection. -// Most Unix networking stacks, and Windows without McAfee installed, will -// not return this to the caller. However, with this product installed, -// Windows returns this as a failed status on the Accept() call. Here, we -// will just re-issue the ISCAcceptEx() call as if nothing had happened. -// -// This code should only be called when the listening socket has received -// such an error. Additionally, the "parent" socket must be locked. -// Additionally, the lpo argument is re-used here, and must not be freed -// by the caller. -// +/* */ +/* The Windows network stack seems to have two very distinct paths depending */ +/* on what is installed. Specifically, if something is looking at network */ +/* connections (like an anti-virus or anti-malware application, such as */ +/* McAfee products) Windows may return additional error conditions which */ +/* were not previously returned. */ +/* */ +/* One specific one is when a TCP SYN scan is used. In this situation, */ +/* Windows responds with the SYN-ACK, but the scanner never responds with */ +/* the 3rd packet, the ACK. Windows considers this a partially open connection. + */ +/* Most Unix networking stacks, and Windows without McAfee installed, will */ +/* not return this to the caller. However, with this product installed, */ +/* Windows returns this as a failed status on the Accept() call. Here, we */ +/* will just re-issue the ISCAcceptEx() call as if nothing had happened. */ +/* */ +/* This code should only be called when the listening socket has received */ +/* such an error. Additionally, the "parent" socket must be locked. */ +/* Additionally, the lpo argument is re-used here, and must not be freed */ +/* by the caller. */ +/* */ static isc_result_t -restart_accept(isc_socket_t *parent, IoCompletionInfo *lpo) -{ +restart_accept(isc_socket_t *parent, IoCompletionInfo *lpo) { isc_socket_t *nsock = lpo->adev->newsocket; SOCKET new_fd; /* * AcceptEx() requires we pass in a socket. Note that we carefully - * do not close the previous socket in case of an error message returned by - * our new socket() call. If we return an error here, our caller will - * clean up. + * do not close the previous socket in case of an error message returned + * by our new socket() call. If we return an error here, our caller + * will clean up. */ new_fd = socket(parent->pf, SOCK_STREAM, IPPROTO_TCP); if (nsock->fd == INVALID_SOCKET) { - return (ISC_R_FAILURE); // parent will ask windows for error message + return (ISC_R_FAILURE); /* parent will ask windows for error */ + /* message */ } closesocket(nsock->fd); nsock->fd = new_fd; memset(&lpo->overlapped, 0, sizeof(lpo->overlapped)); - ISCAcceptEx(parent->fd, - nsock->fd, /* Accepted Socket */ - lpo->acceptbuffer, /* Buffer for initial Recv */ - 0, /* Length of Buffer */ - sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 */ - sizeof(SOCKADDR_STORAGE) + 16, /* Remote address lengh + 16 */ - (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ - (LPOVERLAPPED)lpo /* Overlapped structure */ - ); + ISCAcceptEx(parent->fd, nsock->fd, /* Accepted Socket */ + lpo->acceptbuffer, /* Buffer for initial Recv */ + 0, /* Length of Buffer */ + sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 + */ + sizeof(SOCKADDR_STORAGE) + 16, /* Remote address length + 16 + */ + (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ + (LPOVERLAPPED)lpo /* Overlapped structure */ + ); InterlockedDecrement(&nsock->manager->iocp_total); iocompletionport_update(nsock); @@ -2290,7 +2358,6 @@ restart_accept(isc_socket_t *parent, IoCompletionInfo *lpo) static isc_threadresult_t WINAPI SocketIoThread(LPVOID ThreadContext) { isc_socketmgr_t *manager = ThreadContext; - BOOL bSuccess = FALSE; DWORD nbytes; IoCompletionInfo *lpo = NULL; isc_socket_t *sock = NULL; @@ -2311,8 +2378,7 @@ SocketIoThread(LPVOID ThreadContext) { THREAD_PRIORITY_ABOVE_NORMAL)) { errval = GetLastError(); strerror_r(errval, strbuf, sizeof(strbuf)); - FATAL_ERROR(__FILE__, __LINE__, - "Can't set thread priority: %s", + FATAL_ERROR(__FILE__, __LINE__, "Can't set thread priority: %s", strbuf); } @@ -2320,23 +2386,25 @@ SocketIoThread(LPVOID ThreadContext) { * Loop forever waiting on I/O Completions and then processing them */ while (TRUE) { - wait_again: - bSuccess = GetQueuedCompletionStatus(manager->hIoCompletionPort, - &nbytes, - (PULONG_PTR)&sock, - (LPWSAOVERLAPPED *)&lpo, - INFINITE); - if (lpo == NULL) /* Received request to exit */ + BOOL bSuccess; + + wait_again: + bSuccess = GetQueuedCompletionStatus( + manager->hIoCompletionPort, &nbytes, (PULONG_PTR)&sock, + (LPWSAOVERLAPPED *)&lpo, INFINITE); + if (lpo == NULL) { /* Received request to exit */ break; + } REQUIRE(VALID_SOCKET(sock)); request = lpo->request_type; - if (!bSuccess) + if (!bSuccess) { errstatus = GetLastError(); - else + } else { errstatus = 0; + } if (!bSuccess && errstatus != ERROR_MORE_DATA) { isc_result_t isc_result; @@ -2356,7 +2424,8 @@ SocketIoThread(LPVOID ThreadContext) { if (!sock->connected && ((errstatus == ERROR_HOST_UNREACHABLE) || (errstatus == WSAENETRESET) || - (errstatus == WSAECONNRESET))) { + (errstatus == WSAECONNRESET))) + { /* ignore soft errors */ queue_receive_request(sock); break; @@ -2364,8 +2433,11 @@ SocketIoThread(LPVOID ThreadContext) { send_recvdone_abort(sock, isc_result); if (isc_result == ISC_R_UNEXPECTED) { UNEXPECTED_ERROR(__FILE__, __LINE__, - "SOCKET_RECV: Windows error code: %d, returning ISC error %d", - errstatus, isc_result); + "SOCKET_RECV: Windows " + "error code: %d, " + "returning ISC error " + "%d", + errstatus, isc_result); } break; @@ -2377,7 +2449,7 @@ SocketIoThread(LPVOID ThreadContext) { if (senddone_is_active(sock, lpo->dev)) { lpo->dev->result = isc_result; socket_log(__LINE__, sock, NULL, EVENT, - "canceled_send"); + "canceled_send"); send_senddone_event(sock, &lpo->dev); } break; @@ -2387,19 +2459,26 @@ SocketIoThread(LPVOID ThreadContext) { INSIST(sock->pending_accept > 0); socket_log(__LINE__, sock, NULL, EVENT, - "Accept: errstatus=%d isc_result=%d", + "Accept: errstatus=%d isc_result=%d", errstatus, isc_result); if (acceptdone_is_active(sock, lpo->adev)) { - if (restart_accept(sock, lpo) == ISC_R_SUCCESS) { + if (restart_accept(sock, lpo) == + ISC_R_SUCCESS) { UNLOCK(&sock->lock); goto wait_again; } else { errstatus = GetLastError(); - isc_result = isc__errno2result(errstatus); - socket_log(__LINE__, sock, NULL, EVENT, - "restart_accept() failed: errstatus=%d isc_result=%d", - errstatus, isc_result); + isc_result = isc__errno2result( + errstatus); + socket_log(__LINE__, sock, NULL, + EVENT, + "restart_accept() " + "failed: " + "errstatus=%d " + "isc_result=%d", + errstatus, + isc_result); } } @@ -2407,12 +2486,16 @@ SocketIoThread(LPVOID ThreadContext) { sock->pending_accept--; if (acceptdone_is_active(sock, lpo->adev)) { closesocket(lpo->adev->newsocket->fd); - lpo->adev->newsocket->fd = INVALID_SOCKET; - lpo->adev->newsocket->references--; - free_socket(&lpo->adev->newsocket, __LINE__); + lpo->adev->newsocket->fd = + INVALID_SOCKET; + isc_refcount_decrementz( + &lpo->adev->newsocket + ->references); + free_socket(&lpo->adev->newsocket, + __LINE__); lpo->adev->result = isc_result; socket_log(__LINE__, sock, NULL, EVENT, - "canceled_accept"); + "canceled_accept"); send_acceptdone_event(sock, &lpo->adev); } break; @@ -2424,15 +2507,17 @@ SocketIoThread(LPVOID ThreadContext) { sock->pending_connect = 0; if (connectdone_is_active(sock, lpo->cdev)) { socket_log(__LINE__, sock, NULL, EVENT, - "canceled_connect"); - send_connectdone_abort(sock, isc_result); + "canceled_connect"); + send_connectdone_abort(sock, + isc_result); } break; } maybe_free_socket(&sock, __LINE__); - if (lpo != NULL) + if (lpo != NULL) { HeapFree(hHeapHandle, 0, lpo); + } continue; } @@ -2443,7 +2528,8 @@ SocketIoThread(LPVOID ThreadContext) { internal_recv(sock, nbytes); break; case SOCKET_SEND: - internal_send(sock, lpo->dev, messagehdr, nbytes, errstatus, lpo); + internal_send(sock, lpo->dev, messagehdr, nbytes, + errstatus, lpo); break; case SOCKET_ACCEPT: internal_accept(sock, lpo, errstatus); @@ -2453,8 +2539,9 @@ SocketIoThread(LPVOID ThreadContext) { break; } - if (lpo != NULL) + if (lpo != NULL) { HeapFree(hHeapHandle, 0, lpo); + } } /* @@ -2474,19 +2561,16 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { isc_result_t isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, - unsigned int maxsocks, int nthreads) -{ + unsigned int maxsocks, int nthreads) { isc_socketmgr_t *manager; - isc_result_t result; REQUIRE(managerp != NULL && *managerp == NULL); - if (maxsocks != 0) + if (maxsocks != 0) { return (ISC_R_NOTIMPLEMENTED); + } manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); InitSockets(); @@ -2503,11 +2587,12 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, } manager->maxIOCPThreads = min(nthreads, MAX_IOCPTHREADS); - iocompletionport_init(manager); /* Create the Completion Ports */ + iocompletionport_init(manager); /* Create the Completion Ports */ manager->bShutdown = false; manager->totalSockets = 0; manager->iocp_total = 0; + manager->maxudp = 0; *managerp = manager; @@ -2535,8 +2620,6 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) { void isc_socketmgr_destroy(isc_socketmgr_t **managerp) { isc_socketmgr_t *manager; - int i; - isc_mem_t *mctx; /* * Destroy a socket manager. @@ -2544,6 +2627,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { REQUIRE(managerp != NULL); manager = *managerp; + *managerp = NULL; REQUIRE(VALID_MANAGER(manager)); LOCK(&manager->lock); @@ -2568,11 +2652,8 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { /* * Wait for threads to exit. */ - for (i = 0; i < manager->maxIOCPThreads; i++) { - if (isc_thread_join((isc_thread_t) manager->hIOCPThreads[i], - NULL) != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_thread_join() for Completion Port failed"); + for (int i = 0; i < manager->maxIOCPThreads; i++) { + isc_thread_join((isc_thread_t)manager->hIOCPThreads[i], NULL); } /* * Clean up. @@ -2583,20 +2664,16 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { (void)isc_condition_destroy(&manager->shutdown_ok); isc_mutex_destroy(&manager->lock); - if (manager->stats != NULL) + if (manager->stats != NULL) { isc_stats_detach(&manager->stats); + } manager->magic = 0; - mctx= manager->mctx; - isc_mem_put(mctx, manager, sizeof(*manager)); - - isc_mem_detach(&mctx); - - *managerp = NULL; + isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager)); } static void -queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev) -{ +queue_receive_event(isc_socket_t *sock, isc_task_t *task, + isc_socketevent_t *dev) { isc_task_t *ntask = NULL; isc_task_attach(task, &ntask); @@ -2609,27 +2686,26 @@ queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link); socket_log(__LINE__, sock, NULL, EVENT, - "queue_receive_event: event %p -> task %p", - dev, ntask); + "queue_receive_event: event %p -> task %p", dev, ntask); } /* * Check the pending receive queue, and if we have data pending, give it to this - * caller. If we have none, queue an I/O request. If this caller is not the first - * on the list, then we will just queue this event and return. + * caller. If we have none, queue an I/O request. If this caller is not the + * first on the list, then we will just queue this event and return. * * Caller must have the socket locked. */ static isc_result_t socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, - unsigned int flags) -{ + unsigned int flags) { isc_result_t result = ISC_R_SUCCESS; dev->ev_sender = task; - if (sock->fd == INVALID_SOCKET) + if (sock->fd == INVALID_SOCKET) { return (ISC_R_EOF); + } /* * Queue our event on the list of things to do. Call our function to @@ -2638,8 +2714,9 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, * here and tell our caller that we could not satisfy it immediately. */ queue_receive_event(sock, task, dev); - if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) + if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) { result = ISC_R_INPROGRESS; + } completeio_recv(sock); @@ -2653,10 +2730,8 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, } isc_result_t -isc_socket_recv(isc_socket_t *sock, isc_region_t *region, - unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, void *arg) -{ +isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, + isc_task_t *task, isc_taskaction_t action, void *arg) { isc_socketevent_t *dev; isc_socketmgr_t *manager; isc_result_t ret; @@ -2679,8 +2754,8 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, INSIST(sock->bound); - dev = allocate_socketevent(manager->mctx, sock, - ISC_SOCKEVENT_RECVDONE, action, arg); + dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, + action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); @@ -2692,10 +2767,9 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, } isc_result_t -isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, - unsigned int minimum, isc_task_t *task, - isc_socketevent_t *event, unsigned int flags) -{ +isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, + isc_task_t *task, isc_socketevent_t *event, + unsigned int flags) { isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); @@ -2720,13 +2794,14 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, /* * UDP sockets are always partial read. */ - if (sock->type == isc_sockettype_udp) + if (sock->type == isc_sockettype_udp) { event->minimum = 1; - else { - if (minimum == 0) + } else { + if (minimum == 0) { event->minimum = region->length; - else + } else { event->minimum = minimum; + } } ret = socket_recv(sock, event, task, flags); @@ -2740,8 +2815,7 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, static isc_result_t socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, - unsigned int flags) -{ + unsigned int flags) { int io_state; int send_errno = 0; int cc = 0; @@ -2767,7 +2841,7 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, io_state = startio_send(sock, dev, &cc, &send_errno); switch (io_state) { - case DOIO_PENDING: /* I/O started. Enqueue completion event. */ + case DOIO_PENDING: /* I/O started. Enqueue completion event. */ case DOIO_SOFT: /* * We couldn't send all or part of the request right now, so @@ -2785,11 +2859,12 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link); socket_log(__LINE__, sock, NULL, EVENT, - "socket_send: event %p -> task %p", - dev, ntask); + "socket_send: event %p -> task %p", dev, + ntask); - if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) + if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) { result = ISC_R_INPROGRESS; + } break; } @@ -2801,21 +2876,18 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, } isc_result_t -isc_socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ +isc_socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg) { /* * REQUIRE() checking is performed in isc_socket_sendto(). */ - return (isc_socket_sendto(sock, region, task, action, arg, NULL, - NULL)); + return (isc_socket_sendto(sock, region, task, action, arg, NULL, NULL)); } isc_result_t -isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, void *arg, - const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) -{ +isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, + isc_taskaction_t action, void *arg, + const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { isc_socketevent_t *dev; isc_socketmgr_t *manager; isc_result_t ret; @@ -2841,8 +2913,8 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, INSIST(sock->bound); - dev = allocate_socketevent(manager->mctx, sock, - ISC_SOCKEVENT_SENDDONE, action, arg); + dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, + action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); @@ -2857,17 +2929,18 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_result_t isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, - isc_socketevent_t *event, unsigned int flags) -{ + isc_socketevent_t *event, unsigned int flags) { isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); - REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0); - if ((flags & ISC_SOCKFLAG_NORETRY) != 0) + REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE | ISC_SOCKFLAG_NORETRY)) == + 0); + if ((flags & ISC_SOCKFLAG_NORETRY) != 0) { REQUIRE(sock->type == isc_sockettype_udp); + } event->ev_sender = sock; event->result = ISC_R_UNEXPECTED; /* @@ -2889,8 +2962,7 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_result_t isc_socket_bind(isc_socket_t *sock, const isc_sockaddr_t *sockaddr, - isc_socket_options_t options) -{ + isc_socket_options_t options) { int bind_errno; char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -2922,8 +2994,8 @@ isc_socket_bind(isc_socket_t *sock, const isc_sockaddr_t *sockaddr, setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d) failed", sock->fd); + UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d) failed", + sock->fd); /* Press on... */ } if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) { @@ -2977,7 +3049,7 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { char strbuf[ISC_STRERRORSIZE]; #if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) char on = 1; -#endif +#endif /* if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) */ REQUIRE(VALID_SOCKET(sock)); @@ -2996,8 +3068,9 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { REQUIRE(sock->bound); REQUIRE(sock->type == isc_sockettype_tcp); - if (backlog == 0) + if (backlog == 0) { backlog = SOMAXCONN; + } if (listen(sock->fd, (int)backlog) < 0) { UNLOCK(&sock->lock); @@ -3009,15 +3082,15 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { } #if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) - if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN, - &on, sizeof(on)) < 0) { + if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN, &on, sizeof(on)) < + 0) { strerror_r(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, TCP_FASTOPEN) failed with %s", sock->fd, strbuf); /* TCP_FASTOPEN is experimental so ignore failures */ } -#endif +#endif /* if defined(ENABLE_TCP_FASTOPEN) && defined(TCP_FASTOPEN) */ socket_log(__LINE__, sock, NULL, TRACE, "listening"); sock->listener = 1; @@ -3031,9 +3104,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { * This should try to do aggressive accept() XXXMLG */ isc_result_t -isc_socket_accept(isc_socket_t *sock, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ +isc_socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, + void *arg) { isc_socket_newconnev_t *adev; isc_socketmgr_t *manager; isc_task_t *ntask = NULL; @@ -3064,13 +3136,9 @@ isc_socket_accept(isc_socket_t *sock, * this event to. Just before the actual event is delivered the * actual ev_sender will be touched up to be the socket. */ - adev = (isc_socket_newconnev_t *) - isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN, - action, arg, sizeof(*adev)); - if (adev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } + adev = (isc_socket_newconnev_t *)isc_event_allocate( + manager->mctx, task, ISC_SOCKEVENT_NEWCONN, action, arg, + sizeof(*adev)); ISC_LINK_INIT(adev, ev_link); result = allocate_socket(manager, sock->type, &nsock); @@ -3088,7 +3156,7 @@ isc_socket_accept(isc_socket_t *sock, free_socket(&nsock, __LINE__); isc_event_free((isc_event_t **)&adev); UNLOCK(&sock->lock); - return (ISC_R_FAILURE); // XXXMLG need real error message + return (ISC_R_FAILURE); /* XXXMLG need real error message */ } /* @@ -3102,7 +3170,7 @@ isc_socket_accept(isc_socket_t *sock, UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } - nsock->references++; + isc_refcount_increment0(&nsock->references); adev->ev_sender = ntask; adev->newsocket = nsock; @@ -3111,30 +3179,31 @@ isc_socket_accept(isc_socket_t *sock, /* * Queue io completion for an accept(). */ - lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, - HEAP_ZERO_MEMORY, + lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); - lpo->acceptbuffer = (void *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, - (sizeof(SOCKADDR_STORAGE) + 16) * 2); + lpo->acceptbuffer = + (void *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, + (sizeof(SOCKADDR_STORAGE) + 16) * 2); RUNTIME_CHECK(lpo->acceptbuffer != NULL); lpo->adev = adev; lpo->request_type = SOCKET_ACCEPT; - ISCAcceptEx(sock->fd, - nsock->fd, /* Accepted Socket */ - lpo->acceptbuffer, /* Buffer for initial Recv */ - 0, /* Length of Buffer */ - sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 */ - sizeof(SOCKADDR_STORAGE) + 16, /* Remote address lengh + 16 */ - (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ - (LPOVERLAPPED)lpo /* Overlapped structure */ - ); + ISCAcceptEx(sock->fd, nsock->fd, /* Accepted Socket */ + lpo->acceptbuffer, /* Buffer for initial Recv */ + 0, /* Length of Buffer */ + sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 + */ + sizeof(SOCKADDR_STORAGE) + 16, /* Remote address length + 16 + */ + (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ + (LPOVERLAPPED)lpo /* Overlapped structure */ + ); iocompletionport_update(nsock); - socket_log(__LINE__, sock, NULL, TRACE, - "accepting for nsock %p fd %d", nsock, nsock->fd); + socket_log(__LINE__, sock, NULL, TRACE, "accepting for nsock %p fd %d", + nsock, nsock->fd); /* * Enqueue the event @@ -3149,8 +3218,7 @@ isc_socket_accept(isc_socket_t *sock, isc_result_t isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addr, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ + isc_task_t *task, isc_taskaction_t action, void *arg) { char strbuf[ISC_STRERRORSIZE]; isc_socket_connev_t *cdev; isc_task_t *ntask = NULL; @@ -3167,8 +3235,9 @@ isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addr, REQUIRE(VALID_MANAGER(manager)); REQUIRE(addr != NULL); - if (isc_sockaddr_ismulticast(addr)) + if (isc_sockaddr_ismulticast(addr)) { return (ISC_R_MULTICAST); + } LOCK(&sock->lock); CONSISTENT(sock); @@ -3201,24 +3270,18 @@ isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addr, case WSAEINVAL: return (ISC_R_BOUND); default: - strerror_r(bind_errno, strbuf, - sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "bind: %s", strbuf); + strerror_r(bind_errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s", + strbuf); return (ISC_R_UNEXPECTED); } } sock->bound = 1; } - cdev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock, - ISC_SOCKEVENT_CONNECT, - action, arg, - sizeof(*cdev)); - if (cdev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } + cdev = (isc_socket_connev_t *)isc_event_allocate( + manager->mctx, sock, ISC_SOCKEVENT_CONNECT, action, arg, + sizeof(*cdev)); ISC_LINK_INIT(cdev, ev_link); if (sock->connected) { @@ -3241,8 +3304,8 @@ isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addr, lpo->request_type = SOCKET_CONNECT; sock->address = *addr; - ISCConnectEx(sock->fd, &addr->type.sa, addr->length, - NULL, 0, NULL, (LPOVERLAPPED)lpo); + ISCConnectEx(sock->fd, &addr->type.sa, addr->length, NULL, 0, + NULL, (LPOVERLAPPED)lpo); /* * Attach to task. @@ -3268,7 +3331,8 @@ isc_socket_connect(isc_socket_t *sock, const isc_sockaddr_t *addr, ISC_LIST_ENQUEUE(sock->connect_list, cdev, ev_link); } else { REQUIRE(!sock->pending_connect); - WSAConnect(sock->fd, &addr->type.sa, addr->length, NULL, NULL, NULL, NULL); + WSAConnect(sock->fd, &addr->type.sa, addr->length, NULL, NULL, + NULL, NULL); cdev->result = ISC_R_SUCCESS; isc_task_send(task, (isc_event_t **)&cdev); } @@ -3338,14 +3402,13 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { len = sizeof(addressp->type); if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) { strerror_r(WSAGetLastError(), strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", - strbuf); + UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", strbuf); result = ISC_R_UNEXPECTED; goto out; } addressp->length = (unsigned int)len; - out: +out: UNLOCK(&sock->lock); return (result); @@ -3357,15 +3420,15 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { */ void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { - REQUIRE(VALID_SOCKET(sock)); /* * Quick exit if there is nothing to do. Don't even bother locking * in this case. */ - if (how == 0) + if (how == 0) { return; + } LOCK(&sock->lock); CONSISTENT(sock); @@ -3390,9 +3453,9 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { */ if ((how & ISC_SOCKCANCEL_RECV) != 0) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; + isc_socketevent_t *dev; + isc_socketevent_t *next; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->recv_list); while (dev != NULL) { @@ -3408,9 +3471,9 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { how &= ~ISC_SOCKCANCEL_RECV; if ((how & ISC_SOCKCANCEL_SEND) != 0) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; + isc_socketevent_t *dev; + isc_socketevent_t *next; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->send_list); @@ -3426,11 +3489,11 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { } how &= ~ISC_SOCKCANCEL_SEND; - if (((how & ISC_SOCKCANCEL_ACCEPT) != 0) - && !ISC_LIST_EMPTY(sock->accept_list)) { + if (((how & ISC_SOCKCANCEL_ACCEPT) != 0) && + !ISC_LIST_EMPTY(sock->accept_list)) { isc_socket_newconnev_t *dev; isc_socket_newconnev_t *next; - isc_task_t *current_task; + isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->accept_list); while (dev != NULL) { @@ -3438,8 +3501,8 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { - - dev->newsocket->references--; + isc_refcount_decrementz( + &dev->newsocket->references); closesocket(dev->newsocket->fd); dev->newsocket->fd = INVALID_SOCKET; free_socket(&dev->newsocket, __LINE__); @@ -3453,11 +3516,12 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { } how &= ~ISC_SOCKCANCEL_ACCEPT; - if (((how & ISC_SOCKCANCEL_CONNECT) != 0) - && !ISC_LIST_EMPTY(sock->connect_list)) { - isc_socket_connev_t *dev; - isc_socket_connev_t *next; - isc_task_t *current_task; + if (((how & ISC_SOCKCANCEL_CONNECT) != 0) && + !ISC_LIST_EMPTY(sock->connect_list)) + { + isc_socket_connev_t *dev; + isc_socket_connev_t *next; + isc_task_t *current_task; INSIST(sock->pending_connect); @@ -3477,6 +3541,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { _set_state(sock, SOCK_CLOSED); } how &= ~ISC_SOCKCANCEL_CONNECT; + UNUSED(how); maybe_free_socket(&sock, __LINE__); } @@ -3506,9 +3571,9 @@ void isc_socket_ipv6only(isc_socket_t *sock, bool yes) { #if defined(IPV6_V6ONLY) int onoff = yes ? 1 : 0; -#else +#else /* if defined(IPV6_V6ONLY) */ UNUSED(yes); -#endif +#endif /* if defined(IPV6_V6ONLY) */ REQUIRE(VALID_SOCKET(sock)); @@ -3517,35 +3582,36 @@ isc_socket_ipv6only(isc_socket_t *sock, bool yes) { (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&onoff, sizeof(onoff)); } -#endif +#endif /* ifdef IPV6_V6ONLY */ } void isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) { #if !defined(IP_TOS) && !defined(IPV6_TCLASS) UNUSED(dscp); -#else - if (dscp < 0) +#else /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */ + if (dscp < 0) { return; + } dscp <<= 2; dscp &= 0xff; -#endif +#endif /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */ REQUIRE(VALID_SOCKET(sock)); #ifdef IP_TOS if (sock->pf == AF_INET) { - (void)setsockopt(sock->fd, IPPROTO_IP, IP_TOS, - (char *)&dscp, sizeof(dscp)); + (void)setsockopt(sock->fd, IPPROTO_IP, IP_TOS, (char *)&dscp, + sizeof(dscp)); } -#endif +#endif /* ifdef IP_TOS */ #ifdef IPV6_TCLASS if (sock->pf == AF_INET6) { (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, (char *)&dscp, sizeof(dscp)); } -#endif +#endif /* ifdef IPV6_TCLASS */ } void @@ -3555,9 +3621,8 @@ isc_socket_cleanunix(const isc_sockaddr_t *addr, bool active) { } isc_result_t -isc_socket_permunix(const isc_sockaddr_t *addr, uint32_t perm, - uint32_t owner, uint32_t group) -{ +isc_socket_permunix(const isc_sockaddr_t *addr, uint32_t perm, uint32_t owner, + uint32_t group) { UNUSED(addr); UNUSED(perm); UNUSED(owner); @@ -3567,7 +3632,6 @@ isc_socket_permunix(const isc_sockaddr_t *addr, uint32_t perm, void isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) { - /* * Name 'socket'. */ @@ -3592,7 +3656,7 @@ isc_socket_gettag(isc_socket_t *socket) { int isc_socket_getfd(isc_socket_t *socket) { - return ((short) socket->fd); + return ((short)socket->fd); } void @@ -3602,10 +3666,8 @@ isc_socketmgr_setreserved(isc_socketmgr_t *manager, uint32_t reserved) { } isc_socketevent_t * -isc_socket_socketevent(isc_mem_t *mctx, void *sender, - isc_eventtype_t eventtype, isc_taskaction_t action, - void *arg) -{ +isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, + isc_taskaction_t action, void *arg) { return (allocate_socketevent(mctx, sender, eventtype, action, arg)); } @@ -3630,15 +3692,20 @@ _socktype(isc_sockettype_t type) { } } -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +#define TRY0(a) \ + do { \ + xmlrc = (a); \ + if (xmlrc < 0) \ + goto error; \ + } while (0) int -isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer) -{ +isc_socketmgr_renderxml(isc_socketmgr_t *mgr, void *writer0) { isc_socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; socklen_t len; int xmlrc; + xmlTextWriterPtr writer = (xmlTextWriterPtr)writer0; LOCK(&mgr->lock); @@ -3662,58 +3729,67 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer) TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); - TRY0(xmlTextWriterWriteFormatString(writer, "%d", - sock->references)); + TRY0(xmlTextWriterWriteFormatString( + writer, "%" PRIuFAST32, + isc_refcount_current(&sock->references))); TRY0(xmlTextWriterEndElement(writer)); - TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR _socktype(sock->type))); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "type", + ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->address, peerbuf, sizeof(peerbuf)); - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "peer-address", - ISC_XMLCHAR peerbuf)); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "peer-address", + ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "local-address", - ISC_XMLCHAR peerbuf)); + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "local-address", + ISC_XMLCHAR peerbuf)); } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); - if (sock->pending_recv) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-receive")); - if (sock->pending_send) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-send")); - if (sock->pending_accept) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "pending_accept")); - if (sock->listener) + if (sock->pending_recv) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-receive")); + } + if (sock->pending_send) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-send")); + } + if (sock->pending_accept) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "pending_accept")); + } + if (sock->listener) { TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "listener")); - if (sock->connected) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "connected")); - if (sock->pending_connect) - TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "connecting")); - if (sock->bound) + } + if (sock->connected) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "connected")); + } + if (sock->pending_connect) { + TRY0(xmlTextWriterWriteElement( + writer, ISC_XMLCHAR "state", + ISC_XMLCHAR "connecting")); + } + if (sock->bound) { TRY0(xmlTextWriterWriteElement(writer, - ISC_XMLCHAR "state", - ISC_XMLCHAR "bound")); + ISC_XMLCHAR "state", + ISC_XMLCHAR "bound")); + } TRY0(xmlTextWriterEndElement(writer)); /* states */ @@ -3725,8 +3801,9 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer) TRY0(xmlTextWriterEndElement(writer)); /* sockets */ error: - if (sock != NULL) + if (sock != NULL) { UNLOCK(&sock->lock); + } UNLOCK(&mgr->lock); @@ -3734,22 +3811,23 @@ error: } #endif /* HAVE_LIBXML2 */ -#ifdef HAVE_JSON -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) - +#ifdef HAVE_JSON_C +#define CHECKMEM(m) \ + do { \ + if (m == NULL) { \ + result = ISC_R_NOMEMORY; \ + goto error; \ + } \ + } while (0) isc_result_t -isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats) { +isc_socketmgr_renderjson(isc_socketmgr_t *mgr, void *stats0) { isc_result_t result = ISC_R_SUCCESS; isc_socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; socklen_t len; json_object *obj, *array = json_object_new_array(); + json_object *stats = (json_object *)stats; CHECKMEM(array); @@ -3759,7 +3837,7 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats) { obj = json_object_new_int(mgr->refs); CHECKMEM(obj); json_object_object_add(stats, "references", obj); -#endif /* USE_SHARED_MANAGER */ +#endif /* USE_SHARED_MANAGER */ sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { @@ -3782,7 +3860,8 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats) { json_object_object_add(entry, "name", obj); } - obj = json_object_new_int(sock->references); + obj = json_object_new_int( + isc_refcount_current(&sock->references)); CHECKMEM(obj); json_object_object_add(entry, "references", obj); @@ -3860,36 +3939,33 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats) { array = NULL; result = ISC_R_SUCCESS; - error: - if (array != NULL) +error: + if (array != NULL) { json_object_put(array); + } - if (sock != NULL) + if (sock != NULL) { UNLOCK(&sock->lock); + } UNLOCK(&mgr->lock); return (result); } -#endif /* HAVE_JSON */ +#endif /* HAVE_JSON_C */ isc_result_t -isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, - isc_socketmgr_t **managerp) -{ +isc_socketmgr_createinctx(isc_mem_t *mctx, isc_socketmgr_t **managerp) { isc_result_t result; result = isc_socketmgr_create(mctx, managerp); - if (result == ISC_R_SUCCESS) - isc_appctx_setsocketmgr(actx, *managerp); - return (result); } -/* Not implemented for win32 */ void -isc_socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) { - UNUSED(manager); - UNUSED(maxudp); +isc_socketmgr_maxudp(isc_socketmgr_t *manager, unsigned int maxudp) { + REQUIRE(VALID_MANAGER(manager)); + + manager->maxudp = maxudp; } diff --git a/lib/isc/win32/stdio.c b/lib/isc/win32/stdio.c index a4c81345..d77a640a 100644 --- a/lib/isc/win32/stdio.c +++ b/lib/isc/win32/stdio.c @@ -3,24 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - -#include <io.h> #include <errno.h> +#include <io.h> +#include <sys/stat.h> +#include <sys/types.h> #include <isc/stdio.h> #include <isc/util.h> -#include <sys/stat.h> -#include <sys/types.h> - #include "errno2result.h" isc_result_t @@ -28,8 +24,9 @@ isc_stdio_open(const char *filename, const char *mode, FILE **fp) { FILE *f; f = fopen(filename, mode); - if (f == NULL) + if (f == NULL) { return (isc__errno2result(errno)); + } *fp = f; return (ISC_R_SUCCESS); } @@ -39,10 +36,11 @@ isc_stdio_close(FILE *f) { int r; r = fclose(f); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -51,35 +49,37 @@ isc_stdio_seek(FILE *f, off_t offset, int whence) { #ifndef _WIN64 r = fseek(f, offset, whence); -#else +#else /* ifndef _WIN64 */ r = _fseeki64(f, offset, whence); -#endif - if (r == 0) +#endif /* ifndef _WIN64 */ + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t isc_stdio_tell(FILE *f, off_t *offsetp) { #ifndef _WIN64 long r; -#else +#else /* ifndef _WIN64 */ __int64 r; -#endif +#endif /* ifndef _WIN64 */ REQUIRE(offsetp != NULL); #ifndef _WIN64 r = ftell(f); -#else +#else /* ifndef _WIN64 */ r = _ftelli64(f); -#endif +#endif /* ifndef _WIN64 */ if (r >= 0) { *offsetp = r; return (ISC_R_SUCCESS); - } else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -90,29 +90,32 @@ isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { clearerr(f); r = fread(ptr, size, nmemb, f); if (r != nmemb) { - if (feof(f)) + if (feof(f)) { result = ISC_R_EOF; - else + } else { result = isc__errno2result(errno); + } } - if (nret != NULL) + if (nret != NULL) { *nret = r; + } return (result); } isc_result_t isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, - size_t *nret) -{ + size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fwrite(ptr, size, nmemb, f); - if (r != nmemb) + if (r != nmemb) { result = isc__errno2result(errno); - if (nret != NULL) + } + if (nret != NULL) { *nret = r; + } return (result); } @@ -121,10 +124,11 @@ isc_stdio_flush(FILE *f) { int r; r = fflush(f); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } isc_result_t @@ -132,19 +136,21 @@ isc_stdio_sync(FILE *f) { struct _stat buf; int r; - if (_fstat(_fileno(f), &buf) != 0) + if (_fstat(_fileno(f), &buf) != 0) { return (isc__errno2result(errno)); + } /* * Only call _commit() on regular files. */ - if ((buf.st_mode & S_IFMT) != S_IFREG) + if ((buf.st_mode & S_IFMT) != S_IFREG) { return (ISC_R_SUCCESS); + } r = _commit(_fileno(f)); - if (r == 0) + if (r == 0) { return (ISC_R_SUCCESS); - else + } else { return (isc__errno2result(errno)); + } } - diff --git a/lib/isc/win32/stdtime.c b/lib/isc/win32/stdtime.c index bff6fd18..cff510a7 100644 --- a/lib/isc/win32/stdtime.c +++ b/lib/isc/win32/stdtime.c @@ -3,15 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <time.h> #include <isc/assertions.h> @@ -28,3 +25,17 @@ isc_stdtime_get(isc_stdtime_t *t) { (void)_time32(t); } + +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen) { + time_t when; + + REQUIRE(out != NULL); + /* Minimum buffer as per ctime_r() specification. */ + REQUIRE(outlen >= 26); + + /* time_t and isc_stdtime_t might be different sizes */ + when = t; + INSIST((ctime_s(out, outlen, &when) == 0)); + *(out + strlen(out) - 1) = '\0'; +} diff --git a/lib/isc/win32/syslog.c b/lib/isc/win32/syslog.c index 071e1878..96403e16 100644 --- a/lib/isc/win32/syslog.c +++ b/lib/isc/win32/syslog.c @@ -3,20 +3,17 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <stdio.h> -#include <windows.h> -#include <string.h> #include <stdlib.h> +#include <string.h> #include <syslog.h> +#include <windows.h> #include <isc/bindevt.h> #include <isc/result.h> @@ -30,39 +27,37 @@ static int debug_level = 0; static struct dsn_c_pvt_sfnt { int val; const char *strval; -} facilities[] = { - { LOG_KERN, "kern" }, - { LOG_USER, "user" }, - { LOG_MAIL, "mail" }, - { LOG_DAEMON, "daemon" }, - { LOG_AUTH, "auth" }, - { LOG_SYSLOG, "syslog" }, - { LOG_LPR, "lpr" }, +} facilities[] = { { LOG_KERN, "kern" }, + { LOG_USER, "user" }, + { LOG_MAIL, "mail" }, + { LOG_DAEMON, "daemon" }, + { LOG_AUTH, "auth" }, + { LOG_SYSLOG, "syslog" }, + { LOG_LPR, "lpr" }, #ifdef LOG_NEWS - { LOG_NEWS, "news" }, -#endif + { LOG_NEWS, "news" }, +#endif /* ifdef LOG_NEWS */ #ifdef LOG_UUCP - { LOG_UUCP, "uucp" }, -#endif + { LOG_UUCP, "uucp" }, +#endif /* ifdef LOG_UUCP */ #ifdef LOG_CRON - { LOG_CRON, "cron" }, -#endif + { LOG_CRON, "cron" }, +#endif /* ifdef LOG_CRON */ #ifdef LOG_AUTHPRIV - { LOG_AUTHPRIV, "authpriv" }, -#endif + { LOG_AUTHPRIV, "authpriv" }, +#endif /* ifdef LOG_AUTHPRIV */ #ifdef LOG_FTP - { LOG_FTP, "ftp" }, -#endif - { LOG_LOCAL0, "local0"}, - { LOG_LOCAL1, "local1"}, - { LOG_LOCAL2, "local2"}, - { LOG_LOCAL3, "local3"}, - { LOG_LOCAL4, "local4"}, - { LOG_LOCAL5, "local5"}, - { LOG_LOCAL6, "local6"}, - { LOG_LOCAL7, "local7"}, - { 0, NULL } -}; + { LOG_FTP, "ftp" }, +#endif /* ifdef LOG_FTP */ + { LOG_LOCAL0, "local0" }, + { LOG_LOCAL1, "local1" }, + { LOG_LOCAL2, "local2" }, + { LOG_LOCAL3, "local3" }, + { LOG_LOCAL4, "local4" }, + { LOG_LOCAL5, "local5" }, + { LOG_LOCAL6, "local6" }, + { LOG_LOCAL7, "local7" }, + { 0, NULL } }; isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp) { @@ -167,8 +162,8 @@ NTReportError(const char *name, const char *str) { hNTAppLog = RegisterEventSource(NULL, name); - ReportEvent(hNTAppLog, EVENTLOG_ERROR_TYPE, 0, - BIND_ERR_MSG, NULL, 1, 0, buf, NULL); + ReportEvent(hNTAppLog, EVENTLOG_ERROR_TYPE, 0, BIND_ERR_MSG, NULL, 1, 0, + buf, NULL); DeregisterEventSource(hNTAppLog); } diff --git a/lib/isc/win32/syslog.h b/lib/isc/win32/syslog.h index 01971655..8571158a 100644 --- a/lib/isc/win32/syslog.h +++ b/lib/isc/win32/syslog.h @@ -3,46 +3,45 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - #ifndef _SYSLOG_H #define _SYSLOG_H #include <stdio.h> /* Constant definitions for openlog() */ -#define LOG_PID 1 -#define LOG_CONS 2 +#define LOG_PID 1 +#define LOG_CONS 2 /* NT event log does not support facility level */ -#define LOG_KERN 0 -#define LOG_USER 0 -#define LOG_MAIL 0 -#define LOG_DAEMON 0 -#define LOG_AUTH 0 -#define LOG_SYSLOG 0 -#define LOG_LPR 0 -#define LOG_LOCAL0 0 -#define LOG_LOCAL1 0 -#define LOG_LOCAL2 0 -#define LOG_LOCAL3 0 -#define LOG_LOCAL4 0 -#define LOG_LOCAL5 0 -#define LOG_LOCAL6 0 -#define LOG_LOCAL7 0 +#define LOG_KERN 0 +#define LOG_USER 0 +#define LOG_MAIL 0 +#define LOG_DAEMON 0 +#define LOG_AUTH 0 +#define LOG_SYSLOG 0 +#define LOG_LPR 0 +#define LOG_LOCAL0 0 +#define LOG_LOCAL1 0 +#define LOG_LOCAL2 0 +#define LOG_LOCAL3 0 +#define LOG_LOCAL4 0 +#define LOG_LOCAL5 0 +#define LOG_LOCAL6 0 +#define LOG_LOCAL7 0 -#define LOG_EMERG 0 /* system is unusable */ -#define LOG_ALERT 1 /* action must be taken immediately */ -#define LOG_CRIT 2 /* critical conditions */ -#define LOG_ERR 3 /* error conditions */ -#define LOG_WARNING 4 /* warning conditions */ -#define LOG_NOTICE 5 /* normal but signification condition */ -#define LOG_INFO 6 /* informational */ -#define LOG_DEBUG 7 /* debug-level messages */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but signification condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ void syslog(int level, const char *fmt, ...); @@ -66,4 +65,4 @@ NTReportError(const char *, const char *); */ #include <isc/bindevt.h> -#endif +#endif /* ifndef _SYSLOG_H */ diff --git a/lib/isc/win32/thread.c b/lib/isc/win32/thread.c index 7c147164..814fc9dc 100644 --- a/lib/isc/win32/thread.c +++ b/lib/isc/win32/thread.c @@ -3,53 +3,52 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <process.h> +#include <isc/strerr.h> #include <isc/thread.h> #include <isc/util.h> -isc_result_t +void isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg, - isc_thread_t *threadp) -{ + isc_thread_t *threadp) { isc_thread_t thread; unsigned int id; thread = (isc_thread_t)_beginthreadex(NULL, 0, start, arg, 0, &id); if (thread == NULL) { - /* XXX */ - return (ISC_R_UNEXPECTED); + char strbuf[ISC_STRERRORSIZE]; + strerror_r(errno, strbuf, sizeof(strbuf)); + isc_error_fatal(__FILE__, __LINE__, "_beginthreadex failed: %s", + strbuf); } *threadp = thread; - return (ISC_R_SUCCESS); + return; } -isc_result_t +void isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) { DWORD result; result = WaitForSingleObject(thread, INFINITE); if (result != WAIT_OBJECT_0) { - /* XXX */ - return (ISC_R_UNEXPECTED); + isc_error_fatal(__FILE__, __LINE__, + "WaitForSingleObject() != WAIT_OBJECT_0"); } if (rp != NULL && !GetExitCodeThread(thread, rp)) { - /* XXX */ - return (ISC_R_UNEXPECTED); + isc_error_fatal(__FILE__, __LINE__, + "GetExitCodeThread() failed: %d", + GetLastError()); } (void)CloseHandle(thread); - - return (ISC_R_SUCCESS); } void @@ -71,25 +70,3 @@ isc_thread_setaffinity(int cpu) { /* no-op on Windows for now */ return (ISC_R_SUCCESS); } - -void * -isc_thread_key_getspecific(isc_thread_key_t key) { - return(TlsGetValue(key)); -} - -int -isc_thread_key_setspecific(isc_thread_key_t key, void *value) { - return (TlsSetValue(key, value) ? 0 : GetLastError()); -} - -int -isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)) { - *key = TlsAlloc(); - - return ((*key != -1) ? 0 : GetLastError()); -} - -int -isc_thread_key_delete(isc_thread_key_t key) { - return (TlsFree(key) ? 0 : GetLastError()); -} diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c index 21c3aa87..d35cf5e3 100644 --- a/lib/isc/win32/time.c +++ b/lib/isc/win32/time.c @@ -3,24 +3,20 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - -#include <config.h> - #include <errno.h> -#include <limits.h> -#include <stddef.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> #include <time.h> - #include <windows.h> #include <isc/assertions.h> @@ -35,7 +31,7 @@ * While it is reasonably obvious that this makes the needed * conversion factor 10^7, it is coded this way for additional clarity. */ -#define NS_PER_S 1000000000 +#define NS_PER_S 1000000000 #define NS_INTERVAL 100 #define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL) @@ -44,34 +40,35 @@ ***/ static const isc_time_t epoch = { { 0, 0 } }; -LIBISC_EXTERNAL_DATA const isc_time_t * const isc_time_epoch = &epoch; +LIBISC_EXTERNAL_DATA const isc_time_t *const isc_time_epoch = &epoch; /*** *** Intervals ***/ static const isc_interval_t zero_interval = { 0 }; -LIBISC_EXTERNAL_DATA const isc_interval_t * const isc_interval_zero = &zero_interval; +LIBISC_EXTERNAL_DATA const isc_interval_t *const isc_interval_zero = + &zero_interval; void isc_interval_set(isc_interval_t *i, unsigned int seconds, - unsigned int nanoseconds) -{ + unsigned int nanoseconds) { REQUIRE(i != NULL); REQUIRE(nanoseconds < NS_PER_S); /* * This rounds nanoseconds up not down. */ - i->interval = (LONGLONG)seconds * INTERVALS_PER_S - + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL; + i->interval = (LONGLONG)seconds * INTERVALS_PER_S + + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL; } bool isc_interval_iszero(const isc_interval_t *i) { REQUIRE(i != NULL); - if (i->interval == 0) + if (i->interval == 0) { return (true); + } return (false); } @@ -90,8 +87,10 @@ isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { i1.LowPart = temp.dwLowDateTime; i1.HighPart = temp.dwHighDateTime; - i1.QuadPart += (unsigned __int64)nanoseconds/100; - i1.QuadPart += (unsigned __int64)seconds*10000000; + /* cppcheck-suppress unreadVariable */ + i1.QuadPart += (unsigned __int64)nanoseconds / 100; + /* cppcheck-suppress unreadVariable */ + i1.QuadPart += (unsigned __int64)seconds * 10000000; t->absolute.dwLowDateTime = i1.LowPart; t->absolute.dwHighDateTime = i1.HighPart; @@ -109,9 +108,9 @@ bool isc_time_isepoch(const isc_time_t *t) { REQUIRE(t != NULL); - if (t->absolute.dwLowDateTime == 0 && - t->absolute.dwHighDateTime == 0) + if (t->absolute.dwLowDateTime == 0 && t->absolute.dwHighDateTime == 0) { return (true); + } return (false); } @@ -137,12 +136,14 @@ isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; - if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) + if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) { return (ISC_R_RANGE); + } + /* cppcheck-suppress unreadVariable */ i1.QuadPart += i->interval; - t->absolute.dwLowDateTime = i1.LowPart; + t->absolute.dwLowDateTime = i1.LowPart; t->absolute.dwHighDateTime = i1.HighPart; return (ISC_R_SUCCESS); @@ -156,8 +157,7 @@ isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) { } isc_result_t -isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) -{ +isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { ULARGE_INTEGER i1; REQUIRE(t != NULL && i != NULL && result != NULL); @@ -165,9 +165,11 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; - if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) + if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) { return (ISC_R_RANGE); + } + /* cppcheck-suppress unreadVariable */ i1.QuadPart += i->interval; result->absolute.dwLowDateTime = i1.LowPart; @@ -186,9 +188,11 @@ isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; - if (i1.QuadPart < (unsigned __int64) i->interval) + if (i1.QuadPart < (unsigned __int64)i->interval) { return (ISC_R_RANGE); + } + /* cppcheck-suppress unreadVariable */ i1.QuadPart -= i->interval; result->absolute.dwLowDateTime = i1.LowPart; @@ -204,13 +208,18 @@ isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) { REQUIRE(t1 != NULL && t2 != NULL); - i1.LowPart = t1->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ + i1.LowPart = t1->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ i1.HighPart = t1->absolute.dwHighDateTime; - i2.LowPart = t2->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ + i2.LowPart = t2->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ i2.HighPart = t2->absolute.dwHighDateTime; - if (i1.QuadPart <= i2.QuadPart) + if (i1.QuadPart <= i2.QuadPart) { return (0); + } /* * Convert to microseconds. @@ -229,9 +238,13 @@ isc_time_seconds(const isc_time_t *t) { SystemTimeToFileTime(&epoch1970, &temp); - i1.LowPart = t->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ + i1.LowPart = t->absolute.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ i1.HighPart = t->absolute.dwHighDateTime; - i2.LowPart = temp.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ + i2.LowPart = temp.dwLowDateTime; + /* cppcheck-suppress unreadVariable */ i2.HighPart = temp.dwHighDateTime; i3 = (i1.QuadPart - i2.QuadPart) / 10000000; @@ -250,20 +263,20 @@ isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) { INSIST(sizeof(unsigned int) == sizeof(uint32_t)); INSIST(sizeof(time_t) >= sizeof(uint32_t)); - if (isc_time_seconds(t) > (~0U>>1) && seconds <= (time_t)(~0U>>1)) + if (isc_time_seconds(t) > (~0U >> 1) && seconds <= (time_t)(~0U >> 1)) { return (ISC_R_RANGE); + } *secondsp = seconds; return (ISC_R_SUCCESS); } - uint32_t isc_time_nanoseconds(const isc_time_t *t) { ULARGE_INTEGER i; - i.LowPart = t->absolute.dwLowDateTime; + i.LowPart = t->absolute.dwLowDateTime; i.HighPart = t->absolute.dwHighDateTime; return ((uint32_t)(i.QuadPart % 10000000) * 100); } @@ -280,15 +293,16 @@ isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { REQUIRE(len > 0); if (FileTimeToLocalFileTime(&t->absolute, &localft) && - FileTimeToSystemTime(&localft, &st)) { + FileTimeToSystemTime(&localft, &st)) + { GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy", DateBuf, 50); - GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER| - TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50); + GetTimeFormat(LOCALE_USER_DEFAULT, + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + NULL, TimeBuf, 50); snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf, st.wMilliseconds); - } else { strlcpy(buf, "99-Bad-9999 99:99:99.999", len); } @@ -300,18 +314,18 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) { char DateBuf[50]; char TimeBuf[50]; -/* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */ + /* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */ REQUIRE(t != NULL); REQUIRE(buf != NULL); REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { - GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, - "ddd',' dd MMM yyyy", DateBuf, 50); + GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "ddd',' dd MMM yyyy", + DateBuf, 50); GetTimeFormat(LOCALE_USER_DEFAULT, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hh':'mm':'ss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf); } else { @@ -329,11 +343,13 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { REQUIRE(t != NULL); p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm); - if (p == NULL) + if (p == NULL) { return (ISC_R_UNEXPECTED); + } when = isc_tm_timegm(&t_tm); - if (when == -1) + if (when == -1) { return (ISC_R_UNEXPECTED); + } isc_time_set(t, (unsigned int)when, 0); return (ISC_R_SUCCESS); } @@ -354,8 +370,8 @@ isc_time_formatISO8601L(const isc_time_t *t, char *buf, unsigned int len) { GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "yyyy-MM-dd", DateBuf, 50); GetTimeFormat(LOCALE_USER_DEFAULT, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hh':'mm':'ss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%sT%s", DateBuf, TimeBuf); } else { buf[0] = 0; @@ -378,8 +394,8 @@ isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len) { GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "yyyy-MM-dd", DateBuf, 50); GetTimeFormat(LOCALE_USER_DEFAULT, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hh':'mm':'ss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%sT%s.%03u", DateBuf, TimeBuf, st.wMilliseconds); } else { @@ -388,6 +404,35 @@ isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len) { } void +isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len) { + SYSTEMTIME st; + char DateBuf[50]; + char TimeBuf[50]; + + /* strtime() format: "%Y-%m-%dT%H:%M:%S.SSSSSS" */ + + REQUIRE(t != NULL); + REQUIRE(buf != NULL); + REQUIRE(len > 0); + + if (FileTimeToSystemTime(&t->absolute, &st)) { + ULARGE_INTEGER i; + + GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "yyyy-MM-dd", + DateBuf, 50); + GetTimeFormat(LOCALE_USER_DEFAULT, + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); + i.LowPart = t->absolute.dwLowDateTime; + i.HighPart = t->absolute.dwHighDateTime; + snprintf(buf, len, "%sT%s.%06u", DateBuf, TimeBuf, + (uint32_t)(i.QuadPart % 10000000) / 10); + } else { + buf[0] = 0; + } +} + +void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { SYSTEMTIME st; char DateBuf[50]; @@ -400,11 +445,11 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { - GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", - DateBuf, 50); + GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", DateBuf, + 50); GetTimeFormat(LOCALE_NEUTRAL, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hh':'mm':'ss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%sT%sZ", DateBuf, TimeBuf); } else { buf[0] = 0; @@ -424,11 +469,11 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) { REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { - GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", - DateBuf, 50); + GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", DateBuf, + 50); GetTimeFormat(LOCALE_NEUTRAL, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hh':'mm':'ss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%sT%s.%03uZ", DateBuf, TimeBuf, st.wMilliseconds); } else { @@ -437,8 +482,37 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) { } void -isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len) -{ +isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len) { + SYSTEMTIME st; + char DateBuf[50]; + char TimeBuf[50]; + + /* strtime() format: "%Y-%m-%dT%H:%M:%S.SSSSSSZ" */ + + REQUIRE(t != NULL); + REQUIRE(buf != NULL); + REQUIRE(len > 0); + + if (FileTimeToSystemTime(&t->absolute, &st)) { + ULARGE_INTEGER i; + + GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", DateBuf, + 50); + GetTimeFormat(LOCALE_NEUTRAL, + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hh':'mm':'ss", TimeBuf, 50); + i.LowPart = t->absolute.dwLowDateTime; + i.HighPart = t->absolute.dwHighDateTime; + snprintf(buf, len, "%sT%s.%06uZ", DateBuf, TimeBuf, + (uint32_t)(i.QuadPart % 10000000) / 10); + } else { + buf[0] = 0; + } +} + +void +isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, + unsigned int len) { SYSTEMTIME st; char DateBuf[50]; char TimeBuf[50]; @@ -450,11 +524,10 @@ isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len) REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { - GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyyMMdd", - DateBuf, 50); + GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyyMMdd", DateBuf, 50); GetTimeFormat(LOCALE_NEUTRAL, - TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, - &st, "hhmmss", TimeBuf, 50); + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, + "hhmmss", TimeBuf, 50); snprintf(buf, len, "%s%s%03u", DateBuf, TimeBuf, st.wMilliseconds); } else { diff --git a/lib/isc/win32/unistd.h b/lib/isc/win32/unistd.h index 170577e7..d0c1a01f 100644 --- a/lib/isc/win32/unistd.h +++ b/lib/isc/win32/unistd.h @@ -3,15 +3,14 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ - /* None of these are defined in NT, so define them for our use */ -#define O_NONBLOCK 1 +#define O_NONBLOCK 1 #define PORT_NONBLOCK O_NONBLOCK /* @@ -26,27 +25,28 @@ */ #undef F_DUPFD -int fcntl(int, int, ...); +int +fcntl(int, int, ...); /* * access() related definitions for winXP */ #include <io.h> #ifndef F_OK -#define F_OK 0 -#endif +#define F_OK 0 +#endif /* ifndef F_OK */ #ifndef X_OK -#define X_OK 1 -#endif +#define X_OK 1 +#endif /* ifndef X_OK */ #ifndef W_OK #define W_OK 2 -#endif +#endif /* ifndef W_OK */ #ifndef R_OK #define R_OK 4 -#endif +#endif /* ifndef R_OK */ #define access _access diff --git a/lib/isc/win32/version.c b/lib/isc/win32/version.c index 83e292bc..e699eb4a 100644 --- a/lib/isc/win32/version.c +++ b/lib/isc/win32/version.c @@ -3,14 +3,12 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <versions.h> #include <isc/version.h> diff --git a/lib/isc/win32/win32os.c b/lib/isc/win32/win32os.c index cddb714f..c2c436ab 100644 --- a/lib/isc/win32/win32os.c +++ b/lib/isc/win32/win32os.c @@ -3,28 +3,26 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. */ -#include <config.h> - #include <windows.h> #ifndef TESTVERSION #include <isc/win32os.h> -#else +#else /* ifndef TESTVERSION */ #include <stdio.h> + #include <isc/util.h> -#endif +#endif /* ifndef TESTVERSION */ #include <isc/print.h> int isc_win32os_versioncheck(unsigned int major, unsigned int minor, - unsigned int spmajor, unsigned int spminor) -{ + unsigned int spmajor, unsigned int spminor) { OSVERSIONINFOEX osVer; DWORD typeMask; ULONGLONG conditionMask; @@ -37,45 +35,39 @@ isc_win32os_versioncheck(unsigned int major, unsigned int minor, /* Optimistic: likely greater */ osVer.dwMajorVersion = major; typeMask |= VER_MAJORVERSION; - conditionMask = VerSetConditionMask(conditionMask, - VER_MAJORVERSION, + conditionMask = VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_GREATER); osVer.dwMinorVersion = minor; typeMask |= VER_MINORVERSION; - conditionMask = VerSetConditionMask(conditionMask, - VER_MINORVERSION, + conditionMask = VerSetConditionMask(conditionMask, VER_MINORVERSION, VER_GREATER); osVer.wServicePackMajor = spmajor; typeMask |= VER_SERVICEPACKMAJOR; - conditionMask = VerSetConditionMask(conditionMask, - VER_SERVICEPACKMAJOR, + conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMAJOR, VER_GREATER); osVer.wServicePackMinor = spminor; typeMask |= VER_SERVICEPACKMINOR; - conditionMask = VerSetConditionMask(conditionMask, - VER_SERVICEPACKMINOR, + conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMINOR, VER_GREATER); - if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) + if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) { return (1); + } /* Failed: retry with equal */ conditionMask = 0; - conditionMask = VerSetConditionMask(conditionMask, - VER_MAJORVERSION, + conditionMask = VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_EQUAL); - conditionMask = VerSetConditionMask(conditionMask, - VER_MINORVERSION, + conditionMask = VerSetConditionMask(conditionMask, VER_MINORVERSION, VER_EQUAL); - conditionMask = VerSetConditionMask(conditionMask, - VER_SERVICEPACKMAJOR, + conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMAJOR, VER_EQUAL); - conditionMask = VerSetConditionMask(conditionMask, - VER_SERVICEPACKMINOR, + conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMINOR, VER_EQUAL); - if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) + if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) { return (0); - else + } else { return (-1); + } } #ifdef TESTVERSION @@ -90,30 +82,30 @@ main(int argc, char **argv) { if (argc > 1) { --argc; ++argv; - major = (unsigned int) atoi(argv[0]); + major = (unsigned int)atoi(argv[0]); } if (argc > 1) { --argc; ++argv; - minor = (unsigned int) atoi(argv[0]); + minor = (unsigned int)atoi(argv[0]); } if (argc > 1) { --argc; ++argv; - spmajor = (unsigned int) atoi(argv[0]); + spmajor = (unsigned int)atoi(argv[0]); } if (argc > 1) { --argc; POST(argc); ++argv; - spminor = (unsigned int) atoi(argv[0]); + spminor = (unsigned int)atoi(argv[0]); } ret = isc_win32os_versioncheck(major, minor, spmajor, spminor); printf("%s major %u minor %u SP major %u SP minor %u\n", - ret > 0 ? "greater" : (ret == 0 ? "equal" : "less"), - major, minor, spmajor, spminor); + ret > 0 ? "greater" : (ret == 0 ? "equal" : "less"), major, + minor, spmajor, spminor); return (ret); } -#endif +#endif /* ifdef TESTVERSION */ diff --git a/lib/isc/xoshiro128starstar.c b/lib/isc/xoshiro128starstar.c index 944e3a92..9cdc2581 100644 --- a/lib/isc/xoshiro128starstar.c +++ b/lib/isc/xoshiro128starstar.c @@ -3,7 +3,7 @@ * * 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 http://mozilla.org/MPL/2.0/. + * 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. @@ -18,12 +18,12 @@ * warranty. * * See <http://creativecommons.org/publicdomain/zero/1.0/>. -*/ - -#include <config.h> + */ #include <inttypes.h> +#include <isc/thread.h> + /* * This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator. * It has excellent (sub-ns) speed, a state size (128 bits) that is large @@ -34,67 +34,17 @@ * * The state must be seeded so that it is not everywhere zero. */ -#if defined(HAVE_TLS) -#define _LOCK() {}; -#define _UNLOCK() {}; - -#if defined(HAVE_THREAD_LOCAL) -#include <threads.h> -static thread_local uint32_t seed[4]; -#elif defined(HAVE___THREAD) -static __thread uint32_t seed[4]; -#elif defined(HAVE___DECLSPEC_THREAD) -static __declspec( thread ) uint32_t seed[4]; -#else -#error "Unknown method for defining a TLS variable!" -#endif - -#else -#if defined(_WIN32) || defined(_WIN64) -#include <windows.h> -static volatile HANDLE _mutex = NULL; - -/* - * Initialize the mutex on the first lock attempt. On collision, each thread - * will attempt to allocate a mutex and compare-and-swap it into place as the - * global mutex. On failure to swap in the global mutex, the mutex is closed. - */ -#define _LOCK() \ - do { \ - if (!_mutex) { \ - HANDLE p = CreateMutex(NULL, FALSE, NULL); \ - if (InterlockedCompareExchangePointer \ - ((void **)&_mutex, (void *)p, NULL)) { \ - CloseHandle(p); \ - } \ - } \ - WaitForSingleObject(_mutex, INFINITE); \ - } while (0) +ISC_THREAD_LOCAL uint32_t seed[4] = { 0 }; -#define _UNLOCK() ReleaseMutex(_mutex) - -#else /* defined(_WIN32) || defined(_WIN64) */ - -#include <pthread.h> -static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; -#define _LOCK() RUNTIME_CHECK(pthread_mutex_lock(&_mutex)==0) -#define _UNLOCK() RUNTIME_CHECK(pthread_mutex_unlock(&_mutex)==0) -#endif /* defined(_WIN32) || defined(_WIN64) */ - -static uint32_t seed[4]; - -#endif /* defined(HAVE_TLS) */ - -static inline uint32_t rotl(const uint32_t x, int k) { - return (x << k) | (x >> (32 - k)); +static inline uint32_t +rotl(const uint32_t x, int k) { + return ((x << k) | (x >> (32 - k))); } static inline uint32_t next(void) { uint32_t result_starstar, t; - _LOCK(); - result_starstar = rotl(seed[0] * 5, 7) * 9; t = seed[1] << 9; @@ -107,7 +57,5 @@ next(void) { seed[3] = rotl(seed[3], 11); - _UNLOCK(); - return (result_starstar); } |