diff options
author | dougb <dougb@FreeBSD.org> | 2011-07-16 11:12:09 +0000 |
---|---|---|
committer | dougb <dougb@FreeBSD.org> | 2011-07-16 11:12:09 +0000 |
commit | f4894c219c9f0fee1e1d5d793748161bba7d4111 (patch) | |
tree | 7873e6a2dac5f9ddbfefa3b07f3cf0570f682321 /contrib/bind9/lib/isc/unix | |
parent | 1fab7143c5a0cf07ad84fe178bb29590f5cd2733 (diff) | |
parent | 387965661eaa775833b1e35b917f8e568ab7f5c6 (diff) | |
download | FreeBSD-src-f4894c219c9f0fee1e1d5d793748161bba7d4111.zip FreeBSD-src-f4894c219c9f0fee1e1d5d793748161bba7d4111.tar.gz |
Upgrade to version 9.8.0-P4
This version has many new features, see /usr/share/doc/bind9/README
for details.
Diffstat (limited to 'contrib/bind9/lib/isc/unix')
-rw-r--r-- | contrib/bind9/lib/isc/unix/Makefile.in | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/app.c | 540 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/dir.c | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/entropy.c | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/file.c | 90 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c | 2 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/ifiter_ioctl.c | 2 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/include/isc/net.h | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/include/isc/offset.h | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/include/isc/strerror.h | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/include/isc/time.h | 2 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/interfaceiter.c | 4 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/resource.c | 2 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/socket.c | 952 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/socket_p.h | 9 | ||||
-rw-r--r-- | contrib/bind9/lib/isc/unix/strerror.c | 2 |
16 files changed, 1136 insertions, 493 deletions
diff --git a/contrib/bind9/lib/isc/unix/Makefile.in b/contrib/bind9/lib/isc/unix/Makefile.in index 7d23b96..2c91756 100644 --- a/contrib/bind9/lib/isc/unix/Makefile.in +++ b/contrib/bind9/lib/isc/unix/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.41 2007-06-19 23:47:18 tbox Exp $ +# $Id: Makefile.in,v 1.44 2009-12-05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/contrib/bind9/lib/isc/unix/app.c b/contrib/bind9/lib/isc/unix/app.c index 6bd1660..4dc5130 100644 --- a/contrib/bind9/lib/isc/unix/app.c +++ b/contrib/bind9/lib/isc/unix/app.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: app.c,v 1.60 2008-10-15 03:41:17 marka Exp $ */ +/* $Id: app.c,v 1.64 2009-11-04 05:58:46 marka Exp $ */ /*! \file */ @@ -37,6 +37,7 @@ #include <isc/app.h> #include <isc/boolean.h> #include <isc/condition.h> +#include <isc/mem.h> #include <isc/msgs.h> #include <isc/mutex.h> #include <isc/event.h> @@ -47,31 +48,129 @@ #include <isc/time.h> #include <isc/util.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. + */ +#if defined(ISC_PLATFORM_USETHREADS) && defined(BIND9) +#define USE_THREADS_SINGLECTX +#endif + #ifdef ISC_PLATFORM_USETHREADS #include <pthread.h> -#else /* ISC_PLATFORM_USETHREADS */ +#endif + +#ifndef USE_THREADS_SINGLECTX #include "../timer_p.h" #include "../task_p.h" #include "socket_p.h" +#endif /* USE_THREADS_SINGLECTX */ + +#ifdef ISC_PLATFORM_USETHREADS +static pthread_t blockedthread; #endif /* ISC_PLATFORM_USETHREADS */ -static isc_eventlist_t on_run; -static isc_mutex_t lock; -static isc_boolean_t shutdown_requested = ISC_FALSE; -static isc_boolean_t running = ISC_FALSE; -/*! - * We assume that 'want_shutdown' can be read and written atomically. +/*% + * The following can be either static or public, depending on build environment. */ -static volatile isc_boolean_t want_shutdown = ISC_FALSE; + +#ifdef BIND9 +#define ISC_APPFUNC_SCOPE +#else +#define ISC_APPFUNC_SCOPE static +#endif + +ISC_APPFUNC_SCOPE isc_result_t isc__app_start(void); +ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxstart(isc_appctx_t *ctx); +ISC_APPFUNC_SCOPE isc_result_t isc__app_onrun(isc_mem_t *mctx, + isc_task_t *task, + isc_taskaction_t action, + void *arg); +ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxrun(isc_appctx_t *ctx); +ISC_APPFUNC_SCOPE isc_result_t isc__app_run(void); +ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx); +ISC_APPFUNC_SCOPE isc_result_t isc__app_shutdown(void); +ISC_APPFUNC_SCOPE isc_result_t isc__app_reload(void); +ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx); +ISC_APPFUNC_SCOPE void isc__app_ctxfinish(isc_appctx_t *ctx); +ISC_APPFUNC_SCOPE void isc__app_finish(void); +ISC_APPFUNC_SCOPE void isc__app_block(void); +ISC_APPFUNC_SCOPE void isc__app_unblock(void); +ISC_APPFUNC_SCOPE isc_result_t isc__appctx_create(isc_mem_t *mctx, + isc_appctx_t **ctxp); +ISC_APPFUNC_SCOPE void isc__appctx_destroy(isc_appctx_t **ctxp); +ISC_APPFUNC_SCOPE void isc__appctx_settaskmgr(isc_appctx_t *ctx, + isc_taskmgr_t *taskmgr); +ISC_APPFUNC_SCOPE void isc__appctx_setsocketmgr(isc_appctx_t *ctx, + isc_socketmgr_t *socketmgr); +ISC_APPFUNC_SCOPE void isc__appctx_settimermgr(isc_appctx_t *ctx, + isc_timermgr_t *timermgr); + /* - * We assume that 'want_reload' can be read and written atomically. + * The application context of this module. This implementation actually + * doesn't use it. (This may change in the future). */ -static volatile isc_boolean_t want_reload = ISC_FALSE; +#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; + isc_boolean_t shutdown_requested; + isc_boolean_t running; + + /*! + * We assume that 'want_shutdown' can be read and written atomically. + */ + isc_boolean_t want_shutdown; + /* + * We assume that 'want_reload' can be read and written atomically. + */ + isc_boolean_t want_reload; -static isc_boolean_t blocked = ISC_FALSE; -#ifdef ISC_PLATFORM_USETHREADS -static pthread_t blockedthread; -#endif /* ISC_PLATFORM_USETHREADS */ + isc_boolean_t blocked; + + isc_taskmgr_t *taskmgr; + isc_socketmgr_t *socketmgr; + isc_timermgr_t *timermgr; +} isc__appctx_t; + +static isc__appctx_t isc_g_appctx; + +static struct { + isc_appmethods_t methods; + + /*% + * The following are defined just for avoiding unused static functions. + */ +#ifndef BIND9 + void *run, *shutdown, *start, *onrun, *reload, *finish, + *block, *unblock; +#endif +} appmethods = { + { + isc__appctx_destroy, + isc__app_ctxstart, + isc__app_ctxrun, + isc__app_ctxsuspend, + isc__app_ctxshutdown, + isc__app_ctxfinish, + isc__appctx_settaskmgr, + isc__appctx_setsocketmgr, + isc__appctx_settimermgr + } +#ifndef BIND9 + , + (void *)isc__app_run, (void *)isc__app_shutdown, + (void *)isc__app_start, (void *)isc__app_onrun, (void *)isc__app_reload, + (void *)isc__app_finish, (void *)isc__app_block, + (void *)isc__app_unblock +#endif +}; #ifdef HAVE_LINUXTHREADS /*! @@ -91,13 +190,13 @@ static pthread_t main_thread; static void exit_action(int arg) { UNUSED(arg); - want_shutdown = ISC_TRUE; + isc_g_appctx.want_shutdown = ISC_TRUE; } static void reload_action(int arg) { UNUSED(arg); - want_reload = ISC_TRUE; + isc_g_appctx.want_reload = ISC_TRUE; } #endif @@ -123,12 +222,12 @@ handle_signal(int sig, void (*handler)(int)) { return (ISC_R_SUCCESS); } -isc_result_t -isc_app_start(void) { +ISC_APPFUNC_SCOPE 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. @@ -151,7 +250,35 @@ isc_app_start(void) { main_thread = pthread_self(); #endif - result = isc_mutex_init(&lock); + result = isc_mutex_init(&ctx->lock); + if (result != ISC_R_SUCCESS) + return (result); + + ISC_LIST_INIT(ctx->on_run); + + ctx->shutdown_requested = ISC_FALSE; + ctx->running = ISC_FALSE; + ctx->want_shutdown = ISC_FALSE; + ctx->want_reload = ISC_FALSE; + ctx->blocked = ISC_FALSE; + + return (ISC_R_SUCCESS); +} + +ISC_APPFUNC_SCOPE isc_result_t +isc__app_start(void) { + isc_result_t result; + int presult; + sigset_t sset; + char strbuf[ISC_STRERRORSIZE]; + + isc_g_appctx.common.impmagic = APPCTX_MAGIC; + isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC; + isc_g_appctx.common.methods = &appmethods.methods; + isc_g_appctx.mctx = NULL; + /* The remaining members will be initialized in ctxstart() */ + + result = isc__app_ctxstart((isc_appctx_t *)&isc_g_appctx); if (result != ISC_R_SUCCESS) return (result); @@ -253,22 +380,20 @@ isc_app_start(void) { } #endif /* ISC_PLATFORM_USETHREADS */ - ISC_LIST_INIT(on_run); - return (ISC_R_SUCCESS); } -isc_result_t -isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, +ISC_APPFUNC_SCOPE isc_result_t +isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_event_t *event; isc_task_t *cloned_task = NULL; isc_result_t result; - LOCK(&lock); + LOCK(&isc_g_appctx.lock); - if (running) { + if (isc_g_appctx.running) { result = ISC_R_ALREADYRUNNING; goto unlock; } @@ -285,24 +410,25 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, goto unlock; } - ISC_LIST_APPEND(on_run, event, ev_link); + ISC_LIST_APPEND(isc_g_appctx.on_run, event, ev_link); result = ISC_R_SUCCESS; unlock: - UNLOCK(&lock); + UNLOCK(&isc_g_appctx.lock); return (result); } -#ifndef ISC_PLATFORM_USETHREADS +#ifndef USE_THREADS_SINGLECTX /*! * Event loop for nonthreaded programs. */ static isc_result_t -evloop(void) { +evloop(isc__appctx_t *ctx) { isc_result_t result; - while (!want_shutdown) { + + while (!ctx->want_shutdown) { int n; isc_time_t when, now; struct timeval tv, *tvp; @@ -310,14 +436,27 @@ evloop(void) { isc_boolean_t readytasks; isc_boolean_t call_timer_dispatch = ISC_FALSE; - readytasks = isc__taskmgr_ready(); + /* + * Check the reload (or suspend) case first for exiting the + * loop as fast as possible in case: + * - the direct call to isc__taskmgr_dispatch() in + * isc__app_ctxrun() completes all the tasks so far, + * - there is thus currently no active task, and + * - there is a timer event + */ + if (ctx->want_reload) { + ctx->want_reload = ISC_FALSE; + return (ISC_R_RELOAD); + } + + readytasks = isc__taskmgr_ready(ctx->taskmgr); if (readytasks) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; call_timer_dispatch = ISC_TRUE; } else { - result = isc__timermgr_nextevent(&when); + result = isc__timermgr_nextevent(ctx->timermgr, &when); if (result != ISC_R_SUCCESS) tvp = NULL; else { @@ -334,7 +473,7 @@ evloop(void) { } swait = NULL; - n = isc__socketmgr_waitevents(tvp, &swait); + n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait); if (n == 0 || call_timer_dispatch) { /* @@ -351,20 +490,17 @@ evloop(void) { * call, since this loop only runs in the non-thread * mode. */ - isc__timermgr_dispatch(); + isc__timermgr_dispatch(ctx->timermgr); } if (n > 0) - (void)isc__socketmgr_dispatch(swait); - (void)isc__taskmgr_dispatch(); - - if (want_reload) { - want_reload = ISC_FALSE; - return (ISC_R_RELOAD); - } + (void)isc__socketmgr_dispatch(ctx->socketmgr, swait); + (void)isc__taskmgr_dispatch(ctx->taskmgr); } return (ISC_R_SUCCESS); } +#endif /* USE_THREADS_SINGLECTX */ +#ifndef ISC_PLATFORM_USETHREADS /* * This is a gross hack to support waiting for condition * variables in nonthreaded programs in a limited way; @@ -400,11 +536,11 @@ isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) { INSIST(*mp == 1); /* Mutex must be locked on entry. */ --*mp; - result = evloop(); + result = evloop(&isc_g_appctx); if (result == ISC_R_RELOAD) - want_reload = ISC_TRUE; + isc_g_appctx.want_reload = ISC_TRUE; if (signalled) { - want_shutdown = ISC_FALSE; + isc_g_appctx.want_shutdown = ISC_FALSE; signalled = ISC_FALSE; } @@ -420,43 +556,46 @@ isc__nothread_signal_hack(isc_condition_t *cp) { INSIST(in_recursive_evloop); - want_shutdown = ISC_TRUE; + isc_g_appctx.want_shutdown = ISC_TRUE; signalled = ISC_TRUE; return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_USETHREADS */ -isc_result_t -isc_app_run(void) { +ISC_APPFUNC_SCOPE 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; -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_THREADS_SINGLECTX sigset_t sset; char strbuf[ISC_STRERRORSIZE]; #ifdef HAVE_SIGWAIT int sig; #endif -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_THREADS_SINGLECTX */ + + REQUIRE(VALID_APPCTX(ctx)); #ifdef HAVE_LINUXTHREADS REQUIRE(main_thread == pthread_self()); #endif - LOCK(&lock); + LOCK(&ctx->lock); - if (!running) { - running = ISC_TRUE; + if (!ctx->running) { + ctx->running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ - for (event = ISC_LIST_HEAD(on_run); + for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(on_run, 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); @@ -464,7 +603,7 @@ isc_app_run(void) { } - UNLOCK(&lock); + UNLOCK(&ctx->lock); #ifndef HAVE_SIGWAIT /* @@ -473,19 +612,27 @@ isc_app_run(void) { * We do this here to ensure that the signal handler is installed * (i.e. that it wasn't a "one-shot" handler). */ - result = handle_signal(SIGHUP, reload_action); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); + if (ctx == &isc_g_appctx) { + result = handle_signal(SIGHUP, reload_action); + if (result != ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + } #endif -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_THREADS_SINGLECTX + /* + * When we are using multiple contexts, we don't rely on signals. + */ + if (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 (!want_shutdown) { + while (!ctx->want_shutdown) { #ifdef HAVE_SIGWAIT /* * Wait for SIGHUP, SIGINT, or SIGTERM. @@ -503,21 +650,19 @@ isc_app_run(void) { #ifndef HAVE_UNIXWARE_SIGWAIT result = sigwait(&sset, &sig); if (result == 0) { - if (sig == SIGINT || - sig == SIGTERM) - want_shutdown = ISC_TRUE; + if (sig == SIGINT || sig == SIGTERM) + ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) - want_reload = ISC_TRUE; + ctx->want_reload = ISC_TRUE; } #else /* Using UnixWare sigwait semantics. */ sig = sigwait(&sset); if (sig >= 0) { - if (sig == SIGINT || - sig == SIGTERM) - want_shutdown = ISC_TRUE; + if (sig == SIGINT || sig == SIGTERM) + ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) - want_reload = ISC_TRUE; + ctx->want_reload = ISC_TRUE; } #endif /* HAVE_UNIXWARE_SIGWAIT */ @@ -528,131 +673,174 @@ isc_app_run(void) { if (sigemptyset(&sset) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", strbuf); + "isc_app_run() sigsetops: %s", + strbuf); return (ISC_R_UNEXPECTED); } result = sigsuspend(&sset); #endif /* HAVE_SIGWAIT */ - if (want_reload) { - want_reload = ISC_FALSE; + if (ctx->want_reload) { + ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } - if (want_shutdown && blocked) + if (ctx->want_shutdown && ctx->blocked) exit(1); } -#else /* ISC_PLATFORM_USETHREADS */ +#else /* USE_THREADS_SINGLECTX */ - (void)isc__taskmgr_dispatch(); + (void)isc__taskmgr_dispatch(ctx->taskmgr); - result = evloop(); + result = evloop(ctx); if (result != ISC_R_SUCCESS) return (result); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_THREADS_SINGLECTX */ return (ISC_R_SUCCESS); } -isc_result_t -isc_app_shutdown(void) { +ISC_APPFUNC_SCOPE isc_result_t +isc__app_run() { + return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx)); +} + +ISC_APPFUNC_SCOPE isc_result_t +isc__app_ctxshutdown(isc_appctx_t *ctx0) { + isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; char strbuf[ISC_STRERRORSIZE]; - LOCK(&lock); + REQUIRE(VALID_APPCTX(ctx)); - REQUIRE(running); + LOCK(&ctx->lock); - if (shutdown_requested) + REQUIRE(ctx->running); + + if (ctx->shutdown_requested) want_kill = ISC_FALSE; else - shutdown_requested = ISC_TRUE; + ctx->shutdown_requested = ISC_TRUE; - UNLOCK(&lock); + UNLOCK(&ctx->lock); if (want_kill) { + if (ctx != &isc_g_appctx) + ctx->want_shutdown = ISC_TRUE; + else { #ifdef HAVE_LINUXTHREADS - int result; - - result = pthread_kill(main_thread, SIGTERM); - if (result != 0) { - isc__strerror(result, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_shutdown() pthread_kill: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } + int result; + + result = pthread_kill(main_thread, SIGTERM); + if (result != 0) { + isc__strerror(result, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_app_shutdown() " + "pthread_kill: %s", + strbuf); + return (ISC_R_UNEXPECTED); + } #else - if (kill(getpid(), SIGTERM) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_shutdown() kill: %s", strbuf); - return (ISC_R_UNEXPECTED); + if (kill(getpid(), SIGTERM) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_app_shutdown() " + "kill: %s", strbuf); + return (ISC_R_UNEXPECTED); + } +#endif /* HAVE_LINUXTHREADS */ } -#endif } return (ISC_R_SUCCESS); } -isc_result_t -isc_app_reload(void) { +ISC_APPFUNC_SCOPE isc_result_t +isc__app_shutdown() { + return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); +} + +ISC_APPFUNC_SCOPE isc_result_t +isc__app_ctxsuspend(isc_appctx_t *ctx0) { + isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; char strbuf[ISC_STRERRORSIZE]; - LOCK(&lock); + REQUIRE(VALID_APPCTX(ctx)); + + LOCK(&ctx->lock); - REQUIRE(running); + REQUIRE(ctx->running); /* * Don't send the reload signal if we're shutting down. */ - if (shutdown_requested) + if (ctx->shutdown_requested) want_kill = ISC_FALSE; - UNLOCK(&lock); + UNLOCK(&ctx->lock); if (want_kill) { + if (ctx != &isc_g_appctx) + ctx->want_reload = ISC_TRUE; + else { #ifdef HAVE_LINUXTHREADS - int result; - - result = pthread_kill(main_thread, SIGHUP); - if (result != 0) { - isc__strerror(result, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_reload() pthread_kill: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } + int result; + + result = pthread_kill(main_thread, SIGHUP); + if (result != 0) { + isc__strerror(result, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_app_reload() " + "pthread_kill: %s", + strbuf); + return (ISC_R_UNEXPECTED); + } #else - if (kill(getpid(), SIGHUP) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_reload() kill: %s", strbuf); - return (ISC_R_UNEXPECTED); - } + if (kill(getpid(), SIGHUP) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_app_reload() " + "kill: %s", strbuf); + return (ISC_R_UNEXPECTED); + } #endif + } } return (ISC_R_SUCCESS); } -void -isc_app_finish(void) { - DESTROYLOCK(&lock); +ISC_APPFUNC_SCOPE isc_result_t +isc__app_reload(void) { + return (isc__app_ctxsuspend((isc_appctx_t *)&isc_g_appctx)); +} + +ISC_APPFUNC_SCOPE void +isc__app_ctxfinish(isc_appctx_t *ctx0) { + isc__appctx_t *ctx = (isc__appctx_t *)ctx0; + + REQUIRE(VALID_APPCTX(ctx)); + + DESTROYLOCK(&ctx->lock); +} + +ISC_APPFUNC_SCOPE void +isc__app_finish(void) { + isc__app_ctxfinish((isc_appctx_t *)&isc_g_appctx); } -void -isc_app_block(void) { +ISC_APPFUNC_SCOPE void +isc__app_block(void) { #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; #endif /* ISC_PLATFORM_USETHREADS */ - REQUIRE(running); - REQUIRE(!blocked); + REQUIRE(isc_g_appctx.running); + REQUIRE(!isc_g_appctx.blocked); - blocked = ISC_TRUE; + isc_g_appctx.blocked = ISC_TRUE; #ifdef ISC_PLATFORM_USETHREADS blockedthread = pthread_self(); RUNTIME_CHECK(sigemptyset(&sset) == 0 && @@ -662,16 +850,16 @@ isc_app_block(void) { #endif /* ISC_PLATFORM_USETHREADS */ } -void -isc_app_unblock(void) { +ISC_APPFUNC_SCOPE void +isc__app_unblock(void) { #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; #endif /* ISC_PLATFORM_USETHREADS */ - REQUIRE(running); - REQUIRE(blocked); + REQUIRE(isc_g_appctx.running); + REQUIRE(isc_g_appctx.blocked); - blocked = ISC_FALSE; + isc_g_appctx.blocked = ISC_FALSE; #ifdef ISC_PLATFORM_USETHREADS REQUIRE(blockedthread == pthread_self()); @@ -682,3 +870,77 @@ isc_app_unblock(void) { RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); #endif /* ISC_PLATFORM_USETHREADS */ } + +ISC_APPFUNC_SCOPE 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->common.methods = &appmethods.methods; + + 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); +} + +ISC_APPFUNC_SCOPE 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; +} + +ISC_APPFUNC_SCOPE 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; +} + +ISC_APPFUNC_SCOPE 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; +} + +ISC_APPFUNC_SCOPE 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; +} + +#ifdef USE_APPIMPREGISTER +isc_result_t +isc__app_register() { + return (isc_app_register(isc__appctx_create)); +} +#endif diff --git a/contrib/bind9/lib/isc/unix/dir.c b/contrib/bind9/lib/isc/unix/dir.c index 8053c42..0caf882 100644 --- a/contrib/bind9/lib/isc/unix/dir.c +++ b/contrib/bind9/lib/isc/unix/dir.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dir.c,v 1.25.332.3 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: dir.c,v 1.29 2009-02-16 23:48:04 tbox Exp $ */ /*! \file * \author Principal Authors: DCL */ diff --git a/contrib/bind9/lib/isc/unix/entropy.c b/contrib/bind9/lib/isc/unix/entropy.c index bdff8d9..9044632 100644 --- a/contrib/bind9/lib/isc/unix/entropy.c +++ b/contrib/bind9/lib/isc/unix/entropy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: entropy.c,v 1.80.332.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: entropy.c,v 1.82 2008-12-01 23:47:45 tbox Exp $ */ /* \file unix/entropy.c * \brief diff --git a/contrib/bind9/lib/isc/unix/file.c b/contrib/bind9/lib/isc/unix/file.c index ae737b8..25d856c 100644 --- a/contrib/bind9/lib/isc/unix/file.c +++ b/contrib/bind9/lib/isc/unix/file.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -48,7 +48,7 @@ * SUCH DAMAGE. */ -/* $Id: file.c,v 1.51.332.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: file.c,v 1.57 2011-01-11 23:47:14 tbox Exp $ */ /*! \file */ @@ -68,6 +68,7 @@ #include <isc/dir.h> #include <isc/file.h> #include <isc/log.h> +#include <isc/mem.h> #include <isc/random.h> #include <isc/string.h> #include <isc/time.h> @@ -242,16 +243,26 @@ isc_file_renameunique(const char *file, char *templet) { 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; + return (isc_file_openuniquemode(templet, mode, fp)); +} + +isc_result_t +isc_file_openuniqueprivate(char *templet, FILE **fp) { + int mode = S_IWUSR|S_IRUSR; + return (isc_file_openuniquemode(templet, mode, fp)); +} + +isc_result_t +isc_file_openuniquemode(char *templet, int mode, FILE **fp) { int fd; FILE *f; isc_result_t result = ISC_R_SUCCESS; char *x; char *cp; isc_uint32_t which; - int mode; REQUIRE(templet != NULL); REQUIRE(fp != NULL && *fp == NULL); @@ -269,7 +280,6 @@ isc_file_openunique(char *templet, FILE **fp) { x = cp--; } - mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) { if (errno != EEXIST) @@ -442,3 +452,73 @@ isc_file_truncate(const char *filename, isc_offset_t size) { result = isc__errno2result(errno); return (result); } + +isc_result_t +isc_file_safecreate(const char *filename, FILE **fp) { + isc_result_t result; + int flags; + struct stat sb; + FILE *f; + int fd; + + REQUIRE(filename != NULL); + REQUIRE(fp != NULL && *fp == NULL); + + result = file_stats(filename, &sb); + if (result == ISC_R_SUCCESS) { + 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 + return (result); + + fd = open(filename, flags, S_IRUSR | S_IWUSR); + if (fd == -1) + return (isc__errno2result(errno)); + + f = fdopen(fd, "w"); + if (f == NULL) { + result = isc__errno2result(errno); + close(fd); + return (result); + } + + *fp = f; + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) +{ + char *dir, *file, *slash; + + slash = strrchr(path, '/'); + + if (slash == path) { + file = ++slash; + dir = isc_mem_strdup(mctx, "/"); + } else if (slash != NULL) { + file = ++slash; + dir = isc_mem_allocate(mctx, slash - path); + if (dir != NULL) + strlcpy(dir, path, slash - path); + } else { + file = path; + dir = isc_mem_strdup(mctx, "."); + } + + if (dir == NULL) + return (ISC_R_NOMEMORY); + + if (*file == '\0') { + isc_mem_free(mctx, dir); + return (ISC_R_INVALIDFILE); + } + + *dirname = dir; + *basename = file; + + return (ISC_R_SUCCESS); +} diff --git a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c index 1e9c814..90a3faf 100644 --- a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c +++ b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ifiter_getifaddrs.c,v 1.11.120.2 2009-09-24 23:47:34 tbox Exp $ */ +/* $Id: ifiter_getifaddrs.c,v 1.13 2009-09-24 23:48:13 tbox Exp $ */ /*! \file * \brief diff --git a/contrib/bind9/lib/isc/unix/ifiter_ioctl.c b/contrib/bind9/lib/isc/unix/ifiter_ioctl.c index c004f61..010b365 100644 --- a/contrib/bind9/lib/isc/unix/ifiter_ioctl.c +++ b/contrib/bind9/lib/isc/unix/ifiter_ioctl.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ifiter_ioctl.c,v 1.60.120.2 2009-01-18 23:47:41 tbox Exp $ */ +/* $Id: ifiter_ioctl.c,v 1.62 2009-01-18 23:48:14 tbox Exp $ */ /*! \file * \brief diff --git a/contrib/bind9/lib/isc/unix/include/isc/net.h b/contrib/bind9/lib/isc/unix/include/isc/net.h index 5fad793..112f1d7 100644 --- a/contrib/bind9/lib/isc/unix/include/isc/net.h +++ b/contrib/bind9/lib/isc/unix/include/isc/net.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: net.h,v 1.48.84.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: net.h,v 1.50 2008-12-01 04:14:54 marka Exp $ */ #ifndef ISC_NET_H #define ISC_NET_H 1 diff --git a/contrib/bind9/lib/isc/unix/include/isc/offset.h b/contrib/bind9/lib/isc/unix/include/isc/offset.h index 91f43c37..2920899 100644 --- a/contrib/bind9/lib/isc/unix/include/isc/offset.h +++ b/contrib/bind9/lib/isc/unix/include/isc/offset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: offset.h,v 1.15.332.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: offset.h,v 1.17 2008-12-01 23:47:45 tbox Exp $ */ #ifndef ISC_OFFSET_H #define ISC_OFFSET_H 1 diff --git a/contrib/bind9/lib/isc/unix/include/isc/strerror.h b/contrib/bind9/lib/isc/unix/include/isc/strerror.h index e094e96..ac8d496 100644 --- a/contrib/bind9/lib/isc/unix/include/isc/strerror.h +++ b/contrib/bind9/lib/isc/unix/include/isc/strerror.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: strerror.h,v 1.8.332.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: strerror.h,v 1.10 2008-12-01 23:47:45 tbox Exp $ */ #ifndef ISC_STRERROR_H #define ISC_STRERROR_H diff --git a/contrib/bind9/lib/isc/unix/include/isc/time.h b/contrib/bind9/lib/isc/unix/include/isc/time.h index 2149011..19f0810 100644 --- a/contrib/bind9/lib/isc/unix/include/isc/time.h +++ b/contrib/bind9/lib/isc/unix/include/isc/time.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.h,v 1.38.56.2 2009-01-05 23:47:23 tbox Exp $ */ +/* $Id: time.h,v 1.40 2009-01-05 23:47:54 tbox Exp $ */ #ifndef ISC_TIME_H #define ISC_TIME_H 1 diff --git a/contrib/bind9/lib/isc/unix/interfaceiter.c b/contrib/bind9/lib/isc/unix/interfaceiter.c index 2d60a33..37fc3b1 100644 --- a/contrib/bind9/lib/isc/unix/interfaceiter.c +++ b/contrib/bind9/lib/isc/unix/interfaceiter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfaceiter.c,v 1.44.120.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: interfaceiter.c,v 1.45 2008-12-01 03:51:47 marka Exp $ */ /*! \file */ diff --git a/contrib/bind9/lib/isc/unix/resource.c b/contrib/bind9/lib/isc/unix/resource.c index 1061282..99a4b8c 100644 --- a/contrib/bind9/lib/isc/unix/resource.c +++ b/contrib/bind9/lib/isc/unix/resource.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resource.c,v 1.21.66.2 2009-02-13 23:47:39 tbox Exp $ */ +/* $Id: resource.c,v 1.23 2009-02-13 23:48:14 tbox Exp $ */ #include <config.h> diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c index 055e883..ec7487e 100644 --- a/contrib/bind9/lib/isc/unix/socket.c +++ b/contrib/bind9/lib/isc/unix/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.308.12.17 2010-12-22 03:28:13 marka Exp $ */ +/* $Id: socket.c,v 1.333.14.2.2.1 2011-06-02 23:47:36 tbox Exp $ */ /*! \file */ @@ -76,9 +76,19 @@ #include "errno2result.h" -#ifndef ISC_PLATFORM_USETHREADS +/* See task.c about the following definition: */ +#ifdef BIND9 +#ifdef ISC_PLATFORM_USETHREADS +#define USE_WATCHER_THREAD +#else +#define USE_SHARED_MANAGER +#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* BIND9 */ + +#ifndef USE_WATCHER_THREAD #include "socket_p.h" -#endif /* ISC_PLATFORM_USETHREADS */ +#include "../task_p.h" +#endif /* USE_WATCHER_THREAD */ #if defined(SO_BSDCOMPAT) && defined(__linux__) #include <sys/utsname.h> @@ -101,7 +111,7 @@ typedef struct { #define USE_SELECT #endif /* ISC_PLATFORM_HAVEKQUEUE */ -#ifndef ISC_PLATFORM_USETHREADS +#ifndef USE_WATCHER_THREAD #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) struct isc_socketwait { int nevents; @@ -114,7 +124,7 @@ struct isc_socketwait { int maxfd; }; #endif /* USE_KQUEUE */ -#endif /* !ISC_PLATFORM_USETHREADS */ +#endif /* !USE_WATCHER_THREAD */ /*% * Maximum number of allowable open sockets. This is also the maximum @@ -248,7 +258,7 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; typedef isc_event_t intev_t; #define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') -#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC) +#define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC) /*! * IPv6 control information. If the socket is an IPv6 socket we want @@ -282,16 +292,21 @@ typedef isc_event_t intev_t; */ #define NRETRIES 10 -struct isc_socket { +typedef struct isc__socket isc__socket_t; +typedef struct isc__socketmgr isc__socketmgr_t; + +#define NEWCONNSOCK(ev) ((isc__socket_t *)(ev)->newsocket) + +struct isc__socket { /* Not locked. */ - unsigned int magic; - isc_socketmgr_t *manager; + isc_socket_t common; + isc__socketmgr_t *manager; isc_mutex_t lock; isc_sockettype_t type; const isc_statscounter_t *statsindex; /* Locked by socket lock. */ - ISC_LINK(isc_socket_t) link; + ISC_LINK(isc__socket_t) link; unsigned int references; int fd; int pf; @@ -339,9 +354,9 @@ struct isc_socket { #define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) -struct isc_socketmgr { +struct isc__socketmgr { /* Not locked. */ - unsigned int magic; + isc_socketmgr_t common; isc_mem_t *mctx; isc_mutex_t lock; isc_mutex_t *fdlock; @@ -370,14 +385,14 @@ struct isc_socketmgr { #endif /* Locked by fdlock. */ - isc_socket_t **fds; + isc__socket_t **fds; int *fdstate; #ifdef USE_DEVPOLL pollinfo_t *fdpollinfo; #endif /* Locked by manager lock. */ - ISC_LIST(isc_socket_t) socklist; + ISC_LIST(isc__socket_t) socklist; #ifdef USE_SELECT fd_set *read_fds; fd_set *read_fds_copy; @@ -386,17 +401,18 @@ struct isc_socketmgr { int maxfd; #endif /* USE_SELECT */ int reserved; /* unlocked */ -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD isc_thread_t watcher; isc_condition_t shutdown_ok; -#else /* ISC_PLATFORM_USETHREADS */ +#else /* USE_WATCHER_THREAD */ unsigned int refs; -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ + int maxudp; }; -#ifndef ISC_PLATFORM_USETHREADS -static isc_socketmgr_t *socketmgr = NULL; -#endif /* ISC_PLATFORM_USETHREADS */ +#ifdef USE_SHARED_MANAGER +static isc__socketmgr_t *socketmgr = NULL; +#endif /* USE_SHARED_MANAGER */ #define CLOSED 0 /* this one must be zero */ #define MANAGED 1 @@ -412,26 +428,165 @@ static isc_socketmgr_t *socketmgr = NULL; # define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) #endif -static void send_recvdone_event(isc_socket_t *, isc_socketevent_t **); -static void send_senddone_event(isc_socket_t *, isc_socketevent_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 send_recvdone_event(isc__socket_t *, isc_socketevent_t **); +static void send_senddone_event(isc__socket_t *, isc_socketevent_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_task_t *, isc_event_t *); static void internal_connect(isc_task_t *, isc_event_t *); static void internal_recv(isc_task_t *, isc_event_t *); static void internal_send(isc_task_t *, isc_event_t *); static void internal_fdwatch_write(isc_task_t *, isc_event_t *); static void internal_fdwatch_read(isc_task_t *, isc_event_t *); -static void process_cmsg(isc_socket_t *, struct msghdr *, isc_socketevent_t *); -static void build_msghdr_send(isc_socket_t *, isc_socketevent_t *, +static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *); +static void build_msghdr_send(isc__socket_t *, isc_socketevent_t *, struct msghdr *, struct iovec *, size_t *); -static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *, +static void build_msghdr_recv(isc__socket_t *, isc_socketevent_t *, struct msghdr *, struct iovec *, size_t *); -#ifdef ISC_PLATFORM_USETHREADS -static isc_boolean_t process_ctlfd(isc_socketmgr_t *manager); +#ifdef USE_WATCHER_THREAD +static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager); +#endif + +/*% + * The following can be either static or public, depending on build environment. + */ + +#ifdef BIND9 +#define ISC_SOCKETFUNC_SCOPE +#else +#define ISC_SOCKETFUNC_SCOPE static +#endif + +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, + isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE void +isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE void +isc__socket_detach(isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, + unsigned int maxsocks); +ISC_SOCKETFUNC_SCOPE void +isc__socketmgr_destroy(isc_socketmgr_t **managerp); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, + unsigned int minimum, isc_task_t *task, + isc_taskaction_t action, const void *arg); +ISC_SOCKETFUNC_SCOPE 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, const void *arg); +ISC_SOCKETFUNC_SCOPE 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_SOCKETFUNC_SCOPE isc_result_t +isc__socket_send(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, isc_taskaction_t action, const void *arg); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendto(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, + isc_task_t *task, isc_taskaction_t action, const void *arg); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, + isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, + isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, + isc_socketevent_t *event, unsigned int flags); +ISC_SOCKETFUNC_SCOPE void +isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, + isc_uint32_t owner, isc_uint32_t group); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, + unsigned int options); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_filter(isc_socket_t *sock, const char *filter); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_listen(isc_socket_t *sock, unsigned int backlog); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_accept(isc_socket_t *sock, + isc_task_t *task, isc_taskaction_t action, const void *arg); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, + isc_task_t *task, isc_taskaction_t action, + const void *arg); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp); +ISC_SOCKETFUNC_SCOPE void +isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); +ISC_SOCKETFUNC_SCOPE isc_sockettype_t +isc__socket_gettype(isc_socket_t *sock); +ISC_SOCKETFUNC_SCOPE isc_boolean_t +isc__socket_isbound(isc_socket_t *sock); +ISC_SOCKETFUNC_SCOPE void +isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes); +#if defined(HAVE_LIBXML2) && defined(BIND9) +ISC_SOCKETFUNC_SCOPE void +isc__socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer); +#endif + +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, + isc_sockfdwatch_t callback, void *cbarg, + isc_task_t *task, isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_fdwatchpoke(isc_socket_t *sock, int flags); + +static struct { + isc_socketmethods_t methods; + + /*% + * The following are defined just for avoiding unused static functions. + */ +#ifndef BIND9 + void *recvv, *send, *sendv, *sendto2, *cleanunix, *permunix, *filter, + *listen, *accept, *getpeername, *isbound; +#endif +} socketmethods = { + { + isc__socket_attach, + isc__socket_detach, + isc__socket_bind, + isc__socket_sendto, + isc__socket_connect, + isc__socket_recv, + isc__socket_cancel, + isc__socket_getsockname, + isc__socket_gettype, + isc__socket_ipv6only, + isc__socket_fdwatchpoke + } +#ifndef BIND9 + , + (void *)isc__socket_recvv, (void *)isc__socket_send, + (void *)isc__socket_sendv, (void *)isc__socket_sendto2, + (void *)isc__socket_cleanunix, (void *)isc__socket_permunix, + (void *)isc__socket_filter, (void *)isc__socket_listen, + (void *)isc__socket_accept, (void *)isc__socket_getpeername, + (void *)isc__socket_isbound #endif +}; + +static isc_socketmgrmethods_t socketmgrmethods = { + isc__socketmgr_destroy, + isc__socket_create, + isc__socket_fdwatchcreate +}; #define SELECT_POKE_SHUTDOWN (-1) #define SELECT_POKE_NOTHING (-2) @@ -531,12 +686,14 @@ static const isc_statscounter_t fdwatchstatsindex[] = { isc_sockstatscounter_fdwatchrecvfail }; +#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \ + defined(USE_WATCHER_THREAD) static void -manager_log(isc_socketmgr_t *sockmgr, +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, +manager_log(isc__socketmgr_t *sockmgr, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, ...) { @@ -553,14 +710,15 @@ manager_log(isc_socketmgr_t *sockmgr, isc_log_write(isc_lctx, category, module, level, "sockmgr %p: %s", sockmgr, msgbuf); } +#endif static void -socket_log(isc_socket_t *sock, isc_sockaddr_t *address, +socket_log(isc__socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10); static void -socket_log(isc_socket_t *sock, isc_sockaddr_t *address, +socket_log(isc__socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) @@ -595,7 +753,7 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address, * setting IPV6_V6ONLY. */ static void -FIX_IPV6_RECVPKTINFO(isc_socket_t *sock) +FIX_IPV6_RECVPKTINFO(isc__socket_t *sock) { char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -632,7 +790,7 @@ inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) { } static inline isc_result_t -watch_fd(isc_socketmgr_t *manager, int fd, int msg) { +watch_fd(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result = ISC_R_SUCCESS; #ifdef USE_KQUEUE @@ -700,7 +858,7 @@ watch_fd(isc_socketmgr_t *manager, int fd, int msg) { } static inline isc_result_t -unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) { +unwatch_fd(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result = ISC_R_SUCCESS; #ifdef USE_KQUEUE @@ -787,7 +945,7 @@ unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) { } static void -wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) { +wakeup_socket(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result; int lockid = FDLOCK_ID(fd); @@ -848,14 +1006,14 @@ wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) { } } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD /* * Poke the select loop when there is something for us to do. * The write is required (by POSIX) to complete. That is, we * will not get partial writes. */ static void -select_poke(isc_socketmgr_t *mgr, int fd, int msg) { +select_poke(isc__socketmgr_t *mgr, int fd, int msg) { int cc; int buf[2]; char strbuf[ISC_STRERRORSIZE]; @@ -894,7 +1052,7 @@ select_poke(isc_socketmgr_t *mgr, int fd, int msg) { * Read a message on the internal fd. */ static void -select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) { +select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) { int buf[2]; int cc; char strbuf[ISC_STRERRORSIZE]; @@ -921,19 +1079,19 @@ select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) { *fd = buf[0]; *msg = buf[1]; } -#else /* ISC_PLATFORM_USETHREADS */ +#else /* USE_WATCHER_THREAD */ /* * Update the state of the socketmgr when something changes. */ static void -select_poke(isc_socketmgr_t *manager, int fd, int msg) { +select_poke(isc__socketmgr_t *manager, int fd, int msg) { if (msg == SELECT_POKE_SHUTDOWN) return; else if (fd >= 0) wakeup_socket(manager, fd, msg); return; } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ /* * Make a fd non-blocking. @@ -1026,7 +1184,7 @@ cmsg_space(ISC_SOCKADDR_LEN_T len) { * Process control messages received on a socket. */ static void -process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { +process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { #ifdef USE_CMSG struct cmsghdr *cmsgp; #ifdef ISC_PLATFORM_HAVEIN6PKTINFO @@ -1129,7 +1287,7 @@ 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, isc_socketevent_t *dev, +build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, struct iovec *iov, size_t *write_countp) { unsigned int iovcount; @@ -1248,7 +1406,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, * this transaction can receive. */ static void -build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev, +build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, struct iovec *iov, size_t *read_countp) { unsigned int iovcount; @@ -1369,7 +1527,7 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev, } static void -set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock, +set_dev_address(isc_sockaddr_t *address, isc__socket_t *sock, isc_socketevent_t *dev) { if (sock->type == isc_sockettype_udp) { @@ -1393,7 +1551,7 @@ destroy_socketevent(isc_event_t *event) { } static isc_socketevent_t * -allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype, +allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype, isc_taskaction_t action, const void *arg) { isc_socketevent_t *ev; @@ -1446,7 +1604,7 @@ dump_msg(struct msghdr *msg) { #define DOIO_EOF 3 /* EOF, no event sent */ static int -doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { +doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { int cc; struct iovec iov[MAXSCATTERGATHER_RECV]; size_t read_count; @@ -1554,6 +1712,12 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { } return (DOIO_SOFT); } + /* + * Simulate a firewall blocking UDP responses bigger than + * 512 bytes. + */ + if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp) + return (DOIO_SOFT); } socket_log(sock, &dev->address, IOEVENT, @@ -1630,7 +1794,7 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { * No other return values are possible. */ static int -doio_send(isc_socket_t *sock, isc_socketevent_t *dev) { +doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { int cc; struct iovec iov[MAXSCATTERGATHER_SEND]; size_t write_count; @@ -1741,7 +1905,7 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) { * references exist. */ static void -closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) { +closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) { isc_sockettype_t type = sock->type; int lockid = FDLOCK_ID(fd); @@ -1804,10 +1968,10 @@ closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) { } static void -destroy(isc_socket_t **sockp) { +destroy(isc__socket_t **sockp) { int fd; - isc_socket_t *sock = *sockp; - isc_socketmgr_t *manager = sock->manager; + isc__socket_t *sock = *sockp; + isc__socketmgr_t *manager = sock->manager; socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DESTROYING, "destroying"); @@ -1828,10 +1992,10 @@ destroy(isc_socket_t **sockp) { ISC_LIST_UNLINK(manager->socklist, sock, link); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (ISC_LIST_EMPTY(manager->socklist)) SIGNAL(&manager->shutdown_ok); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ UNLOCK(&manager->lock); @@ -1839,10 +2003,10 @@ destroy(isc_socket_t **sockp) { } static isc_result_t -allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, - isc_socket_t **socketp) +allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, + isc__socket_t **socketp) { - isc_socket_t *sock; + isc__socket_t *sock; isc_result_t result; ISC_SOCKADDR_LEN_T cmsgbuflen; @@ -1853,7 +2017,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, result = ISC_R_UNEXPECTED; - sock->magic = 0; + sock->common.magic = 0; + sock->common.impmagic = 0; sock->references = 0; sock->manager = manager; @@ -1917,7 +2082,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, */ result = isc_mutex_init(&sock->lock); if (result != ISC_R_SUCCESS) { - sock->magic = 0; + sock->common.magic = 0; + sock->common.impmagic = 0; goto error; } @@ -1931,7 +2097,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW, NULL, sock, sock, NULL, NULL); - sock->magic = SOCKET_MAGIC; + sock->common.magic = ISCAPI_SOCKET_MAGIC; + sock->common.impmagic = SOCKET_MAGIC; *socketp = sock; return (ISC_R_SUCCESS); @@ -1956,8 +2123,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, * also close the socket. */ static void -free_socket(isc_socket_t **socketp) { - isc_socket_t *sock = *socketp; +free_socket(isc__socket_t **socketp) { + isc__socket_t *sock = *socketp; INSIST(sock->references == 0); INSIST(VALID_SOCKET(sock)); @@ -1977,7 +2144,8 @@ free_socket(isc_socket_t **socketp) { isc_mem_put(sock->manager->mctx, sock->sendcmsgbuf, sock->sendcmsgbuflen); - sock->magic = 0; + sock->common.magic = 0; + sock->common.impmagic = 0; DESTROYLOCK(&sock->lock); @@ -2025,7 +2193,7 @@ clear_bsdcompat(void) { #endif static isc_result_t -opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) { +opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; @@ -2316,11 +2484,12 @@ opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) { * called with 'arg' as the arg value. The new socket is returned * in 'socketp'. */ -isc_result_t -isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, - isc_socket_t **socketp) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp) { - isc_socket_t *sock = NULL; + isc__socket_t *sock = NULL; + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; isc_result_t result; int lockid; @@ -2356,8 +2525,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, return (result); } + sock->common.methods = (isc_socketmethods_t *)&socketmethods; sock->references = 1; - *socketp = sock; + *socketp = (isc_socket_t *)sock; /* * Note we don't have to lock the socket like we normally would because @@ -2388,9 +2558,11 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, return (ISC_R_SUCCESS); } -isc_result_t -isc_socket_open(isc_socket_t *sock) { +#ifdef BIND9 +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_open(isc_socket_t *sock0) { isc_result_t result; + isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); @@ -2430,6 +2602,7 @@ isc_socket_open(isc_socket_t *sock) { return (result); } +#endif /* BIND9 */ /* * Create a new 'type' socket managed by 'manager'. Events @@ -2437,12 +2610,13 @@ isc_socket_open(isc_socket_t *sock) { * called with 'arg' as the arg value. The new socket is returned * in 'socketp'. */ -isc_result_t -isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, - isc_sockfdwatch_t callback, void *cbarg, - isc_task_t *task, isc_socket_t **socketp) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags, + isc_sockfdwatch_t callback, void *cbarg, + isc_task_t *task, isc_socket_t **socketp) { - isc_socket_t *sock = NULL; + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; + isc__socket_t *sock = NULL; isc_result_t result; int lockid; @@ -2460,8 +2634,9 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, sock->fdwatchtask = task; sock->statsindex = fdwatchstatsindex; + sock->common.methods = (isc_socketmethods_t *)&socketmethods; sock->references = 1; - *socketp = sock; + *socketp = (isc_socket_t *)sock; /* * Note we don't have to lock the socket like we normally would because @@ -2494,10 +2669,50 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, } /* + * Indicate to the manager that it should watch the socket again. + * This can be used to restart watching if the previous event handler + * didn't indicate there was more data to be processed. Primarily + * it is for writing but could be used for reading if desired + */ + +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags) +{ + isc__socket_t *sock = (isc__socket_t *)sock0; + + REQUIRE(VALID_SOCKET(sock)); + + /* + * We check both flags first to allow us to get the lock + * once but only if we need it. + */ + + if ((flags & (ISC_SOCKFDWATCH_READ | ISC_SOCKFDWATCH_WRITE)) != 0) { + LOCK(&sock->lock); + if (((flags & ISC_SOCKFDWATCH_READ) != 0) && + !sock->pending_recv) + select_poke(sock->manager, sock->fd, + SELECT_POKE_READ); + if (((flags & ISC_SOCKFDWATCH_WRITE) != 0) && + !sock->pending_send) + select_poke(sock->manager, sock->fd, + SELECT_POKE_WRITE); + UNLOCK(&sock->lock); + } + + socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, + ISC_MSG_POKED, "fdwatch-poked flags: %d", flags); + + return (ISC_R_SUCCESS); +} + +/* * Attach to a socket. Caller must explicitly detach when it is done. */ -void -isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { +ISC_SOCKETFUNC_SCOPE void +isc__socket_attach(isc_socket_t *sock0, isc_socket_t **socketp) { + isc__socket_t *sock = (isc__socket_t *)sock0; + REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); @@ -2505,20 +2720,20 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { sock->references++; UNLOCK(&sock->lock); - *socketp = sock; + *socketp = (isc_socket_t *)sock; } /* * Dereference a socket. If this is the last reference to it, clean things * up by destroying the socket. */ -void -isc_socket_detach(isc_socket_t **socketp) { - isc_socket_t *sock; +ISC_SOCKETFUNC_SCOPE void +isc__socket_detach(isc_socket_t **socketp) { + isc__socket_t *sock; isc_boolean_t kill_socket = ISC_FALSE; REQUIRE(socketp != NULL); - sock = *socketp; + sock = (isc__socket_t *)*socketp; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -2534,10 +2749,12 @@ isc_socket_detach(isc_socket_t **socketp) { *socketp = NULL; } -isc_result_t -isc_socket_close(isc_socket_t *sock) { +#ifdef BIND9 +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_close(isc_socket_t *sock0) { + isc__socket_t *sock = (isc__socket_t *)sock0; int fd; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; isc_sockettype_t type; REQUIRE(VALID_SOCKET(sock)); @@ -2575,6 +2792,7 @@ isc_socket_close(isc_socket_t *sock) { return (ISC_R_SUCCESS); } +#endif /* BIND9 */ /* * I/O is possible on a given socket. Schedule an event to this task that @@ -2585,7 +2803,7 @@ isc_socket_close(isc_socket_t *sock) { * The socket and manager must be locked before calling this function. */ static void -dispatch_recv(isc_socket_t *sock) { +dispatch_recv(isc__socket_t *sock) { intev_t *iev; isc_socketevent_t *ev; isc_task_t *sender; @@ -2619,7 +2837,7 @@ dispatch_recv(isc_socket_t *sock) { } static void -dispatch_send(isc_socket_t *sock) { +dispatch_send(isc__socket_t *sock) { intev_t *iev; isc_socketevent_t *ev; isc_task_t *sender; @@ -2656,7 +2874,7 @@ dispatch_send(isc_socket_t *sock) { * Dispatch an internal accept event. */ static void -dispatch_accept(isc_socket_t *sock) { +dispatch_accept(isc__socket_t *sock) { intev_t *iev; isc_socket_newconnev_t *ev; @@ -2682,7 +2900,7 @@ dispatch_accept(isc_socket_t *sock) { } static void -dispatch_connect(isc_socket_t *sock) { +dispatch_connect(isc__socket_t *sock) { intev_t *iev; isc_socket_connev_t *ev; @@ -2712,7 +2930,7 @@ dispatch_connect(isc_socket_t *sock) { * Caller must have the socket locked if the event is attached to the socket. */ static void -send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) { +send_recvdone_event(isc__socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; task = (*dev)->ev_sender; @@ -2735,7 +2953,7 @@ send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) { * Caller must have the socket locked if the event is attached to the socket. */ static void -send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) { +send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; INSIST(dev != NULL && *dev != NULL); @@ -2766,8 +2984,8 @@ send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) { */ static void internal_accept(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; - isc_socketmgr_t *manager; + isc__socket_t *sock; + isc__socketmgr_t *manager; isc_socket_newconnev_t *dev; isc_task_t *task; ISC_SOCKADDR_LEN_T addrlen; @@ -2822,9 +3040,9 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { * daemons such as BIND 8 and Apache. */ - addrlen = sizeof(dev->newsocket->peer_address.type); - memset(&dev->newsocket->peer_address.type, 0, addrlen); - fd = accept(sock->fd, &dev->newsocket->peer_address.type.sa, + addrlen = sizeof(NEWCONNSOCK(dev)->peer_address.type); + memset(&NEWCONNSOCK(dev)->peer_address.type, 0, addrlen); + fd = accept(sock->fd, &NEWCONNSOCK(dev)->peer_address.type.sa, (void *)&addrlen); #ifdef F_DUPFD @@ -2894,14 +3112,14 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { (void)close(fd); goto soft_error; - } else if (dev->newsocket->peer_address.type.sa.sa_family != + } 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)", - dev->newsocket->peer_address. + NEWCONNSOCK(dev)->peer_address. type.sa.sa_family, sock->pf); (void)close(fd); @@ -2920,8 +3138,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { } if (fd != -1) { - dev->newsocket->peer_address.length = addrlen; - dev->newsocket->pf = sock->pf; + NEWCONNSOCK(dev)->peer_address.length = addrlen; + NEWCONNSOCK(dev)->pf = sock->pf; } /* @@ -2950,28 +3168,28 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { int lockid = FDLOCK_ID(fd); LOCK(&manager->fdlock[lockid]); - manager->fds[fd] = dev->newsocket; + manager->fds[fd] = NEWCONNSOCK(dev); manager->fdstate[fd] = MANAGED; UNLOCK(&manager->fdlock[lockid]); LOCK(&manager->lock); - ISC_LIST_APPEND(manager->socklist, dev->newsocket, link); + ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); - dev->newsocket->fd = fd; - dev->newsocket->bound = 1; - dev->newsocket->connected = 1; + NEWCONNSOCK(dev)->fd = fd; + NEWCONNSOCK(dev)->bound = 1; + NEWCONNSOCK(dev)->connected = 1; /* * Save away the remote address */ - dev->address = dev->newsocket->peer_address; + dev->address = NEWCONNSOCK(dev)->peer_address; #ifdef USE_SELECT if (manager->maxfd < fd) manager->maxfd = fd; #endif - socket_log(sock, &dev->newsocket->peer_address, CREATION, + socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN, "accepted connection, new socket %p", dev->newsocket); @@ -2981,8 +3199,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]); } else { inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]); - dev->newsocket->references--; - free_socket(&dev->newsocket); + NEWCONNSOCK(dev)->references--; + free_socket((isc__socket_t **)&dev->newsocket); } /* @@ -3006,7 +3224,7 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { static void internal_recv(isc_task_t *me, isc_event_t *ev) { isc_socketevent_t *dev; - isc_socket_t *sock; + isc__socket_t *sock; INSIST(ev->ev_type == ISC_SOCKEVENT_INTR); @@ -3071,14 +3289,14 @@ internal_recv(isc_task_t *me, isc_event_t *ev) { static void internal_send(isc_task_t *me, isc_event_t *ev) { isc_socketevent_t *dev; - isc_socket_t *sock; + isc__socket_t *sock; INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); /* * Find out what socket this is and lock it. */ - sock = (isc_socket_t *)ev->ev_sender; + sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -3125,7 +3343,7 @@ internal_send(isc_task_t *me, isc_event_t *ev) { static void internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; + isc__socket_t *sock; int more_data; INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); @@ -3133,7 +3351,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) { /* * Find out what socket this is and lock it. */ - sock = (isc_socket_t *)ev->ev_sender; + sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -3144,7 +3362,8 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) { INSIST(sock->pending_send == 1); UNLOCK(&sock->lock); - more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg); + more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock, + sock->fdwatcharg, ISC_SOCKFDWATCH_WRITE); LOCK(&sock->lock); sock->pending_send = 0; @@ -3165,7 +3384,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) { static void internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; + isc__socket_t *sock; int more_data; INSIST(ev->ev_type == ISC_SOCKEVENT_INTR); @@ -3173,7 +3392,7 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { /* * Find out what socket this is and lock it. */ - sock = (isc_socket_t *)ev->ev_sender; + sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -3184,7 +3403,8 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { INSIST(sock->pending_recv == 1); UNLOCK(&sock->lock); - more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg); + more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock, + sock->fdwatcharg, ISC_SOCKFDWATCH_READ); LOCK(&sock->lock); sock->pending_recv = 0; @@ -3208,10 +3428,10 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { * and unlocking twice if both reads and writes are possible. */ static void -process_fd(isc_socketmgr_t *manager, int fd, isc_boolean_t readable, +process_fd(isc__socketmgr_t *manager, int fd, isc_boolean_t readable, isc_boolean_t writeable) { - isc_socket_t *sock; + isc__socket_t *sock; isc_boolean_t unlock_sock; isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE; int lockid = FDLOCK_ID(fd); @@ -3277,11 +3497,11 @@ check_write: #ifdef USE_KQUEUE static isc_boolean_t -process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) { +process_fds(isc__socketmgr_t *manager, struct kevent *events, int nevents) { int i; isc_boolean_t readable, writable; isc_boolean_t done = ISC_FALSE; -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif @@ -3299,7 +3519,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) { for (i = 0; i < nevents; i++) { REQUIRE(events[i].ident < manager->maxsocks); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (events[i].ident == (uintptr_t)manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; @@ -3310,7 +3530,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) { process_fd(manager, events[i].ident, readable, writable); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif @@ -3319,10 +3539,11 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) { } #elif defined(USE_EPOLL) static isc_boolean_t -process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) { +process_fds(isc__socketmgr_t *manager, struct epoll_event *events, int nevents) +{ int i; isc_boolean_t done = ISC_FALSE; -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif @@ -3335,7 +3556,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) { for (i = 0; i < nevents; i++) { REQUIRE(events[i].data.fd < (int)manager->maxsocks); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (events[i].data.fd == manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; @@ -3357,7 +3578,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) { (events[i].events & EPOLLOUT) != 0); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif @@ -3366,10 +3587,10 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) { } #elif defined(USE_DEVPOLL) static isc_boolean_t -process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) { +process_fds(isc__socketmgr_t *manager, struct pollfd *events, int nevents) { int i; isc_boolean_t done = ISC_FALSE; -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif @@ -3382,7 +3603,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) { for (i = 0; i < nevents; i++) { REQUIRE(events[i].fd < (int)manager->maxsocks); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (events[i].fd == manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; @@ -3393,7 +3614,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) { (events[i].events & POLLOUT) != 0); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif @@ -3402,27 +3623,27 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) { } #elif defined(USE_SELECT) static void -process_fds(isc_socketmgr_t *manager, int maxfd, - fd_set *readfds, fd_set *writefds) +process_fds(isc__socketmgr_t *manager, int maxfd, fd_set *readfds, + fd_set *writefds) { int i; REQUIRE(maxfd <= (int)manager->maxsocks); for (i = 0; i < maxfd; i++) { -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1]) continue; -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ process_fd(manager, i, FD_ISSET(i, readfds), FD_ISSET(i, writefds)); } } #endif -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD static isc_boolean_t -process_ctlfd(isc_socketmgr_t *manager) { +process_ctlfd(isc__socketmgr_t *manager) { int msg, fd; for (;;) { @@ -3470,7 +3691,7 @@ process_ctlfd(isc_socketmgr_t *manager) { */ static isc_threadresult_t watcher(void *uap) { - isc_socketmgr_t *manager = uap; + isc__socketmgr_t *manager = uap; isc_boolean_t done; int ctlfd; int cc; @@ -3585,22 +3806,34 @@ watcher(void *uap) { return ((isc_threadresult_t)0); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ -void -isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) { +#ifdef BIND9 +ISC_SOCKETFUNC_SCOPE void +isc__socketmgr_setreserved(isc_socketmgr_t *manager0, isc_uint32_t reserved) { + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); manager->reserved = reserved; } +ISC_SOCKETFUNC_SCOPE void +isc___socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) { + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; + + REQUIRE(VALID_MANAGER(manager)); + + manager->maxudp = maxudp; +} +#endif /* BIND9 */ + /* * Create a new socket manager. */ static isc_result_t -setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { +setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) { isc_result_t result; #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) char strbuf[ISC_STRERRORSIZE]; @@ -3626,7 +3859,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { return (result); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->kqueue_fd); @@ -3634,7 +3867,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { sizeof(struct kevent) * manager->nevents); return (result); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ #elif defined(USE_EPOLL) manager->nevents = ISC_SOCKET_MAXEVENTS; manager->events = isc_mem_get(mctx, sizeof(struct epoll_event) * @@ -3654,7 +3887,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { sizeof(struct epoll_event) * manager->nevents); return (result); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->epoll_fd); @@ -3662,7 +3895,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { sizeof(struct epoll_event) * manager->nevents); return (result); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ #elif defined(USE_DEVPOLL) /* * XXXJT: /dev/poll seems to reject large numbers of events, @@ -3700,7 +3933,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { sizeof(pollinfo_t) * manager->maxsocks); return (result); } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->devpoll_fd); @@ -3710,7 +3943,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { sizeof(pollinfo_t) * manager->maxsocks); return (result); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ #elif defined(USE_SELECT) UNUSED(result); @@ -3758,20 +3991,20 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { memset(manager->read_fds, 0, manager->fd_bufsize); memset(manager->write_fds, 0, manager->fd_bufsize); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD (void)watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); manager->maxfd = manager->pipe_fds[0]; -#else /* ISC_PLATFORM_USETHREADS */ +#else /* USE_WATCHER_THREAD */ manager->maxfd = 0; -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ #endif /* USE_KQUEUE */ return (ISC_R_SUCCESS); } static void -cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { -#ifdef ISC_PLATFORM_USETHREADS +cleanup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) { +#ifdef USE_WATCHER_THREAD isc_result_t result; result = unwatch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); @@ -3781,7 +4014,7 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ #ifdef USE_KQUEUE close(manager->kqueue_fd); @@ -3809,35 +4042,35 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { #endif /* USE_KQUEUE */ } -isc_result_t -isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { - return (isc_socketmgr_create2(mctx, managerp, 0)); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { + return (isc__socketmgr_create2(mctx, managerp, 0)); } -isc_result_t -isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, - unsigned int maxsocks) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, + unsigned int maxsocks) { int i; - isc_socketmgr_t *manager; -#ifdef ISC_PLATFORM_USETHREADS + isc__socketmgr_t *manager; +#ifdef USE_WATCHER_THREAD char strbuf[ISC_STRERRORSIZE]; #endif isc_result_t result; REQUIRE(managerp != NULL && *managerp == NULL); -#ifndef ISC_PLATFORM_USETHREADS +#ifdef USE_SHARED_MANAGER if (socketmgr != NULL) { /* Don't allow maxsocks to be updated */ if (maxsocks > 0 && socketmgr->maxsocks != maxsocks) return (ISC_R_EXISTS); socketmgr->refs++; - *managerp = socketmgr; + *managerp = (isc_socketmgr_t *)socketmgr; return (ISC_R_SUCCESS); } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_SHARED_MANAGER */ if (maxsocks == 0) maxsocks = ISC_SOCKET_MAXSOCKETS; @@ -3850,8 +4083,9 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, memset(manager, 0, sizeof(*manager)); manager->maxsocks = maxsocks; manager->reserved = 0; + manager->maxudp = 0; manager->fds = isc_mem_get(mctx, - manager->maxsocks * sizeof(isc_socket_t *)); + manager->maxsocks * sizeof(isc__socket_t *)); if (manager->fds == NULL) { result = ISC_R_NOMEMORY; goto free_manager; @@ -3863,7 +4097,9 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, } manager->stats = NULL; - manager->magic = SOCKET_MANAGER_MAGIC; + manager->common.methods = &socketmgrmethods; + manager->common.magic = ISCAPI_SOCKETMGR_MAGIC; + manager->common.impmagic = SOCKET_MANAGER_MAGIC; manager->mctx = NULL; memset(manager->fds, 0, manager->maxsocks * sizeof(isc_socket_t *)); ISC_LIST_INIT(manager->socklist); @@ -3887,7 +4123,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, } } -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", @@ -3916,9 +4152,11 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, #if 0 RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS); #endif -#else /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ + +#ifdef USE_SHARED_MANAGER manager->refs = 1; -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_SHARED_MANAGER */ /* * Set up initial state for the select loop @@ -3927,7 +4165,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, if (result != ISC_R_SUCCESS) goto cleanup; memset(manager->fdstate, 0, manager->maxsocks * sizeof(int)); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD /* * Start up the select/poll thread. */ @@ -3941,26 +4179,26 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, result = ISC_R_UNEXPECTED; goto cleanup; } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ isc_mem_attach(mctx, &manager->mctx); -#ifndef ISC_PLATFORM_USETHREADS +#ifdef USE_SHARED_MANAGER socketmgr = manager; -#endif /* ISC_PLATFORM_USETHREADS */ - *managerp = manager; +#endif /* USE_SHARED_MANAGER */ + *managerp = (isc_socketmgr_t *)manager; return (ISC_R_SUCCESS); cleanup: -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD (void)close(manager->pipe_fds[0]); (void)close(manager->pipe_fds[1]); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD cleanup_condition: (void)isc_condition_destroy(&manager->shutdown_ok); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ cleanup_lock: @@ -3988,8 +4226,10 @@ free_manager: return (result); } +#ifdef BIND9 isc_result_t -isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) { +isc__socketmgr_getmaxsockets(isc_socketmgr_t *manager0, unsigned int *nsockp) { + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); REQUIRE(nsockp != NULL); @@ -3999,7 +4239,9 @@ isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) { } void -isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) { +isc__socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats) { + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; + REQUIRE(VALID_MANAGER(manager)); REQUIRE(ISC_LIST_EMPTY(manager->socklist)); REQUIRE(manager->stats == NULL); @@ -4007,10 +4249,11 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) { isc_stats_attach(stats, &manager->stats); } +#endif -void -isc_socketmgr_destroy(isc_socketmgr_t **managerp) { - isc_socketmgr_t *manager; +ISC_SOCKETFUNC_SCOPE void +isc__socketmgr_destroy(isc_socketmgr_t **managerp) { + isc__socketmgr_t *manager; int i; isc_mem_t *mctx; @@ -4019,42 +4262,36 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { */ REQUIRE(managerp != NULL); - manager = *managerp; + manager = (isc__socketmgr_t *)*managerp; REQUIRE(VALID_MANAGER(manager)); -#ifndef ISC_PLATFORM_USETHREADS - if (manager->refs > 1) { - manager->refs--; +#ifdef USE_SHARED_MANAGER + manager->refs--; + if (manager->refs > 0) { *managerp = NULL; return; } -#endif /* ISC_PLATFORM_USETHREADS */ + socketmgr = NULL; +#endif /* USE_SHARED_MANAGER */ LOCK(&manager->lock); -#ifdef ISC_PLATFORM_USETHREADS /* * Wait for all sockets to be destroyed. */ while (!ISC_LIST_EMPTY(manager->socklist)) { +#ifdef USE_WATCHER_THREAD manager_log(manager, CREATION, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SOCKETSREMAIN, "sockets exist")); WAIT(&manager->shutdown_ok, &manager->lock); +#else /* USE_WATCHER_THREAD */ + UNLOCK(&manager->lock); + isc__taskmgr_dispatch(NULL); + LOCK(&manager->lock); +#endif /* USE_WATCHER_THREAD */ } -#else /* ISC_PLATFORM_USETHREADS */ - /* - * Hope all sockets have been destroyed. - */ - if (!ISC_LIST_EMPTY(manager->socklist)) { - manager_log(manager, CREATION, "%s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_SOCKETSREMAIN, - "sockets exist")); - INSIST(0); - } -#endif /* ISC_PLATFORM_USETHREADS */ UNLOCK(&manager->lock); @@ -4065,7 +4302,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { */ select_poke(manager, 0, SELECT_POKE_SHUTDOWN); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD /* * Wait for thread to exit. */ @@ -4074,25 +4311,25 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { "isc_thread_join() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ /* * Clean up. */ cleanup_watcher(manager->mctx, manager); -#ifdef ISC_PLATFORM_USETHREADS +#ifdef USE_WATCHER_THREAD (void)close(manager->pipe_fds[0]); (void)close(manager->pipe_fds[1]); (void)isc_condition_destroy(&manager->shutdown_ok); -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ for (i = 0; i < (int)manager->maxsocks; i++) if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */ (void)close(i); isc_mem_put(manager->mctx, manager->fds, - manager->maxsocks * sizeof(isc_socket_t *)); + manager->maxsocks * sizeof(isc__socket_t *)); isc_mem_put(manager->mctx, manager->fdstate, manager->maxsocks * sizeof(int)); @@ -4106,17 +4343,22 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) { FDLOCK_COUNT * sizeof(isc_mutex_t)); } DESTROYLOCK(&manager->lock); - manager->magic = 0; + manager->common.magic = 0; + manager->common.impmagic = 0; mctx= manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; + +#ifdef USE_SHARED_MANAGER + socketmgr = NULL; +#endif } static isc_result_t -socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, +socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, unsigned int flags) { int io_state; @@ -4187,13 +4429,14 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, return (result); } -isc_result_t -isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, - unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist, + unsigned int minimum, isc_task_t *task, + isc_taskaction_t action, const void *arg) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; @@ -4241,12 +4484,14 @@ isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, return (socket_recv(sock, dev, task, 0)); } -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, const void *arg) +ISC_SOCKETFUNC_SCOPE 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, const void *arg) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; REQUIRE(VALID_SOCKET(sock)); REQUIRE(action != NULL); @@ -4260,14 +4505,16 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, if (dev == NULL) return (ISC_R_NOMEMORY); - return (isc_socket_recv2(sock, region, minimum, task, dev, 0)); + return (isc__socket_recv2(sock0, region, minimum, task, dev, 0)); } -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_SOCKETFUNC_SCOPE 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) { + isc__socket_t *sock = (isc__socket_t *)sock0; + event->ev_sender = sock; event->result = ISC_R_UNEXPECTED; ISC_LIST_INIT(event->bufferlist); @@ -4292,7 +4539,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, +socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { @@ -4383,24 +4630,25 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, return (result); } -isc_result_t -isc_socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_send(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, isc_taskaction_t action, const 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, const void *arg, - isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region, + isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; REQUIRE(VALID_SOCKET(sock)); REQUIRE(region != NULL); @@ -4422,21 +4670,22 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, return (socket_send(sock, dev, task, address, pktinfo, 0)); } -isc_result_t -isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, + isc_task_t *task, isc_taskaction_t action, const void *arg) { - return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL, - NULL)); + return (isc__socket_sendtov(sock, buflist, task, action, arg, NULL, + NULL)); } -isc_result_t -isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, - isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist, + isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; @@ -4470,12 +4719,15 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, return (socket_send(sock, dev, task, address, pktinfo, 0)); } -isc_result_t -isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, - isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, - isc_socketevent_t *event, unsigned int flags) +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_sendto2(isc_socket_t *sock0, isc_region_t *region, + isc_task_t *task, + 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(sock->type == isc_sockettype_udp); @@ -4490,8 +4742,8 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, return (socket_send(sock, event, task, address, pktinfo, flags)); } -void -isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) { +ISC_SOCKETFUNC_SCOPE void +isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) { #ifdef ISC_PLATFORM_HAVESYSUNH int s; struct stat sb; @@ -4620,8 +4872,8 @@ isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) { #endif } -isc_result_t -isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group) { #ifdef ISC_PLATFORM_HAVESYSUNH @@ -4674,12 +4926,15 @@ isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, #endif } -isc_result_t -isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, - unsigned int options) { +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr, + unsigned int options) { + isc__socket_t *sock = (isc__socket_t *)sock0; char strbuf[ISC_STRERRORSIZE]; int on = 1; + REQUIRE(VALID_SOCKET(sock)); + LOCK(&sock->lock); INSIST(!sock->bound); @@ -4745,8 +5000,9 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, */ #undef ENABLE_ACCEPTFILTER -isc_result_t -isc_socket_filter(isc_socket_t *sock, const char *filter) { +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_filter(isc_socket_t *sock0, const char *filter) { + isc__socket_t *sock = (isc__socket_t *)sock0; #if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) char strbuf[ISC_STRERRORSIZE]; struct accept_filter_arg afa; @@ -4784,8 +5040,9 @@ isc_socket_filter(isc_socket_t *sock, const char *filter) { * is a new connection we'll have to allocate a new one anyway, so we might * as well keep things simple rather than having to track them. */ -isc_result_t -isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) { + isc__socket_t *sock = (isc__socket_t *)sock0; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); @@ -4818,14 +5075,15 @@ 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_SOCKETFUNC_SCOPE isc_result_t +isc__socket_accept(isc_socket_t *sock0, isc_task_t *task, isc_taskaction_t action, const void *arg) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_newconnev_t *dev; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; isc_task_t *ntask = NULL; - isc_socket_t *nsock; + isc__socket_t *nsock; isc_result_t result; isc_boolean_t do_poke = ISC_FALSE; @@ -4872,7 +5130,7 @@ isc_socket_accept(isc_socket_t *sock, nsock->statsindex = sock->statsindex; dev->ev_sender = ntask; - dev->newsocket = nsock; + dev->newsocket = (isc_socket_t *)nsock; /* * Poke watcher here. We still have the socket locked, so there @@ -4891,13 +5149,14 @@ isc_socket_accept(isc_socket_t *sock, return (ISC_R_SUCCESS); } -isc_result_t -isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, const void *arg) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_connev_t *dev; isc_task_t *ntask = NULL; - isc_socketmgr_t *manager; + isc__socketmgr_t *manager; int cc; char strbuf[ISC_STRERRORSIZE]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; @@ -5037,7 +5296,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, */ static void internal_connect(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; + isc__socket_t *sock; isc_socket_connev_t *dev; isc_task_t *task; int cc; @@ -5151,8 +5410,9 @@ internal_connect(isc_task_t *me, isc_event_t *ev) { isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev)); } -isc_result_t -isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) { +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_getpeername(isc_socket_t *sock0, isc_sockaddr_t *addressp) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_result_t result; REQUIRE(VALID_SOCKET(sock)); @@ -5172,8 +5432,9 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) { return (result); } -isc_result_t -isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_getsockname(isc_socket_t *sock0, isc_sockaddr_t *addressp) { + isc__socket_t *sock = (isc__socket_t *)sock0; ISC_SOCKADDR_LEN_T len; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; @@ -5210,8 +5471,9 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { * Run through the list of events on this socket, and cancel the ones * queued for task "task" of type "how". "how" is a bitmask. */ -void -isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { +ISC_SOCKETFUNC_SCOPE void +isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { + isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); @@ -5290,8 +5552,8 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { ISC_LIST_UNLINK(sock->accept_list, dev, ev_link); - dev->newsocket->references--; - free_socket(&dev->newsocket); + NEWCONNSOCK(dev)->references--; + free_socket((isc__socket_t **)&dev->newsocket); dev->result = ISC_R_CANCELED; dev->ev_sender = sock; @@ -5330,17 +5592,22 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { UNLOCK(&sock->lock); } -isc_sockettype_t -isc_socket_gettype(isc_socket_t *sock) { +ISC_SOCKETFUNC_SCOPE isc_sockettype_t +isc__socket_gettype(isc_socket_t *sock0) { + isc__socket_t *sock = (isc__socket_t *)sock0; + REQUIRE(VALID_SOCKET(sock)); return (sock->type); } -isc_boolean_t -isc_socket_isbound(isc_socket_t *sock) { +ISC_SOCKETFUNC_SCOPE isc_boolean_t +isc__socket_isbound(isc_socket_t *sock0) { + isc__socket_t *sock = (isc__socket_t *)sock0; isc_boolean_t val; + REQUIRE(VALID_SOCKET(sock)); + LOCK(&sock->lock); val = ((sock->bound) ? ISC_TRUE : ISC_FALSE); UNLOCK(&sock->lock); @@ -5348,8 +5615,9 @@ isc_socket_isbound(isc_socket_t *sock) { return (val); } -void -isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { +ISC_SOCKETFUNC_SCOPE void +isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) { + isc__socket_t *sock = (isc__socket_t *)sock0; #if defined(IPV6_V6ONLY) int onoff = yes ? 1 : 0; #else @@ -5379,12 +5647,21 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { #endif } -#ifndef ISC_PLATFORM_USETHREADS -/* In our assumed scenario, we can simply use a single static object. */ +#ifndef USE_WATCHER_THREAD +/* + * In our assumed scenario, we can simply use a single static object. + * XXX: this is not true if the application uses multiple threads with + * 'multi-context' mode. Fixing this is a future TODO item. + */ static isc_socketwait_t swait_private; int -isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) { +isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp, + isc_socketwait_t **swaitp) +{ + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; + + int n; #ifdef USE_KQUEUE struct timespec ts, *tsp; @@ -5398,7 +5675,11 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) { REQUIRE(swaitp != NULL && *swaitp == NULL); - if (socketmgr == NULL) +#ifdef USE_SHARED_MANAGER + if (manager == NULL) + manager = socketmgr; +#endif + if (manager == NULL) return (0); #ifdef USE_KQUEUE @@ -5408,8 +5689,8 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) { tsp = &ts; } else tsp = NULL; - swait_private.nevents = kevent(socketmgr->kqueue_fd, NULL, 0, - socketmgr->events, socketmgr->nevents, + swait_private.nevents = kevent(manager->kqueue_fd, NULL, 0, + manager->events, manager->nevents, tsp); n = swait_private.nevents; #elif defined(USE_EPOLL) @@ -5417,29 +5698,28 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) { timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000; else timeout = -1; - swait_private.nevents = epoll_wait(socketmgr->epoll_fd, - socketmgr->events, - socketmgr->nevents, timeout); + swait_private.nevents = epoll_wait(manager->epoll_fd, + manager->events, + manager->nevents, timeout); n = swait_private.nevents; #elif defined(USE_DEVPOLL) - dvp.dp_fds = socketmgr->events; - dvp.dp_nfds = socketmgr->nevents; + dvp.dp_fds = manager->events; + dvp.dp_nfds = manager->nevents; if (tvp != NULL) { dvp.dp_timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000; } else dvp.dp_timeout = -1; - swait_private.nevents = ioctl(socketmgr->devpoll_fd, DP_POLL, &dvp); + swait_private.nevents = ioctl(manager->devpoll_fd, DP_POLL, &dvp); n = swait_private.nevents; #elif defined(USE_SELECT) - memcpy(socketmgr->read_fds_copy, socketmgr->read_fds, - socketmgr->fd_bufsize); - memcpy(socketmgr->write_fds_copy, socketmgr->write_fds, - socketmgr->fd_bufsize); + memcpy(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize); + memcpy(manager->write_fds_copy, manager->write_fds, + manager->fd_bufsize); - swait_private.readset = socketmgr->read_fds_copy; - swait_private.writeset = socketmgr->write_fds_copy; - swait_private.maxfd = socketmgr->maxfd + 1; + swait_private.readset = manager->read_fds_copy; + swait_private.writeset = manager->write_fds_copy; + swait_private.maxfd = manager->maxfd + 1; n = select(swait_private.maxfd, swait_private.readset, swait_private.writeset, NULL, tvp); @@ -5450,24 +5730,32 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) { } isc_result_t -isc__socketmgr_dispatch(isc_socketwait_t *swait) { +isc__socketmgr_dispatch(isc_socketmgr_t *manager0, isc_socketwait_t *swait) { + isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; + REQUIRE(swait == &swait_private); - if (socketmgr == NULL) +#ifdef USE_SHARED_MANAGER + if (manager == NULL) + manager = socketmgr; +#endif + if (manager == NULL) return (ISC_R_NOTFOUND); #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) - (void)process_fds(socketmgr, socketmgr->events, swait->nevents); + (void)process_fds(manager, manager->events, swait->nevents); return (ISC_R_SUCCESS); #elif defined(USE_SELECT) - process_fds(socketmgr, swait->maxfd, swait->readset, swait->writeset); + process_fds(manager, swait->maxfd, swait->readset, swait->writeset); return (ISC_R_SUCCESS); #endif } -#endif /* ISC_PLATFORM_USETHREADS */ +#endif /* USE_WATCHER_THREAD */ +#ifdef BIND9 void -isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) { +isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag) { + isc__socket_t *socket = (isc__socket_t *)socket0; /* * Name 'socket'. @@ -5482,17 +5770,29 @@ isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) { UNLOCK(&socket->lock); } -const char * -isc_socket_getname(isc_socket_t *socket) { +ISC_SOCKETFUNC_SCOPE const char * +isc__socket_getname(isc_socket_t *socket0) { + isc__socket_t *socket = (isc__socket_t *)socket0; + return (socket->name); } void * -isc_socket_gettag(isc_socket_t *socket) { +isc__socket_gettag(isc_socket_t *socket0) { + isc__socket_t *socket = (isc__socket_t *)socket0; + return (socket->tag); } +#endif /* BIND9 */ -#ifdef HAVE_LIBXML2 +#ifdef USE_SOCKETIMPREGISTER +isc_result_t +isc__socket_register() { + return (isc_socket_register(isc__socketmgr_create)); +} +#endif + +#if defined(HAVE_LIBXML2) && defined(BIND9) static const char * _socktype(isc_sockettype_t type) @@ -5509,21 +5809,21 @@ _socktype(isc_sockettype_t type) return ("not-initialized"); } -void -isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer) -{ - isc_socket_t *sock; +ISC_SOCKETFUNC_SCOPE void +isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { + isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; + isc__socket_t *sock; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; LOCK(&mgr->lock); -#ifndef ISC_PLATFORM_USETHREADS +#ifdef USE_SHARED_MANAGER xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); xmlTextWriterEndElement(writer); -#endif +#endif /* USE_SHARED_MANAGER */ xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"); sock = ISC_LIST_HEAD(mgr->socklist); diff --git a/contrib/bind9/lib/isc/unix/socket_p.h b/contrib/bind9/lib/isc/unix/socket_p.h index b9a2347..b6c4b6a 100644 --- a/contrib/bind9/lib/isc/unix/socket_p.h +++ b/contrib/bind9/lib/isc/unix/socket_p.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket_p.h,v 1.13 2008-06-23 23:47:11 tbox Exp $ */ +/* $Id: socket_p.h,v 1.15 2009-09-02 23:48:03 tbox Exp $ */ #ifndef ISC_SOCKET_P_H #define ISC_SOCKET_P_H @@ -27,6 +27,7 @@ #endif typedef struct isc_socketwait isc_socketwait_t; -int isc__socketmgr_waitevents(struct timeval *, isc_socketwait_t **); -isc_result_t isc__socketmgr_dispatch(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/contrib/bind9/lib/isc/unix/strerror.c b/contrib/bind9/lib/isc/unix/strerror.c index 08ea52d..4a61a97 100644 --- a/contrib/bind9/lib/isc/unix/strerror.c +++ b/contrib/bind9/lib/isc/unix/strerror.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: strerror.c,v 1.8.332.2 2009-02-16 23:47:15 tbox Exp $ */ +/* $Id: strerror.c,v 1.10 2009-02-16 23:48:04 tbox Exp $ */ /*! \file */ |