diff options
Diffstat (limited to 'contrib/bind9/lib/isc/unix')
37 files changed, 0 insertions, 10246 deletions
diff --git a/contrib/bind9/lib/isc/unix/Makefile.in b/contrib/bind9/lib/isc/unix/Makefile.in deleted file mode 100644 index 49845d420d5b..000000000000 --- a/contrib/bind9/lib/isc/unix/Makefile.in +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -# $Id: Makefile.in,v 1.35.2.1.10.2 2004/06/22 02:48:36 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -CINCLUDES = -I${srcdir}/include \ - -I${srcdir}/../@ISC_THREAD_DIR@/include \ - -I../include \ - -I${srcdir}/../include \ - -I${srcdir}/.. - -CDEFINES = -CWARNINGS = - -# Alphabetically -OBJS = @ISC_IPV6_O@ \ - app.@O@ dir.@O@ entropy.@O@ errno2result.@O@ file.@O@ \ - fsaccess.@O@ interfaceiter.@O@ keyboard.@O@ net.@O@ \ - os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \ - strerror.@O@ syslog.@O@ time.@O@ - -# Alphabetically -SRCS = @ISC_IPV6_C@ \ - app.c dir.c entropy.c errno2result.c file.c \ - fsaccess.c interfaceiter.c keyboard.c net.c \ - os.c resource.c socket.c stdio.c stdtime.c \ - strerror.c syslog.c time.c - -SUBDIRS = include -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ - -interfaceiter.@O@: interfaceiter.c ifiter_ioctl.c ifiter_sysctl.c ifiter_getifaddrs.c - diff --git a/contrib/bind9/lib/isc/unix/app.c b/contrib/bind9/lib/isc/unix/app.c deleted file mode 100644 index 811d67be1ff6..000000000000 --- a/contrib/bind9/lib/isc/unix/app.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: app.c,v 1.43.2.3.8.5 2004/03/08 02:08:05 marka Exp $ */ - -#include <config.h> - -#include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */ -#include <sys/types.h> - -#include <stddef.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <sys/time.h> - -#include <isc/app.h> -#include <isc/boolean.h> -#include <isc/condition.h> -#include <isc/msgs.h> -#include <isc/mutex.h> -#include <isc/event.h> -#include <isc/platform.h> -#include <isc/strerror.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/time.h> -#include <isc/util.h> - -#ifdef ISC_PLATFORM_USETHREADS -#include <pthread.h> -#else /* ISC_PLATFORM_USETHREADS */ -#include "../timer_p.h" -#include "../task_p.h" -#include "socket_p.h" -#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. - */ -static isc_boolean_t want_shutdown = ISC_FALSE; -/* - * We assume that 'want_reload' can be read and written atomically. - */ -static isc_boolean_t want_reload = ISC_FALSE; - -static isc_boolean_t blocked = ISC_FALSE; -#ifdef ISC_PLATFORM_USETHREADS -static pthread_t blockedthread; -#endif /* ISC_PLATFORM_USETHREADS */ - -#ifdef HAVE_LINUXTHREADS -/* - * Linux has sigwait(), but it appears to prevent signal handlers from - * running, even if they're not in the set being waited for. This makes - * it impossible to get the default actions for SIGILL, SIGSEGV, etc. - * Instead of messing with it, we just use sigsuspend() instead. - */ -#undef HAVE_SIGWAIT -/* - * We need to remember which thread is the main thread... - */ -static pthread_t main_thread; -#endif - -#ifndef HAVE_SIGWAIT -static void -exit_action(int arg) { - UNUSED(arg); - want_shutdown = ISC_TRUE; -} - -static void -reload_action(int arg) { - UNUSED(arg); - want_reload = ISC_TRUE; -} -#endif - -static isc_result_t -handle_signal(int sig, void (*handler)(int)) { - struct sigaction sa; - char strbuf[ISC_STRERRORSIZE]; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handler; - - if (sigfillset(&sa.sa_mask) != 0 || - sigaction(sig, &sa, NULL) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_APP, - ISC_MSG_SIGNALSETUP, - "handle_signal() %d setup: %s"), - sig, strbuf); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_start(void) { - isc_result_t result; - int presult; - sigset_t sset; - char strbuf[ISC_STRERRORSIZE]; - - /* - * Start an ISC library application. - */ - -#ifdef NEED_PTHREAD_INIT - /* - * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this. - */ - presult = pthread_init(); - if (presult != 0) { - isc__strerror(presult, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() pthread_init: %s", strbuf); - return (ISC_R_UNEXPECTED); - } -#endif - -#ifdef HAVE_LINUXTHREADS - main_thread = pthread_self(); -#endif - - result = isc_mutex_init(&lock); - if (result != ISC_R_SUCCESS) - return (result); - -#ifndef HAVE_SIGWAIT - /* - * Install do-nothing handlers for SIGINT and SIGTERM. - * - * We install them now because BSDI 3.1 won't block - * the default actions, regardless of what we do with - * pthread_sigmask(). - */ - result = handle_signal(SIGINT, exit_action); - if (result != ISC_R_SUCCESS) - return (result); - result = handle_signal(SIGTERM, exit_action); - if (result != ISC_R_SUCCESS) - return (result); -#endif - - /* - * Always ignore SIGPIPE. - */ - result = handle_signal(SIGPIPE, SIG_IGN); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * On Solaris 2, delivery of a signal whose action is SIG_IGN - * will not cause sigwait() to return. We may have inherited - * unexpected actions for SIGHUP, SIGINT, and SIGTERM from our parent - * process (e.g, Solaris cron). Set an action of SIG_DFL to make - * sure sigwait() works as expected. Only do this for SIGTERM and - * SIGINT if we don't have sigwait(), since a different handler is - * installed above. - */ - result = handle_signal(SIGHUP, SIG_DFL); - if (result != ISC_R_SUCCESS) - return (result); - -#ifdef HAVE_SIGWAIT - result = handle_signal(SIGTERM, SIG_DFL); - if (result != ISC_R_SUCCESS) - return (result); - result = handle_signal(SIGINT, SIG_DFL); - if (result != ISC_R_SUCCESS) - return (result); -#endif - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Block SIGHUP, SIGINT, SIGTERM. - * - * If isc_app_start() is called from the main thread before any other - * threads have been created, then the pthread_sigmask() call below - * will result in all threads having SIGHUP, SIGINT and SIGTERM - * blocked by default, ensuring that only the thread that calls - * sigwait() for them will get those signals. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() sigsetops: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - presult = pthread_sigmask(SIG_BLOCK, &sset, NULL); - if (presult != 0) { - isc__strerror(presult, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() pthread_sigmask: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } -#else /* ISC_PLATFORM_USETHREADS */ - /* - * Unblock SIGHUP, SIGINT, SIGTERM. - * - * If we're not using threads, we need to make sure that SIGHUP, - * SIGINT and SIGTERM are not inherited as blocked from the parent - * process. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() sigsetops: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - presult = sigprocmask(SIG_UNBLOCK, &sset, NULL); - if (presult != 0) { - isc__strerror(presult, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_start() sigprocmask: %s", strbuf); - return (ISC_R_UNEXPECTED); - } -#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, - void *arg) -{ - isc_event_t *event; - isc_task_t *cloned_task = NULL; - isc_result_t result; - - LOCK(&lock); - - if (running) { - result = ISC_R_ALREADYRUNNING; - goto unlock; - } - - /* - * Note that we store the task to which we're going to send the event - * in the event's "sender" field. - */ - isc_task_attach(task, &cloned_task); - event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, - action, arg, sizeof(*event)); - if (event == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - - ISC_LIST_APPEND(on_run, event, ev_link); - - result = ISC_R_SUCCESS; - - unlock: - UNLOCK(&lock); - - return (result); -} - -#ifndef ISC_PLATFORM_USETHREADS -/* - * Event loop for nonthreaded programs. - */ -static isc_result_t -evloop() { - isc_result_t result; - while (!want_shutdown) { - int n; - isc_time_t when, now; - struct timeval tv, *tvp; - fd_set readfds, writefds; - int maxfd; - isc_boolean_t readytasks; - isc_boolean_t call_timer_dispatch = ISC_FALSE; - - readytasks = isc__taskmgr_ready(); - if (readytasks) { - tv.tv_sec = 0; - tv.tv_usec = 0; - tvp = &tv; - call_timer_dispatch = ISC_TRUE; - } else { - result = isc__timermgr_nextevent(&when); - if (result != ISC_R_SUCCESS) - tvp = NULL; - else { - isc_uint64_t us; - - TIME_NOW(&now); - us = isc_time_microdiff(&when, &now); - if (us == 0) - call_timer_dispatch = ISC_TRUE; - tv.tv_sec = us / 1000000; - tv.tv_usec = us % 1000000; - tvp = &tv; - } - } - - isc__socketmgr_getfdsets(&readfds, &writefds, &maxfd); - n = select(maxfd, &readfds, &writefds, NULL, tvp); - - if (n == 0 || call_timer_dispatch) { - /* - * We call isc__timermgr_dispatch() only when - * necessary, in order to reduce overhead. If the - * select() call indicates a timeout, we need the - * dispatch. Even if not, if we set the 0-timeout - * for the select() call, we need to check the timer - * events. In the 'readytasks' case, there may be no - * timeout event actually, but there is no other way - * to reduce the overhead. - * Note that we do not have to worry about the case - * where a new timer is inserted during the select() - * call, since this loop only runs in the non-thread - * mode. - */ - isc__timermgr_dispatch(); - } - if (n > 0) - (void)isc__socketmgr_dispatch(&readfds, &writefds, - maxfd); - (void)isc__taskmgr_dispatch(); - - if (want_reload) { - want_reload = ISC_FALSE; - return (ISC_R_RELOAD); - } - } - return (ISC_R_SUCCESS); -} - -/* - * This is a gross hack to support waiting for condition - * variables in nonthreaded programs in a limited way; - * see lib/isc/nothreads/include/isc/condition.h. - * We implement isc_condition_wait() by entering the - * event loop recursively until the want_shutdown flag - * is set by isc_condition_signal(). - */ - -/* - * True iff we are currently executing in the recursive - * event loop. - */ -static isc_boolean_t in_recursive_evloop = ISC_FALSE; - -/* - * True iff we are exiting the event loop as the result of - * a call to isc_condition_signal() rather than a shutdown - * or reload. - */ -static isc_boolean_t signalled = ISC_FALSE; - -isc_result_t -isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) { - isc_result_t result; - - UNUSED(cp); - UNUSED(mp); - - INSIST(!in_recursive_evloop); - in_recursive_evloop = ISC_TRUE; - - INSIST(*mp == 1); /* Mutex must be locked on entry. */ - --*mp; - - result = evloop(); - if (result == ISC_R_RELOAD) - want_reload = ISC_TRUE; - if (signalled) { - want_shutdown = ISC_FALSE; - signalled = ISC_FALSE; - } - - ++*mp; - in_recursive_evloop = ISC_FALSE; - return (ISC_R_SUCCESS); -} - -isc_result_t -isc__nothread_signal_hack(isc_condition_t *cp) { - - UNUSED(cp); - - INSIST(in_recursive_evloop); - - want_shutdown = ISC_TRUE; - signalled = ISC_TRUE; - return (ISC_R_SUCCESS); -} - -#endif /* ISC_PLATFORM_USETHREADS */ - -isc_result_t -isc_app_run(void) { - int result; - isc_event_t *event, *next_event; - isc_task_t *task; -#ifdef ISC_PLATFORM_USETHREADS - sigset_t sset; - char strbuf[ISC_STRERRORSIZE]; -#endif /* ISC_PLATFORM_USETHREADS */ -#ifdef HAVE_SIGWAIT - int sig; -#endif - -#ifdef HAVE_LINUXTHREADS - REQUIRE(main_thread == pthread_self()); -#endif - - LOCK(&lock); - - if (!running) { - running = ISC_TRUE; - - /* - * Post any on-run events (in FIFO order). - */ - for (event = ISC_LIST_HEAD(on_run); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(on_run, event, ev_link); - task = event->ev_sender; - event->ev_sender = NULL; - isc_task_sendanddetach(&task, &event); - } - - } - - UNLOCK(&lock); - -#ifndef HAVE_SIGWAIT - /* - * Catch SIGHUP. - * - * 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); -#endif - -#ifdef ISC_PLATFORM_USETHREADS - /* - * 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) { -#ifdef HAVE_SIGWAIT - /* - * Wait for SIGHUP, SIGINT, or SIGTERM. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - -#ifndef HAVE_UNIXWARE_SIGWAIT - result = sigwait(&sset, &sig); - if (result == 0) { - if (sig == SIGINT || - sig == SIGTERM) - want_shutdown = ISC_TRUE; - else if (sig == SIGHUP) - want_reload = ISC_TRUE; - } - -#else /* Using UnixWare sigwait semantics. */ - sig = sigwait(&sset); - if (sig >= 0) { - if (sig == SIGINT || - sig == SIGTERM) - want_shutdown = ISC_TRUE; - else if (sig == SIGHUP) - want_reload = ISC_TRUE; - } - -#endif /* HAVE_UNIXWARE_SIGWAIT */ -#else /* Don't have sigwait(). */ - /* - * Listen for all signals. - */ - if (sigemptyset(&sset) != 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", strbuf); - return (ISC_R_UNEXPECTED); - } - result = sigsuspend(&sset); -#endif /* HAVE_SIGWAIT */ - - if (want_reload) { - want_reload = ISC_FALSE; - return (ISC_R_RELOAD); - } - - if (want_shutdown && blocked) - exit(1); - } - -#else /* ISC_PLATFORM_USETHREADS */ - - (void)isc__taskmgr_dispatch(); - - result = evloop(); - if (result != ISC_R_SUCCESS) - return (result); - -#endif /* ISC_PLATFORM_USETHREADS */ - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_shutdown(void) { - isc_boolean_t want_kill = ISC_TRUE; - char strbuf[ISC_STRERRORSIZE]; - - LOCK(&lock); - - REQUIRE(running); - - if (shutdown_requested) - want_kill = ISC_FALSE; - else - shutdown_requested = ISC_TRUE; - - UNLOCK(&lock); - - if (want_kill) { -#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); - } -#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); - } -#endif - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_reload(void) { - isc_boolean_t want_kill = ISC_TRUE; - char strbuf[ISC_STRERRORSIZE]; - - LOCK(&lock); - - REQUIRE(running); - - /* - * Don't send the reload signal if we're shutting down. - */ - if (shutdown_requested) - want_kill = ISC_FALSE; - - UNLOCK(&lock); - - if (want_kill) { -#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); - } -#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); - } -#endif - } - - return (ISC_R_SUCCESS); -} - -void -isc_app_finish(void) { - DESTROYLOCK(&lock); -} - -void -isc_app_block(void) { -#ifdef ISC_PLATFORM_USETHREADS - sigset_t sset; -#endif /* ISC_PLATFORM_USETHREADS */ - REQUIRE(running); - REQUIRE(!blocked); - - blocked = ISC_TRUE; -#ifdef ISC_PLATFORM_USETHREADS - blockedthread = pthread_self(); - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0); -#endif /* ISC_PLATFORM_USETHREADS */ -} - -void -isc_app_unblock(void) { -#ifdef ISC_PLATFORM_USETHREADS - sigset_t sset; -#endif /* ISC_PLATFORM_USETHREADS */ - - REQUIRE(running); - REQUIRE(blocked); - - blocked = ISC_FALSE; - -#ifdef ISC_PLATFORM_USETHREADS - REQUIRE(blockedthread == pthread_self()); - - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); -#endif /* ISC_PLATFORM_USETHREADS */ -} diff --git a/contrib/bind9/lib/isc/unix/dir.c b/contrib/bind9/lib/isc/unix/dir.c deleted file mode 100644 index 85a121739b4c..000000000000 --- a/contrib/bind9/lib/isc/unix/dir.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: dir.c,v 1.18.2.1.2.3 2004/03/08 09:04:55 marka Exp $ */ - -/* Principal Authors: DCL */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <errno.h> -#include <unistd.h> - -#include <isc/dir.h> -#include <isc/magic.h> -#include <isc/string.h> -#include <isc/util.h> - -#include "errno2result.h" - -#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') -#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) - -void -isc_dir_init(isc_dir_t *dir) { - REQUIRE(dir != NULL); - - dir->entry.name[0] = '\0'; - dir->entry.length = 0; - - dir->handle = NULL; - - dir->magic = ISC_DIR_MAGIC; -} - -/* - * Allocate workspace and open directory stream. If either one fails, - * NULL will be returned. - */ -isc_result_t -isc_dir_open(isc_dir_t *dir, const char *dirname) { - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(VALID_DIR(dir)); - REQUIRE(dirname != NULL); - - /* - * Open stream. - */ - dir->handle = opendir(dirname); - - if (dir->handle == NULL) - return isc__errno2result(errno); - - return (result); -} - -/* - * Return previously retrieved file or get next one. Unix's dirent has - * separate open and read functions, but the Win32 and DOS interfaces open - * the dir stream and reads the first file in one operation. - */ -isc_result_t -isc_dir_read(isc_dir_t *dir) { - struct dirent *entry; - - REQUIRE(VALID_DIR(dir) && dir->handle != NULL); - - /* - * Fetch next file in directory. - */ - entry = readdir(dir->handle); - - if (entry == NULL) - return (ISC_R_NOMORE); - - /* - * Make sure that the space for the name is long enough. - */ - if (sizeof(dir->entry.name) <= strlen(entry->d_name)) - return (ISC_R_UNEXPECTED); - - strcpy(dir->entry.name, entry->d_name); - - /* - * Some dirents have d_namlen, but it is not portable. - */ - dir->entry.length = strlen(entry->d_name); - - return (ISC_R_SUCCESS); -} - -/* - * Close directory stream. - */ -void -isc_dir_close(isc_dir_t *dir) { - REQUIRE(VALID_DIR(dir) && dir->handle != NULL); - - (void)closedir(dir->handle); - dir->handle = NULL; -} - -/* - * Reposition directory stream at start. - */ -isc_result_t -isc_dir_reset(isc_dir_t *dir) { - REQUIRE(VALID_DIR(dir) && dir->handle != NULL); - - rewinddir(dir->handle); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_dir_chdir(const char *dirname) { - /* - * Change the current directory to 'dirname'. - */ - - REQUIRE(dirname != NULL); - - if (chdir(dirname) < 0) - return (isc__errno2result(errno)); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_dir_chroot(const char *dirname) { - - REQUIRE(dirname != NULL); - - if (chroot(dirname) < 0) - return (isc__errno2result(errno)); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_dir_createunique(char *templet) { - isc_result_t result; - char *x; - char *p; - int i; - int pid; - - REQUIRE(templet != NULL); - - /* - * mkdtemp is not portable, so this emulates it. - */ - - pid = getpid(); - - /* - * Replace trailing Xs with the process-id, zero-filled. - */ - for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet; - x--, pid /= 10) - *x = pid % 10 + '0'; - - x++; /* Set x to start of ex-Xs. */ - - do { - i = mkdir(templet, 0700); - if (i == 0 || errno != EEXIST) - break; - - /* - * The BSD algorithm. - */ - p = x; - while (*p != '\0') { - if (isdigit(*p & 0xff)) - *p = 'a'; - else if (*p != 'z') - ++*p; - else { - /* - * Reset character and move to next. - */ - *p++ = 'a'; - continue; - } - - break; - } - - if (*p == '\0') { - /* - * Tried all combinations. errno should already - * be EEXIST, but ensure it is anyway for - * isc__errno2result(). - */ - errno = EEXIST; - break; - } - } while (1); - - if (i == -1) - result = isc__errno2result(errno); - else - result = ISC_R_SUCCESS; - - return (result); -} diff --git a/contrib/bind9/lib/isc/unix/entropy.c b/contrib/bind9/lib/isc/unix/entropy.c deleted file mode 100644 index 50506634e4cd..000000000000 --- a/contrib/bind9/lib/isc/unix/entropy.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: entropy.c,v 1.60.2.3.8.11 2005/07/12 05:47:43 marka Exp $ */ - -/* - * This is the system depenedent part of the ISC entropy API. - */ - -#include <config.h> - -#include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */ -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <unistd.h> - -#include <isc/platform.h> -#include <isc/strerror.h> - -#ifdef ISC_PLATFORM_NEEDSYSSELECTH -#include <sys/select.h> -#endif - -#include "errno2result.h" - -/* - * There is only one variable in the entropy data structures that is not - * system independent, but pulling the structure that uses it into this file - * ultimately means pulling several other independent structures here also to - * resolve their interdependencies. Thus only the problem variable's type - * is defined here. - */ -#define FILESOURCE_HANDLE_TYPE int - -typedef struct { - int handle; - enum { - isc_usocketsource_disconnected, - isc_usocketsource_connecting, - isc_usocketsource_connected, - isc_usocketsource_ndesired, - isc_usocketsource_wrote, - isc_usocketsource_reading - } status; - size_t sz_to_recv; -} isc_entropyusocketsource_t; - -#include "../entropy.c" - -static unsigned int -get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) { - isc_entropy_t *ent = source->ent; - unsigned char buf[128]; - int fd = source->sources.file.handle; - ssize_t n, ndesired; - unsigned int added; - - if (source->bad) - return (0); - - desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); - - added = 0; - while (desired > 0) { - ndesired = ISC_MIN(desired, sizeof(buf)); - n = read(fd, buf, ndesired); - if (n < 0) { - if (errno == EAGAIN || errno == EINTR) - goto out; - goto err; - } - if (n == 0) - goto err; - - entropypool_adddata(ent, buf, n, n * 8); - added += n * 8; - desired -= n; - } - goto out; - - err: - (void)close(fd); - source->sources.file.handle = -1; - source->bad = ISC_TRUE; - - out: - return (added); -} - -static unsigned int -get_from_usocketsource(isc_entropysource_t *source, isc_uint32_t desired) { - isc_entropy_t *ent = source->ent; - unsigned char buf[128]; - int fd = source->sources.usocket.handle; - ssize_t n = 0, ndesired; - unsigned int added; - size_t sz_to_recv = source->sources.usocket.sz_to_recv; - - if (source->bad) - return (0); - - desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); - - added = 0; - while (desired > 0) { - ndesired = ISC_MIN(desired, sizeof(buf)); - eagain_loop: - - switch ( source->sources.usocket.status ) { - case isc_usocketsource_ndesired: - buf[0] = ndesired; - if ((n = send(fd, buf, 1, 0)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNRESET) - goto out; - goto err; - } - INSIST(n == 1); - source->sources.usocket.status = - isc_usocketsource_wrote; - goto eagain_loop; - - case isc_usocketsource_connecting: - case isc_usocketsource_connected: - buf[0] = 1; - buf[1] = ndesired; - if ((n = send(fd, buf, 2, 0)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNRESET) - goto out; - goto err; - } - if (n == 1) { - source->sources.usocket.status = - isc_usocketsource_ndesired; - goto eagain_loop; - } - INSIST(n == 2); - source->sources.usocket.status = - isc_usocketsource_wrote; - /*FALLTHROUGH*/ - - case isc_usocketsource_wrote: - if (recv(fd, buf, 1, 0) != 1) { - if (errno == EAGAIN) { - /* - * The problem of EAGAIN (try again - * later) is a major issue on HP-UX. - * Solaris actually tries the recv - * call again, while HP-UX just dies. - * This code is an attempt to let the - * entropy pool fill back up (at least - * that's what I think the problem is.) - * We go to eagain_loop because if we - * just "break", then the "desired" - * amount gets borked. - */ - usleep(1000); - goto eagain_loop; - } - if (errno == EWOULDBLOCK || errno == EINTR) - goto out; - goto err; - } - source->sources.usocket.status = - isc_usocketsource_reading; - sz_to_recv = buf[0]; - source->sources.usocket.sz_to_recv = sz_to_recv; - if (sz_to_recv > sizeof(buf)) - goto err; - /*FALLTHROUGH*/ - - case isc_usocketsource_reading: - if (sz_to_recv != 0U) { - n = recv(fd, buf, sz_to_recv, 0); - if (n < 0) { - if (errno == EWOULDBLOCK || - errno == EINTR) - goto out; - goto err; - } - } else - n = 0; - break; - - default: - goto err; - } - - if ((size_t)n != sz_to_recv) - source->sources.usocket.sz_to_recv -= n; - else - source->sources.usocket.status = - isc_usocketsource_connected; - - if (n == 0) - goto out; - - entropypool_adddata(ent, buf, n, n * 8); - added += n * 8; - desired -= n; - } - goto out; - - err: - close(fd); - source->bad = ISC_TRUE; - source->sources.usocket.status = isc_usocketsource_disconnected; - source->sources.usocket.handle = -1; - - out: - return (added); -} - -/* - * Poll each source, trying to get data from it to stuff into the entropy - * pool. - */ -static void -fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) { - unsigned int added; - unsigned int remaining; - unsigned int needed; - unsigned int nsource; - isc_entropysource_t *source; - - REQUIRE(VALID_ENTROPY(ent)); - - needed = desired; - - /* - * This logic is a little strange, so an explanation is in order. - * - * If needed is 0, it means we are being asked to "fill to whatever - * we think is best." This means that if we have at least a - * partially full pool (say, > 1/4th of the pool) we probably don't - * need to add anything. - * - * Also, we will check to see if the "pseudo" count is too high. - * If it is, try to mix in better data. Too high is currently - * defined as 1/4th of the pool. - * - * Next, if we are asked to add a specific bit of entropy, make - * certain that we will do so. Clamp how much we try to add to - * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy). - * - * Note that if we are in a blocking mode, we will only try to - * get as much data as we need, not as much as we might want - * to build up. - */ - if (needed == 0) { - REQUIRE(!blocking); - - if ((ent->pool.entropy >= RND_POOLBITS / 4) - && (ent->pool.pseudo <= RND_POOLBITS / 4)) - return; - - needed = THRESHOLD_BITS * 4; - } else { - needed = ISC_MAX(needed, THRESHOLD_BITS); - needed = ISC_MIN(needed, RND_POOLBITS); - } - - /* - * In any case, clamp how much we need to how much we can add. - */ - needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy); - - /* - * But wait! If we're not yet initialized, we need at least - * THRESHOLD_BITS - * of randomness. - */ - if (ent->initialized < THRESHOLD_BITS) - needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized); - - /* - * Poll each file source to see if we can read anything useful from - * it. XXXMLG When where are multiple sources, we should keep a - * record of which one we last used so we can start from it (or the - * next one) to avoid letting some sources build up entropy while - * others are always drained. - */ - - added = 0; - remaining = needed; - if (ent->nextsource == NULL) { - ent->nextsource = ISC_LIST_HEAD(ent->sources); - if (ent->nextsource == NULL) - return; - } - source = ent->nextsource; - again_file: - for (nsource = 0; nsource < ent->nsources; nsource++) { - unsigned int got; - - if (remaining == 0) - break; - - got = 0; - - switch ( source->type ) { - case ENTROPY_SOURCETYPE_FILE: - got = get_from_filesource(source, remaining); - break; - - case ENTROPY_SOURCETYPE_USOCKET: - got = get_from_usocketsource(source, remaining); - break; - } - - added += got; - - remaining -= ISC_MIN(remaining, got); - - source = ISC_LIST_NEXT(source, link); - if (source == NULL) - source = ISC_LIST_HEAD(ent->sources); - } - ent->nextsource = source; - - if (blocking && remaining != 0) { - int fds; - - fds = wait_for_sources(ent); - if (fds > 0) - goto again_file; - } - - /* - * Here, if there are bits remaining to be had and we can block, - * check to see if we have a callback source. If so, call them. - */ - source = ISC_LIST_HEAD(ent->sources); - while ((remaining != 0) && (source != NULL)) { - unsigned int got; - - got = 0; - - if (source->type == ENTROPY_SOURCETYPE_CALLBACK) - got = get_from_callback(source, remaining, blocking); - - added += got; - remaining -= ISC_MIN(remaining, got); - - if (added >= needed) - break; - - source = ISC_LIST_NEXT(source, link); - } - - /* - * Mark as initialized if we've added enough data. - */ - if (ent->initialized < THRESHOLD_BITS) - ent->initialized += added; -} - -static int -wait_for_sources(isc_entropy_t *ent) { - isc_entropysource_t *source; - int maxfd, fd; - int cc; - fd_set reads; - fd_set writes; - - maxfd = -1; - FD_ZERO(&reads); - FD_ZERO(&writes); - - source = ISC_LIST_HEAD(ent->sources); - while (source != NULL) { - if (source->type == ENTROPY_SOURCETYPE_FILE) { - fd = source->sources.file.handle; - if (fd >= 0) { - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &reads); - } - } - if (source->type == ENTROPY_SOURCETYPE_USOCKET) { - fd = source->sources.usocket.handle; - if (fd >= 0) { - switch (source->sources.usocket.status) { - case isc_usocketsource_disconnected: - break; - case isc_usocketsource_connecting: - case isc_usocketsource_connected: - case isc_usocketsource_ndesired: - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &writes); - break; - case isc_usocketsource_wrote: - case isc_usocketsource_reading: - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &reads); - break; - } - } - } - source = ISC_LIST_NEXT(source, link); - } - - if (maxfd < 0) - return (-1); - - cc = select(maxfd + 1, &reads, &writes, NULL, NULL); - if (cc < 0) - return (-1); - - return (cc); -} - -static void -destroyfilesource(isc_entropyfilesource_t *source) { - (void)close(source->handle); -} - -static void -destroyusocketsource(isc_entropyusocketsource_t *source) { - close(source->handle); -} - -/* - * Make a fd non-blocking - */ -static isc_result_t -make_nonblock(int fd) { - int ret; - int flags; - char strbuf[ISC_STRERRORSIZE]; -#ifdef USE_FIONBIO_IOCTL - int on = 1; - - ret = ioctl(fd, FIONBIO, (char *)&on); -#else - flags = fcntl(fd, F_GETFL, 0); - flags |= PORT_NONBLOCK; - ret = fcntl(fd, F_SETFL, flags); -#endif - - if (ret == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, -#ifdef USE_FIONBIO_IOCTL - "ioctl(%d, FIONBIO, &on): %s", fd, -#else - "fcntl(%d, F_SETFL, %d): %s", fd, flags, -#endif - strbuf); - - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { - int fd; - struct stat _stat; - isc_boolean_t is_usocket = ISC_FALSE; - isc_boolean_t is_connected = ISC_FALSE; - isc_result_t ret; - isc_entropysource_t *source; - - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(fname != NULL); - - LOCK(&ent->lock); - - source = NULL; - - if (stat(fname, &_stat) < 0) { - ret = isc__errno2result(errno); - goto errout; - } - /* - * Solaris 2.5.1 does not have support for sockets (S_IFSOCK), - * but it does return type S_IFIFO (the OS believes that - * the socket is a fifo). This may be an issue if we tell - * the program to look at an actual FIFO as its source of - * entropy. - */ -#if defined(S_ISSOCK) - if (S_ISSOCK(_stat.st_mode)) - is_usocket = ISC_TRUE; -#endif -#if defined(S_ISFIFO) - if (S_ISFIFO(_stat.st_mode)) - is_usocket = ISC_TRUE; -#endif - if (is_usocket) - fd = socket(PF_UNIX, SOCK_STREAM, 0); - else - fd = open(fname, O_RDONLY | PORT_NONBLOCK, 0); - - if (fd < 0) { - ret = isc__errno2result(errno); - goto errout; - } - - ret = make_nonblock(fd); - if (ret != ISC_R_SUCCESS) - goto closefd; - - if (is_usocket) { - struct sockaddr_un sname; - - memset(&sname, 0, sizeof(sname)); - sname.sun_family = AF_UNIX; - strncpy(sname.sun_path, fname, sizeof(sname.sun_path)); - sname.sun_path[sizeof(sname.sun_path)-1] = '0'; -#ifdef ISC_PLATFORM_HAVESALEN -#if !defined(SUN_LEN) -#define SUN_LEN(su) \ - (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) -#endif - sname.sun_len = SUN_LEN(&sname); -#endif - - if (connect(fd, (struct sockaddr *) &sname, - sizeof(struct sockaddr_un)) < 0) { - if (errno != EINPROGRESS) { - ret = isc__errno2result(errno); - goto closefd; - } - } else - is_connected = ISC_TRUE; - } - - source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); - if (source == NULL) { - ret = ISC_R_NOMEMORY; - goto closefd; - } - - /* - * From here down, no failures can occur. - */ - source->magic = SOURCE_MAGIC; - source->ent = ent; - source->total = 0; - source->bad = ISC_FALSE; - memset(source->name, 0, sizeof(source->name)); - ISC_LINK_INIT(source, link); - if (is_usocket) { - source->sources.usocket.handle = fd; - if (is_connected) - source->sources.usocket.status = - isc_usocketsource_connected; - else - source->sources.usocket.status = - isc_usocketsource_connecting; - source->sources.usocket.sz_to_recv = 0; - source->type = ENTROPY_SOURCETYPE_USOCKET; - } else { - source->sources.file.handle = fd; - source->type = ENTROPY_SOURCETYPE_FILE; - } - - /* - * Hook it into the entropy system. - */ - ISC_LIST_APPEND(ent->sources, source, link); - ent->nsources++; - - UNLOCK(&ent->lock); - return (ISC_R_SUCCESS); - - closefd: - (void)close(fd); - - errout: - if (source != NULL) - isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); - - UNLOCK(&ent->lock); - - return (ret); -} diff --git a/contrib/bind9/lib/isc/unix/errno2result.c b/contrib/bind9/lib/isc/unix/errno2result.c deleted file mode 100644 index 66a4e916d79c..000000000000 --- a/contrib/bind9/lib/isc/unix/errno2result.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: errno2result.c,v 1.8.2.4.8.1 2004/03/06 08:14:59 marka Exp $ */ - -#include <config.h> - -#include <isc/result.h> -#include <isc/strerror.h> -#include <isc/util.h> - -#include "errno2result.h" - -/* - * Convert a POSIX errno value into an isc_result_t. The - * list of supported errno values is not complete; new users - * of this function should add any expected errors that are - * not already there. - */ -isc_result_t -isc__errno2result(int posixerrno) { - char strbuf[ISC_STRERRORSIZE]; - - switch (posixerrno) { - case ENOTDIR: - case ELOOP: - case EINVAL: /* XXX sometimes this is not for files */ - case ENAMETOOLONG: - case EBADF: - return (ISC_R_INVALIDFILE); - case ENOENT: - return (ISC_R_FILENOTFOUND); - case EACCES: - case EPERM: - return (ISC_R_NOPERM); - case EEXIST: - return (ISC_R_FILEEXISTS); - case EIO: - return (ISC_R_IOERROR); - case ENOMEM: - return (ISC_R_NOMEMORY); - case ENFILE: - case EMFILE: - return (ISC_R_TOOMANYOPENFILES); - case EPIPE: -#ifdef ECONNRESET - case ECONNRESET: -#endif -#ifdef ECONNABORTED - case ECONNABORTED: -#endif - return (ISC_R_CONNECTIONRESET); -#ifdef ENOTCONN - case ENOTCONN: - return (ISC_R_NOTCONNECTED); -#endif -#ifdef ETIMEDOUT - case ETIMEDOUT: - return (ISC_R_TIMEDOUT); -#endif -#ifdef ENOBUFS - case ENOBUFS: - return (ISC_R_NORESOURCES); -#endif -#ifdef EAFNOSUPPORT - case EAFNOSUPPORT: - return (ISC_R_FAMILYNOSUPPORT); -#endif -#ifdef ENETDOWN - case ENETDOWN: - return (ISC_R_NETDOWN); -#endif -#ifdef EHOSTDOWN - case EHOSTDOWN: - return (ISC_R_HOSTDOWN); -#endif -#ifdef ENETUNREACH - case ENETUNREACH: - return (ISC_R_NETUNREACH); -#endif -#ifdef EHOSTUNREACH - case EHOSTUNREACH: - return (ISC_R_HOSTUNREACH); -#endif -#ifdef EADDRINUSE - case EADDRINUSE: - return (ISC_R_ADDRINUSE); -#endif - case EADDRNOTAVAIL: - return (ISC_R_ADDRNOTAVAIL); - case ECONNREFUSED: - return (ISC_R_CONNREFUSED); - default: - isc__strerror(posixerrno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unable to convert errno " - "to isc_result: %d: %s", - posixerrno, strbuf); - /* - * XXXDCL would be nice if perhaps this function could - * return the system's error string, so the caller - * might have something more descriptive than "unexpected - * error" to log with. - */ - return (ISC_R_UNEXPECTED); - } -} diff --git a/contrib/bind9/lib/isc/unix/errno2result.h b/contrib/bind9/lib/isc/unix/errno2result.h deleted file mode 100644 index 9a8d07c6d4cf..000000000000 --- a/contrib/bind9/lib/isc/unix/errno2result.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: errno2result.h,v 1.7.206.1 2004/03/06 08:14:59 marka Exp $ */ - -#ifndef UNIX_ERRNO2RESULT_H -#define UNIX_ERRNO2RESULT_H 1 - -/* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */ - -#include <errno.h> /* Provides errno. */ - -#include <isc/lang.h> -#include <isc/types.h> - -ISC_LANG_BEGINDECLS - -isc_result_t -isc__errno2result(int posixerrno); - -ISC_LANG_ENDDECLS - -#endif /* UNIX_ERRNO2RESULT_H */ diff --git a/contrib/bind9/lib/isc/unix/file.c b/contrib/bind9/lib/isc/unix/file.c deleted file mode 100644 index 7ed6272efb73..000000000000 --- a/contrib/bind9/lib/isc/unix/file.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Portions Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $Id: file.c,v 1.38.12.8 2004/03/16 05:50:25 marka Exp $ */ - -#include <config.h> - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdlib.h> -#include <time.h> /* Required for utimes on some platforms. */ -#include <unistd.h> /* Required for mkstemp on NetBSD. */ - - -#include <sys/stat.h> -#include <sys/time.h> - -#include <isc/dir.h> -#include <isc/file.h> -#include <isc/random.h> -#include <isc/string.h> -#include <isc/time.h> -#include <isc/util.h> - -#include "errno2result.h" - -/* - * XXXDCL As the API for accessing file statistics undoubtedly gets expanded, - * it might be good to provide a mechanism that allows for the results - * of a previous stat() to be used again without having to do another stat, - * such as perl's mechanism of using "_" in place of a file name to indicate - * that the results of the last stat should be used. But then you get into - * annoying MP issues. BTW, Win32 has stat(). - */ -static isc_result_t -file_stats(const char *file, struct stat *stats) { - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(file != NULL); - REQUIRE(stats != NULL); - - if (stat(file, stats) != 0) - result = isc__errno2result(errno); - - return (result); -} - -isc_result_t -isc_file_getmodtime(const char *file, isc_time_t *time) { - isc_result_t result; - struct stat stats; - - REQUIRE(file != NULL); - REQUIRE(time != NULL); - - result = file_stats(file, &stats); - - if (result == ISC_R_SUCCESS) - /* - * XXXDCL some operating systems provide nanoseconds, too, - * such as BSD/OS via st_mtimespec. - */ - isc_time_set(time, stats.st_mtime, 0); - - return (result); -} - -isc_result_t -isc_file_settime(const char *file, isc_time_t *time) { - struct timeval times[2]; - - REQUIRE(file != NULL && time != NULL); - - /* - * tv_sec is at least a 32 bit quantity on all platforms we're - * dealing with, but it is signed on most (all?) of them, - * so we need to make sure the high bit isn't set. This unfortunately - * loses when either: - * * tv_sec becomes a signed 64 bit integer but long is 32 bits - * and isc_time_seconds > LONG_MAX, or - * * isc_time_seconds is changed to be > 32 bits but long is 32 bits - * and isc_time_seconds has at least 33 significant bits. - */ - times[0].tv_sec = times[1].tv_sec = (long)isc_time_seconds(time); - - /* - * Here is the real check for the high bit being set. - */ - if ((times[0].tv_sec & - (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0) - return (ISC_R_RANGE); - - /* - * isc_time_nanoseconds guarantees a value that divided by 1000 will - * fit into the minimum possible size tv_usec field. Unfortunately, - * we don't know what that type is so can't cast directly ... but - * we can at least cast to signed so the IRIX compiler shuts up. - */ - times[0].tv_usec = times[1].tv_usec = - (isc_int32_t)(isc_time_nanoseconds(time) / 1000); - - if (utimes(file, times) < 0) - return (isc__errno2result(errno)); - - return (ISC_R_SUCCESS); -} - -#undef TEMPLATE -#define TEMPLATE "tmp-XXXXXXXXXX" /* 14 characters. */ - -isc_result_t -isc_file_mktemplate(const char *path, char *buf, size_t buflen) { - return (isc_file_template(path, TEMPLATE, buf, buflen)); -} - -isc_result_t -isc_file_template(const char *path, const char *templet, char *buf, - size_t buflen) { - char *s; - - REQUIRE(path != NULL); - REQUIRE(templet != NULL); - REQUIRE(buf != NULL); - - s = strrchr(templet, '/'); - if (s != NULL) - templet = s + 1; - - s = strrchr(path, '/'); - - if (s != NULL) { - if ((s - path + 1 + strlen(templet) + 1) > buflen) - return (ISC_R_NOSPACE); - - strncpy(buf, path, s - path + 1); - buf[s - path + 1] = '\0'; - strcat(buf, templet); - } else { - if ((strlen(templet) + 1) > buflen) - return (ISC_R_NOSPACE); - - strcpy(buf, templet); - } - - return (ISC_R_SUCCESS); -} - -static char alphnum[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -isc_result_t -isc_file_renameunique(const char *file, char *templet) { - char *x; - char *cp; - isc_uint32_t which; - - REQUIRE(file != NULL); - REQUIRE(templet != NULL); - - cp = templet; - while (*cp != '\0') - cp++; - if (cp == templet) - return (ISC_R_FAILURE); - - x = cp--; - while (cp >= templet && *cp == 'X') { - isc_random_get(&which); - *cp = alphnum[which % (sizeof(alphnum) - 1)]; - x = cp--; - } - while (link(file, templet) == -1) { - if (errno != EEXIST) - return (isc__errno2result(errno)); - for (cp = x;;) { - char *t; - if (*cp == '\0') - return (ISC_R_FAILURE); - t = strchr(alphnum, *cp); - if (t == NULL || *++t == '\0') - *cp++ = alphnum[0]; - else { - *cp = *t; - break; - } - } - } - (void)unlink(file); - return (ISC_R_SUCCESS); -} - - -isc_result_t -isc_file_openunique(char *templet, 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); - - cp = templet; - while (*cp != '\0') - cp++; - if (cp == templet) - return (ISC_R_FAILURE); - - x = cp--; - while (cp >= templet && *cp == 'X') { - isc_random_get(&which); - *cp = alphnum[which % (sizeof(alphnum) - 1)]; - 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) - return (isc__errno2result(errno)); - for (cp = x;;) { - char *t; - if (*cp == '\0') - return (ISC_R_FAILURE); - t = strchr(alphnum, *cp); - if (t == NULL || *++t == '\0') - *cp++ = alphnum[0]; - else { - *cp = *t; - break; - } - } - } - f = fdopen(fd, "w+"); - if (f == NULL) { - result = isc__errno2result(errno); - (void)remove(templet); - (void)close(fd); - } else - *fp = f; - - return (result); -} - -isc_result_t -isc_file_remove(const char *filename) { - int r; - - REQUIRE(filename != NULL); - - r = unlink(filename); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_result_t -isc_file_rename(const char *oldname, const char *newname) { - int r; - - REQUIRE(oldname != NULL); - REQUIRE(newname != NULL); - - r = rename(oldname, newname); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_boolean_t -isc_file_exists(const char *pathname) { - struct stat stats; - - REQUIRE(pathname != NULL); - - return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS)); -} - -isc_boolean_t -isc_file_isabsolute(const char *filename) { - REQUIRE(filename != NULL); - return (ISC_TF(filename[0] == '/')); -} - -isc_boolean_t -isc_file_iscurrentdir(const char *filename) { - REQUIRE(filename != NULL); - return (ISC_TF(filename[0] == '.' && filename[1] == '\0')); -} - -isc_boolean_t -isc_file_ischdiridempotent(const char *filename) { - REQUIRE(filename != NULL); - if (isc_file_isabsolute(filename)) - return (ISC_TRUE); - if (isc_file_iscurrentdir(filename)) - return (ISC_TRUE); - return (ISC_FALSE); -} - -const char * -isc_file_basename(const char *filename) { - char *s; - - REQUIRE(filename != NULL); - - s = strrchr(filename, '/'); - if (s == NULL) - return (filename); - - return (s + 1); -} - -isc_result_t -isc_file_progname(const char *filename, char *buf, size_t buflen) { - const char *base; - size_t len; - - REQUIRE(filename != NULL); - REQUIRE(buf != NULL); - - base = isc_file_basename(filename); - len = strlen(base) + 1; - - if (len > buflen) - return (ISC_R_NOSPACE); - memcpy(buf, base, len); - - return (ISC_R_SUCCESS); -} - -/* - * Put the absolute name of the current directory into 'dirname', which is - * a buffer of at least 'length' characters. End the string with the - * appropriate path separator, such that the final product could be - * concatenated with a relative pathname to make a valid pathname string. - */ -static isc_result_t -dir_current(char *dirname, size_t length) { - char *cwd; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(dirname != NULL); - REQUIRE(length > 0U); - - cwd = getcwd(dirname, length); - - if (cwd == NULL) { - if (errno == ERANGE) - result = ISC_R_NOSPACE; - else - result = isc__errno2result(errno); - } else { - if (strlen(dirname) + 1 == length) - result = ISC_R_NOSPACE; - else if (dirname[1] != '\0') - strcat(dirname, "/"); - } - - return (result); -} - -isc_result_t -isc_file_absolutepath(const char *filename, char *path, size_t pathlen) { - isc_result_t result; - result = dir_current(path, pathlen); - if (result != ISC_R_SUCCESS) - return (result); - if (strlen(path) + strlen(filename) + 1 > pathlen) - return (ISC_R_NOSPACE); - strcat(path, filename); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_file_truncate(const char *filename, isc_offset_t size) { - isc_result_t result = ISC_R_SUCCESS; - - if (truncate(filename, size) < 0) - result = isc__errno2result(errno); - return (result); -} diff --git a/contrib/bind9/lib/isc/unix/fsaccess.c b/contrib/bind9/lib/isc/unix/fsaccess.c deleted file mode 100644 index 5fa4fb47495a..000000000000 --- a/contrib/bind9/lib/isc/unix/fsaccess.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: fsaccess.c,v 1.6.206.1 2004/03/06 08:14:59 marka Exp $ */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#include "errno2result.h" - -/* - * The OS-independent part of the API is in lib/isc. - */ -#include "../fsaccess.c" - -isc_result_t -isc_fsaccess_set(const char *path, isc_fsaccess_t access) { - struct stat statb; - mode_t mode; - isc_boolean_t is_dir = ISC_FALSE; - isc_fsaccess_t bits; - isc_result_t result; - - if (stat(path, &statb) != 0) - return (isc__errno2result(errno)); - - if ((statb.st_mode & S_IFDIR) != 0) - is_dir = ISC_TRUE; - else if ((statb.st_mode & S_IFREG) == 0) - return (ISC_R_INVALIDFILE); - - result = check_bad_bits(access, is_dir); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Done with checking bad bits. Set mode_t. - */ - mode = 0; - -#define SET_AND_CLEAR1(modebit) \ - if ((access & bits) != 0) { \ - mode |= modebit; \ - access &= ~bits; \ - } -#define SET_AND_CLEAR(user, group, other) \ - SET_AND_CLEAR1(user); \ - bits <<= STEP; \ - SET_AND_CLEAR1(group); \ - bits <<= STEP; \ - SET_AND_CLEAR1(other); - - bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; - - SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); - - bits = ISC_FSACCESS_WRITE | - ISC_FSACCESS_CREATECHILD | - ISC_FSACCESS_DELETECHILD; - - SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); - - bits = ISC_FSACCESS_EXECUTE | - ISC_FSACCESS_ACCESSCHILD; - - SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH); - - INSIST(access == 0); - - if (chmod(path, mode) < 0) - return (isc__errno2result(errno)); - - return (ISC_R_SUCCESS); -} diff --git a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c deleted file mode 100644 index ad6e1e0b0409..000000000000 --- a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: ifiter_getifaddrs.c,v 1.2.68.3 2004/03/06 08:14:59 marka Exp $ */ - -/* - * Obtain the list of network interfaces using the getifaddrs(3) library. - */ - -#include <ifaddrs.h> - -#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G') -#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) - -struct isc_interfaceiter { - unsigned int magic; /* Magic number. */ - isc_mem_t *mctx; - void *buf; /* (unused) */ - unsigned int bufsize; /* (always 0) */ - struct ifaddrs *ifaddrs; /* List of ifaddrs */ - struct ifaddrs *pos; /* Ptr to current ifaddr */ - isc_interface_t current; /* Current interface data. */ - isc_result_t result; /* Last result code. */ -}; - -isc_result_t -isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { - isc_interfaceiter_t *iter; - isc_result_t result; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(mctx != NULL); - REQUIRE(iterp != NULL); - REQUIRE(*iterp == NULL); - - iter = isc_mem_get(mctx, sizeof(*iter)); - if (iter == NULL) - return (ISC_R_NOMEMORY); - - iter->mctx = mctx; - iter->buf = NULL; - iter->bufsize = 0; - iter->ifaddrs = NULL; - - if (getifaddrs(&iter->ifaddrs) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERGETIFADDRS, - ISC_MSG_GETIFADDRS, - "getting interface " - "addresses: getifaddrs: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto failure; - } - - /* - * A newly created iterator has an undefined position - * until isc_interfaceiter_first() is called. - */ - iter->pos = NULL; - iter->result = ISC_R_FAILURE; - - iter->magic = IFITER_MAGIC; - *iterp = iter; - return (ISC_R_SUCCESS); - - failure: - if (iter->ifaddrs != NULL) /* just in case */ - freeifaddrs(iter->ifaddrs); - isc_mem_put(mctx, iter, sizeof(*iter)); - return (result); -} - -/* - * Get information about the current interface to iter->current. - * If successful, return ISC_R_SUCCESS. - * If the interface has an unsupported address family, - * return ISC_R_IGNORE. - */ - -static isc_result_t -internal_current(isc_interfaceiter_t *iter) { - struct ifaddrs *ifa; - int family; - unsigned int namelen; - - REQUIRE(VALID_IFITER(iter)); - - ifa = iter->pos; - - INSIST(ifa != NULL); - INSIST(ifa->ifa_name != NULL); - INSIST(ifa->ifa_addr != NULL); - - family = ifa->ifa_addr->sa_family; - if (family != AF_INET && family != AF_INET6) - return (ISC_R_IGNORE); - - memset(&iter->current, 0, sizeof(iter->current)); - - namelen = strlen(ifa->ifa_name); - if (namelen > sizeof(iter->current.name) - 1) - namelen = sizeof(iter->current.name) - 1; - - memset(iter->current.name, 0, sizeof(iter->current.name)); - memcpy(iter->current.name, ifa->ifa_name, namelen); - - iter->current.flags = 0; - - if ((ifa->ifa_flags & IFF_UP) != 0) - iter->current.flags |= INTERFACE_F_UP; - - if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0) - iter->current.flags |= INTERFACE_F_POINTTOPOINT; - - if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) - iter->current.flags |= INTERFACE_F_LOOPBACK; - - iter->current.af = family; - - get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name); - - if (ifa->ifa_netmask != NULL) - get_addr(family, &iter->current.netmask, ifa->ifa_netmask, - ifa->ifa_name); - - if (ifa->ifa_dstaddr != NULL && - (iter->current.flags & IFF_POINTOPOINT) != 0) - get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr, - ifa->ifa_name); - - return (ISC_R_SUCCESS); -} - -/* - * Step the iterator to the next interface. Unlike - * isc_interfaceiter_next(), this may leave the iterator - * positioned on an interface that will ultimately - * be ignored. Return ISC_R_NOMORE if there are no more - * interfaces, otherwise ISC_R_SUCCESS. - */ -static isc_result_t -internal_next(isc_interfaceiter_t *iter) { - iter->pos = iter->pos->ifa_next; - - if (iter->pos == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -static void -internal_destroy(isc_interfaceiter_t *iter) { - if (iter->ifaddrs) - freeifaddrs(iter->ifaddrs); - iter->ifaddrs = NULL; -} - -static -void internal_first(isc_interfaceiter_t *iter) { - iter->pos = iter->ifaddrs; -} diff --git a/contrib/bind9/lib/isc/unix/ifiter_ioctl.c b/contrib/bind9/lib/isc/unix/ifiter_ioctl.c deleted file mode 100644 index 0b01b96f942c..000000000000 --- a/contrib/bind9/lib/isc/unix/ifiter_ioctl.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: ifiter_ioctl.c,v 1.19.2.5.2.17 2005/10/14 02:13:07 marka Exp $ */ - -/* - * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl. - * See netintro(4). - */ - -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) -#ifdef ISC_PLATFORM_HAVEIF_LADDRCONF -#define lifc_len iflc_len -#define lifc_buf iflc_buf -#define lifc_req iflc_req -#define LIFCONF if_laddrconf -#else -#define ISC_HAVE_LIFC_FAMILY 1 -#define ISC_HAVE_LIFC_FLAGS 1 -#define LIFCONF lifconf -#endif - -#ifdef ISC_PLATFORM_HAVEIF_LADDRREQ -#define lifr_addr iflr_addr -#define lifr_name iflr_name -#define lifr_dstaddr iflr_dstaddr -#define lifr_flags iflr_flags -#define ss_family sa_family -#define LIFREQ if_laddrreq -#else -#define LIFREQ lifreq -#endif -#endif - -#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'T') -#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) - -#define ISC_IF_INET6_SZ \ - sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n") - -struct isc_interfaceiter { - unsigned int magic; /* Magic number. */ - isc_mem_t *mctx; - int mode; - int socket; - struct ifconf ifc; - void *buf; /* Buffer for sysctl data. */ - unsigned int bufsize; /* Bytes allocated. */ - unsigned int pos; /* Current offset in - SIOCGIFCONF data */ -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - int socket6; - struct LIFCONF lifc; - void *buf6; /* Buffer for sysctl data. */ - unsigned int bufsize6; /* Bytes allocated. */ - unsigned int pos6; /* Current offset in - SIOCGLIFCONF data */ - isc_result_t result6; /* Last result code. */ - isc_boolean_t first6; -#endif -#ifdef HAVE_TRUCLUSTER - int clua_context; /* Cluster alias context */ - isc_boolean_t clua_done; - struct sockaddr clua_sa; -#endif -#ifdef __linux - FILE * proc; - char entry[ISC_IF_INET6_SZ]; - isc_result_t valid; - isc_boolean_t first; -#endif - isc_interface_t current; /* Current interface data. */ - isc_result_t result; /* Last result code. */ -}; - -#ifdef HAVE_TRUCLUSTER -#include <clua/clua.h> -#include <sys/socket.h> -#endif - - -/* - * Size of buffer for SIOCGLIFCONF, in bytes. We assume no sane system - * will have more than a megabyte of interface configuration data. - */ -#define IFCONF_BUFSIZE_INITIAL 4096 -#define IFCONF_BUFSIZE_MAX 1048576 - -#ifdef __linux -#ifndef IF_NAMESIZE -# ifdef IFNAMSIZ -# define IF_NAMESIZE IFNAMSIZ -# else -# define IF_NAMESIZE 16 -# endif -#endif -#endif - -static isc_result_t -getbuf4(isc_interfaceiter_t *iter) { - char strbuf[ISC_STRERRORSIZE]; - - iter->bufsize = IFCONF_BUFSIZE_INITIAL; - - for (;;) { - iter->buf = isc_mem_get(iter->mctx, iter->bufsize); - if (iter->buf == NULL) - return (ISC_R_NOMEMORY); - - memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len)); - iter->ifc.ifc_len = iter->bufsize; - iter->ifc.ifc_buf = iter->buf; - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion". It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc) - == -1) { - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETIFCONFIG, - "get interface " - "configuration: %s"), - strbuf); - goto unexpected; - } - /* - * EINVAL. Retry with a bigger buffer. - */ - } else { - /* - * The ioctl succeeded. - * Some OS's just return what will fit rather - * than set EINVAL if the buffer is too small - * to fit all the interfaces in. If - * ifc.lifc_len is too near to the end of the - * buffer we will grow it just in case and - * retry. - */ - if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq) - < iter->bufsize) - break; - } - if (iter->bufsize >= IFCONF_BUFSIZE_MAX) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_BUFFERMAX, - "get interface " - "configuration: " - "maximum buffer " - "size exceeded")); - goto unexpected; - } - isc_mem_put(iter->mctx, iter->buf, iter->bufsize); - - iter->bufsize *= 2; - } - return (ISC_R_SUCCESS); - - unexpected: - isc_mem_put(iter->mctx, iter->buf, iter->bufsize); - iter->buf = NULL; - return (ISC_R_UNEXPECTED); -} - -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) -static isc_result_t -getbuf6(isc_interfaceiter_t *iter) { - char strbuf[ISC_STRERRORSIZE]; - isc_result_t result; - - iter->bufsize6 = IFCONF_BUFSIZE_INITIAL; - - for (;;) { - iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6); - if (iter->buf6 == NULL) - return (ISC_R_NOMEMORY); - - memset(&iter->lifc, 0, sizeof(iter->lifc)); -#ifdef ISC_HAVE_LIFC_FAMILY - iter->lifc.lifc_family = AF_INET6; -#endif -#ifdef ISC_HAVE_LIFC_FLAGS - iter->lifc.lifc_flags = 0; -#endif - iter->lifc.lifc_len = iter->bufsize6; - iter->lifc.lifc_buf = iter->buf6; - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion". It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc) - == -1) { -#ifdef __hpux - /* - * IPv6 interface scanning is not available on all - * kernels w/ IPv6 sockets. - */ - if (errno == ENOENT) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_INTERFACE, - ISC_LOG_DEBUG(1), - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETIFCONFIG, - "get interface " - "configuration: %s"), - strbuf); - result = ISC_R_FAILURE; - goto cleanup; - } -#endif - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETIFCONFIG, - "get interface " - "configuration: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - /* - * EINVAL. Retry with a bigger buffer. - */ - } else { - /* - * The ioctl succeeded. - * Some OS's just return what will fit rather - * than set EINVAL if the buffer is too small - * to fit all the interfaces in. If - * ifc.ifc_len is too near to the end of the - * buffer we will grow it just in case and - * retry. - */ - if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ) - < iter->bufsize6) - break; - } - if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_BUFFERMAX, - "get interface " - "configuration: " - "maximum buffer " - "size exceeded")); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); - - iter->bufsize6 *= 2; - } - - if (iter->lifc.lifc_len != 0) - iter->mode = 6; - return (ISC_R_SUCCESS); - - cleanup: - isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); - iter->buf6 = NULL; - return (result); -} -#endif - -isc_result_t -isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { - isc_interfaceiter_t *iter; - isc_result_t result; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(mctx != NULL); - REQUIRE(iterp != NULL); - REQUIRE(*iterp == NULL); - - iter = isc_mem_get(mctx, sizeof(*iter)); - if (iter == NULL) - return (ISC_R_NOMEMORY); - - iter->mctx = mctx; - iter->mode = 4; - iter->buf = NULL; - iter->pos = (unsigned int) -1; -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - iter->buf6 = NULL; - iter->pos6 = (unsigned int) -1; - iter->result6 = ISC_R_NOMORE; - iter->socket6 = -1; - iter->first6 = ISC_FALSE; -#endif - - /* - * Get the interface configuration, allocating more memory if - * necessary. - */ - -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - result = isc_net_probeipv6(); - if (result == ISC_R_SUCCESS) { - /* - * Create an unbound datagram socket to do the SIOCGLIFCONF - * ioctl on. HP/UX requires an AF_INET6 socket for - * SIOCGLIFCONF to get IPv6 addresses. - */ - if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_MAKESCANSOCKET, - "making interface " - "scan socket: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto socket6_failure; - } - result = iter->result6 = getbuf6(iter); - if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS) - goto ioctl6_failure; - } -#endif - if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_MAKESCANSOCKET, - "making interface " - "scan socket: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto socket_failure; - } - result = getbuf4(iter); - if (result != ISC_R_SUCCESS) - goto ioctl_failure; - - /* - * A newly created iterator has an undefined position - * until isc_interfaceiter_first() is called. - */ -#ifdef HAVE_TRUCLUSTER - iter->clua_context = -1; - iter->clua_done = ISC_TRUE; -#endif -#ifdef __linux - iter->proc = fopen("/proc/net/if_inet6", "r"); - iter->valid = ISC_R_FAILURE; - iter->first = ISC_FALSE; -#endif - iter->result = ISC_R_FAILURE; - - iter->magic = IFITER_MAGIC; - *iterp = iter; - return (ISC_R_SUCCESS); - - ioctl_failure: - if (iter->buf != NULL) - isc_mem_put(mctx, iter->buf, iter->bufsize); - (void) close(iter->socket); - - socket_failure: -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - if (iter->buf6 != NULL) - isc_mem_put(mctx, iter->buf6, iter->bufsize6); - ioctl6_failure: - if (iter->socket6 != -1) - (void) close(iter->socket6); - socket6_failure: -#endif - - isc_mem_put(mctx, iter, sizeof(*iter)); - return (result); -} - -#ifdef HAVE_TRUCLUSTER -static void -get_inaddr(isc_netaddr_t *dst, struct in_addr *src) { - dst->family = AF_INET; - memcpy(&dst->type.in, src, sizeof(struct in_addr)); -} - -static isc_result_t -internal_current_clusteralias(isc_interfaceiter_t *iter) { - struct clua_info ci; - if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS) - return (ISC_R_IGNORE); - memset(&iter->current, 0, sizeof(iter->current)); - iter->current.af = iter->clua_sa.sa_family; - memset(iter->current.name, 0, sizeof(iter->current.name)); - sprintf(iter->current.name, "clua%d", ci.aliasid); - iter->current.flags = INTERFACE_F_UP; - get_inaddr(&iter->current.address, &ci.addr); - get_inaddr(&iter->current.netmask, &ci.netmask); - return (ISC_R_SUCCESS); -} -#endif - -#ifdef __linux -static isc_result_t -linux_if_inet6_next(isc_interfaceiter_t *iter) { - if (iter->proc != NULL && - fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL) - iter->valid = ISC_R_SUCCESS; - else - iter->valid = ISC_R_NOMORE; - return (iter->valid); -} - -static void -linux_if_inet6_first(isc_interfaceiter_t *iter) { - if (iter->proc != NULL) { - rewind(iter->proc); - (void)linux_if_inet6_next(iter); - } else - iter->valid = ISC_R_NOMORE; - iter->first = ISC_FALSE; -} - -static isc_result_t -linux_if_inet6_current(isc_interfaceiter_t *iter) { - char address[33]; - char name[IF_NAMESIZE+1]; - struct in6_addr addr6; - int ifindex, prefix, flag3, flag4; - int res; - unsigned int i; - - if (iter->valid != ISC_R_SUCCESS) - return (iter->valid); - if (iter->proc == NULL) { - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, - "/proc/net/if_inet6:iter->proc == NULL"); - return (ISC_R_FAILURE); - } - - res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n", - address, &ifindex, &prefix, &flag3, &flag4, name); - if (res != 6) { - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, - "/proc/net/if_inet6:sscanf() -> %d (expected 6)", - res); - return (ISC_R_FAILURE); - } - if (strlen(address) != 32) { - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, - "/proc/net/if_inet6:strlen(%s) != 32", address); - return (ISC_R_FAILURE); - } - for (i = 0; i < 16; i++) { - unsigned char byte; - static const char hex[] = "0123456789abcdef"; - byte = ((index(hex, address[i * 2]) - hex) << 4) | - (index(hex, address[i * 2 + 1]) - hex); - addr6.s6_addr[i] = byte; - } - iter->current.af = AF_INET6; - iter->current.flags = INTERFACE_F_UP; - isc_netaddr_fromin6(&iter->current.address, &addr6); - if (isc_netaddr_islinklocal(&iter->current.address)) { - isc_netaddr_setzone(&iter->current.address, - (isc_uint32_t)ifindex); - } - for (i = 0; i < 16; i++) { - if (prefix > 8) { - addr6.s6_addr[i] = 0xff; - prefix -= 8; - } else { - addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff; - prefix = 0; - } - } - isc_netaddr_fromin6(&iter->current.netmask, &addr6); - strncpy(iter->current.name, name, sizeof(iter->current.name)); - return (ISC_R_SUCCESS); -} -#endif - -/* - * Get information about the current interface to iter->current. - * If successful, return ISC_R_SUCCESS. - * If the interface has an unsupported address family, or if - * some operation on it fails, return ISC_R_IGNORE to make - * the higher-level iterator code ignore it. - */ - -static isc_result_t -internal_current4(isc_interfaceiter_t *iter) { - struct ifreq *ifrp; - struct ifreq ifreq; - int family; - char strbuf[ISC_STRERRORSIZE]; -#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR) - struct lifreq lifreq; -#else - char sabuf[256]; -#endif - int i, bits, prefixlen; -#ifdef __linux - isc_result_t result; -#endif - - REQUIRE(VALID_IFITER(iter)); - REQUIRE (iter->pos < (unsigned int) iter->ifc.ifc_len); - -#ifdef __linux - result = linux_if_inet6_current(iter); - if (result != ISC_R_NOMORE) - return (result); - iter->first = ISC_TRUE; -#endif - - ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); - - memset(&ifreq, 0, sizeof(ifreq)); - memcpy(&ifreq, ifrp, sizeof(ifreq)); - - family = ifreq.ifr_addr.sa_family; -#if defined(ISC_PLATFORM_HAVEIPV6) - if (family != AF_INET && family != AF_INET6) -#else - if (family != AF_INET) -#endif - return (ISC_R_IGNORE); - - memset(&iter->current, 0, sizeof(iter->current)); - iter->current.af = family; - - INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name)); - memset(iter->current.name, 0, sizeof(iter->current.name)); - memcpy(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name)); - - get_addr(family, &iter->current.address, - (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name); - - /* - * If the interface does not have a address ignore it. - */ - switch (family) { - case AF_INET: - if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY)) - return (ISC_R_IGNORE); - break; - case AF_INET6: - if (memcmp(&iter->current.address.type.in6, &in6addr_any, - sizeof(in6addr_any)) == 0) - return (ISC_R_IGNORE); - break; - } - - /* - * Get interface flags. - */ - - iter->current.flags = 0; - - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: getting interface flags: %s", - ifreq.ifr_name, strbuf); - return (ISC_R_IGNORE); - } - - if ((ifreq.ifr_flags & IFF_UP) != 0) - iter->current.flags |= INTERFACE_F_UP; - -#ifdef IFF_POINTOPOINT - if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0) - iter->current.flags |= INTERFACE_F_POINTTOPOINT; -#endif - - if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0) - iter->current.flags |= INTERFACE_F_LOOPBACK; - - if (family == AF_INET) - goto inet; - -#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR) - memset(&lifreq, 0, sizeof(lifreq)); - memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name)); - memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6, - sizeof(iter->current.address.type.in6)); - - if (ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: getting interface address: %s", - ifreq.ifr_name, strbuf); - return (ISC_R_IGNORE); - } - prefixlen = lifreq.lifr_addrlen; -#else - isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf)); - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_INTERFACE, - ISC_LOG_INFO, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETIFCONFIG, - "prefix length for %s is unknown " - "(assume 128)"), sabuf); - prefixlen = 128; -#endif - - /* - * Netmask already zeroed. - */ - iter->current.netmask.family = family; - for (i = 0; i < 16; i++) { - if (prefixlen > 8) { - bits = 0; - prefixlen -= 8; - } else { - bits = 8 - prefixlen; - prefixlen = 0; - } - iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff; - } - return (ISC_R_SUCCESS); - - inet: - if (family != AF_INET) - return (ISC_R_IGNORE); -#ifdef IFF_POINTOPOINT - /* - * If the interface is point-to-point, get the destination address. - */ - if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq) - < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETDESTADDR, - "%s: getting " - "destination address: %s"), - ifreq.ifr_name, strbuf); - return (ISC_R_IGNORE); - } - get_addr(family, &iter->current.dstaddress, - (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name); - } -#endif - - /* - * Get the network mask. - */ - memset(&ifreq, 0, sizeof(ifreq)); - memcpy(&ifreq, ifrp, sizeof(ifreq)); - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETNETMASK, - "%s: getting netmask: %s"), - ifreq.ifr_name, strbuf); - return (ISC_R_IGNORE); - } - get_addr(family, &iter->current.netmask, - (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name); - return (ISC_R_SUCCESS); -} - -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) -static isc_result_t -internal_current6(isc_interfaceiter_t *iter) { - struct LIFREQ *ifrp; - struct LIFREQ lifreq; - int family; - char strbuf[ISC_STRERRORSIZE]; - int fd; - - REQUIRE(VALID_IFITER(iter)); - if (iter->result6 != ISC_R_SUCCESS) - return (iter->result6); - REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len); - - ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); - - memset(&lifreq, 0, sizeof(lifreq)); - memcpy(&lifreq, ifrp, sizeof(lifreq)); - - family = lifreq.lifr_addr.ss_family; -#ifdef ISC_PLATFORM_HAVEIPV6 - if (family != AF_INET && family != AF_INET6) -#else - if (family != AF_INET) -#endif - return (ISC_R_IGNORE); - - memset(&iter->current, 0, sizeof(iter->current)); - iter->current.af = family; - - INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name)); - memset(iter->current.name, 0, sizeof(iter->current.name)); - memcpy(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name)); - - get_addr(family, &iter->current.address, - (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name); - - /* - * If the interface does not have a address ignore it. - */ - switch (family) { - case AF_INET: - if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY)) - return (ISC_R_IGNORE); - break; - case AF_INET6: - if (memcmp(&iter->current.address.type.in6, &in6addr_any, - sizeof(in6addr_any)) == 0) - return (ISC_R_IGNORE); - break; - } - - /* - * Get interface flags. - */ - - iter->current.flags = 0; - - if (family == AF_INET6) - fd = iter->socket6; - else - fd = iter->socket; - - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: getting interface flags: %s", - lifreq.lifr_name, strbuf); - return (ISC_R_IGNORE); - } - - if ((lifreq.lifr_flags & IFF_UP) != 0) - iter->current.flags |= INTERFACE_F_UP; - -#ifdef IFF_POINTOPOINT - if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0) - iter->current.flags |= INTERFACE_F_POINTTOPOINT; -#endif - - if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0) - iter->current.flags |= INTERFACE_F_LOOPBACK; - -#ifdef IFF_POINTOPOINT - /* - * If the interface is point-to-point, get the destination address. - */ - if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq) - < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETDESTADDR, - "%s: getting " - "destination address: %s"), - lifreq.lifr_name, strbuf); - return (ISC_R_IGNORE); - } - get_addr(family, &iter->current.dstaddress, - (struct sockaddr *)&lifreq.lifr_dstaddr, - lifreq.lifr_name); - } -#endif - - /* - * Get the network mask. Netmask already zeroed. - */ - memset(&lifreq, 0, sizeof(lifreq)); - memcpy(&lifreq, ifrp, sizeof(lifreq)); - -#ifdef lifr_addrlen - /* - * Special case: if the system provides lifr_addrlen member, the - * netmask of an IPv6 address can be derived from the length, since - * an IPv6 address always has a contiguous mask. - */ - if (family == AF_INET6) { - int i, bits; - - iter->current.netmask.family = family; - for (i = 0; i < lifreq.lifr_addrlen; i += 8) { - bits = lifreq.lifr_addrlen - i; - bits = (bits < 8) ? (8 - bits) : 0; - iter->current.netmask.type.in6.s6_addr[i / 8] = - (~0 << bits) & 0xff; - } - - return (ISC_R_SUCCESS); - } -#endif - - /* - * Ignore the HP/UX warning about "interger overflow during - * conversion. It comes from its own macro definition, - * and is really hard to shut up. - */ - if (ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERIOCTL, - ISC_MSG_GETNETMASK, - "%s: getting netmask: %s"), - lifreq.lifr_name, strbuf); - return (ISC_R_IGNORE); - } - get_addr(family, &iter->current.netmask, - (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name); - - return (ISC_R_SUCCESS); -} -#endif - -static isc_result_t -internal_current(isc_interfaceiter_t *iter) { -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - if (iter->mode == 6) { - iter->result6 = internal_current6(iter); - if (iter->result6 != ISC_R_NOMORE) - return (iter->result6); - } -#endif -#ifdef HAVE_TRUCLUSTER - if (!iter->clua_done) - return(internal_current_clusteralias(iter)); -#endif - return (internal_current4(iter)); -} - -/* - * Step the iterator to the next interface. Unlike - * isc_interfaceiter_next(), this may leave the iterator - * positioned on an interface that will ultimately - * be ignored. Return ISC_R_NOMORE if there are no more - * interfaces, otherwise ISC_R_SUCCESS. - */ -static isc_result_t -internal_next4(isc_interfaceiter_t *iter) { -#ifdef ISC_PLATFORM_HAVESALEN - struct ifreq *ifrp; -#endif - - REQUIRE (iter->pos < (unsigned int) iter->ifc.ifc_len); - -#ifdef __linux - if (linux_if_inet6_next(iter) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - if (!iter->first) - return (ISC_R_SUCCESS); -#endif -#ifdef ISC_PLATFORM_HAVESALEN - ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); - - if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr)) - iter->pos += sizeof(ifrp->ifr_name) + ifrp->ifr_addr.sa_len; - else -#endif - iter->pos += sizeof(struct ifreq); - - if (iter->pos >= (unsigned int) iter->ifc.ifc_len) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) -static isc_result_t -internal_next6(isc_interfaceiter_t *iter) { -#ifdef ISC_PLATFORM_HAVESALEN - struct LIFREQ *ifrp; -#endif - - if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE) - return (iter->result6); - - REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len); - -#ifdef ISC_PLATFORM_HAVESALEN - ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); - - if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr)) - iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len; - else -#endif - iter->pos6 += sizeof(struct LIFREQ); - - if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} -#endif - -static isc_result_t -internal_next(isc_interfaceiter_t *iter) { -#ifdef HAVE_TRUCLUSTER - int clua_result; -#endif -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - if (iter->mode == 6) { - iter->result6 = internal_next6(iter); - if (iter->result6 != ISC_R_NOMORE) - return (iter->result6); - if (iter->first6) { - iter->first6 = ISC_FALSE; - return (ISC_R_SUCCESS); - } - } -#endif -#ifdef HAVE_TRUCLUSTER - if (!iter->clua_done) { - clua_result = clua_getaliasaddress(&iter->clua_sa, - &iter->clua_context); - if (clua_result != CLUA_SUCCESS) - iter->clua_done = ISC_TRUE; - return (ISC_R_SUCCESS); - } -#endif - return (internal_next4(iter)); -} - -static void -internal_destroy(isc_interfaceiter_t *iter) { - (void) close(iter->socket); -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - if (iter->socket6 != -1) - (void) close(iter->socket6); - if (iter->buf6 != NULL) { - isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); - } -#endif -#ifdef __linux - if (iter->proc != NULL) - fclose(iter->proc); -#endif -} - -static -void internal_first(isc_interfaceiter_t *iter) { -#ifdef HAVE_TRUCLUSTER - int clua_result; -#endif - iter->pos = 0; -#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) - iter->pos6 = 0; - if (iter->result6 == ISC_R_NOMORE) - iter->result6 = ISC_R_SUCCESS; - iter->first6 = ISC_TRUE; -#endif -#ifdef HAVE_TRUCLUSTER - iter->clua_context = 0; - clua_result = clua_getaliasaddress(&iter->clua_sa, - &iter->clua_context); - iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS); -#endif -#ifdef __linux - linux_if_inet6_first(iter); -#endif -} diff --git a/contrib/bind9/lib/isc/unix/ifiter_sysctl.c b/contrib/bind9/lib/isc/unix/ifiter_sysctl.c deleted file mode 100644 index b10a2d2090f0..000000000000 --- a/contrib/bind9/lib/isc/unix/ifiter_sysctl.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: ifiter_sysctl.c,v 1.14.12.9 2005/03/17 03:58:33 marka Exp $ */ - -/* - * Obtain the list of network interfaces using sysctl. - * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14, - * and 19.16. - */ - -#include <sys/param.h> -#include <sys/sysctl.h> - -#include <net/route.h> -#include <net/if_dl.h> - -/* XXX what about Alpha? */ -#ifdef sgi -#define ROUNDUP(a) ((a) > 0 ? \ - (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) : \ - sizeof(__uint64_t)) -#else -#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ - : sizeof(long)) -#endif - -#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'S') -#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) - -struct isc_interfaceiter { - unsigned int magic; /* Magic number. */ - isc_mem_t *mctx; - void *buf; /* Buffer for sysctl data. */ - unsigned int bufsize; /* Bytes allocated. */ - unsigned int bufused; /* Bytes used. */ - unsigned int pos; /* Current offset in - sysctl data. */ - isc_interface_t current; /* Current interface data. */ - isc_result_t result; /* Last result code. */ -}; - -static int mib[6] = { - CTL_NET, - PF_ROUTE, - 0, - 0, /* Any address family. */ - NET_RT_IFLIST, - 0 /* Flags. */ -}; - -isc_result_t -isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { - isc_interfaceiter_t *iter; - isc_result_t result; - size_t bufsize; - size_t bufused; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(mctx != NULL); - REQUIRE(iterp != NULL); - REQUIRE(*iterp == NULL); - - iter = isc_mem_get(mctx, sizeof(*iter)); - if (iter == NULL) - return (ISC_R_NOMEMORY); - - iter->mctx = mctx; - iter->buf = 0; - - /* - * Determine the amount of memory needed. - */ - bufsize = 0; - if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERSYSCTL, - ISC_MSG_GETIFLISTSIZE, - "getting interface " - "list size: sysctl: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto failure; - } - iter->bufsize = bufsize; - - iter->buf = isc_mem_get(iter->mctx, iter->bufsize); - if (iter->buf == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - - bufused = bufsize; - if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_IFITERSYSCTL, - ISC_MSG_GETIFLIST, - "getting interface list: " - "sysctl: %s"), - strbuf); - result = ISC_R_UNEXPECTED; - goto failure; - } - iter->bufused = bufused; - INSIST(iter->bufused <= iter->bufsize); - - /* - * A newly created iterator has an undefined position - * until isc_interfaceiter_first() is called. - */ - iter->pos = (unsigned int) -1; - iter->result = ISC_R_FAILURE; - - iter->magic = IFITER_MAGIC; - *iterp = iter; - return (ISC_R_SUCCESS); - - failure: - if (iter->buf != NULL) - isc_mem_put(mctx, iter->buf, iter->bufsize); - isc_mem_put(mctx, iter, sizeof(*iter)); - return (result); -} - -/* - * Get information about the current interface to iter->current. - * If successful, return ISC_R_SUCCESS. - * If the interface has an unsupported address family, - * return ISC_R_IGNORE. In case of other failure, - * return ISC_R_UNEXPECTED. - */ - -static isc_result_t -internal_current(isc_interfaceiter_t *iter) { - struct ifa_msghdr *ifam, *ifam_end; - - REQUIRE(VALID_IFITER(iter)); - REQUIRE (iter->pos < (unsigned int) iter->bufused); - - ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos); - ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused); - - if (ifam->ifam_type == RTM_IFINFO) { - struct if_msghdr *ifm = (struct if_msghdr *) ifam; - struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1); - unsigned int namelen; - - memset(&iter->current, 0, sizeof(iter->current)); - - namelen = sdl->sdl_nlen; - if (namelen > sizeof(iter->current.name) - 1) - namelen = sizeof(iter->current.name) - 1; - - memset(iter->current.name, 0, sizeof(iter->current.name)); - memcpy(iter->current.name, sdl->sdl_data, namelen); - - iter->current.flags = 0; - - if ((ifam->ifam_flags & IFF_UP) != 0) - iter->current.flags |= INTERFACE_F_UP; - - if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0) - iter->current.flags |= INTERFACE_F_POINTTOPOINT; - - if ((ifam->ifam_flags & IFF_LOOPBACK) != 0) - iter->current.flags |= INTERFACE_F_LOOPBACK; - - /* - * This is not an interface address. - * Force another iteration. - */ - return (ISC_R_IGNORE); - } else if (ifam->ifam_type == RTM_NEWADDR) { - int i; - int family; - struct sockaddr *mask_sa = NULL; - struct sockaddr *addr_sa = NULL; - struct sockaddr *dst_sa = NULL; - - struct sockaddr *sa = (struct sockaddr *)(ifam + 1); - family = sa->sa_family; - - for (i = 0; i < RTAX_MAX; i++) - { - if ((ifam->ifam_addrs & (1 << i)) == 0) - continue; - - INSIST(sa < (struct sockaddr *) ifam_end); - - switch (i) { - case RTAX_NETMASK: /* Netmask */ - mask_sa = sa; - break; - case RTAX_IFA: /* Interface address */ - addr_sa = sa; - break; - case RTAX_BRD: /* Broadcast or destination address */ - dst_sa = sa; - break; - } -#ifdef ISC_PLATFORM_HAVESALEN - sa = (struct sockaddr *)((char*)(sa) - + ROUNDUP(sa->sa_len)); -#else -#ifdef sgi - /* - * Do as the contributed SGI code does. - */ - sa = (struct sockaddr *)((char*)(sa) - + ROUNDUP(_FAKE_SA_LEN_DST(sa))); -#else - /* XXX untested. */ - sa = (struct sockaddr *)((char*)(sa) - + ROUNDUP(sizeof(struct sockaddr))); -#endif -#endif - } - - if (addr_sa == NULL) - return (ISC_R_IGNORE); - - family = addr_sa->sa_family; - if (family != AF_INET && family != AF_INET6) - return (ISC_R_IGNORE); - - iter->current.af = family; - - get_addr(family, &iter->current.address, addr_sa, - iter->current.name); - - if (mask_sa != NULL) - get_addr(family, &iter->current.netmask, mask_sa, - iter->current.name); - - if (dst_sa != NULL && - (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) - get_addr(family, &iter->current.dstaddress, dst_sa, - iter->current.name); - - return (ISC_R_SUCCESS); - } else { - printf(isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, - ISC_MSG_UNEXPECTEDTYPE, - "warning: unexpected interface list " - "message type\n")); - return (ISC_R_IGNORE); - } -} - -/* - * Step the iterator to the next interface. Unlike - * isc_interfaceiter_next(), this may leave the iterator - * positioned on an interface that will ultimately - * be ignored. Return ISC_R_NOMORE if there are no more - * interfaces, otherwise ISC_R_SUCCESS. - */ -static isc_result_t -internal_next(isc_interfaceiter_t *iter) { - struct ifa_msghdr *ifam; - REQUIRE (iter->pos < (unsigned int) iter->bufused); - - ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos); - - iter->pos += ifam->ifam_msglen; - - if (iter->pos >= iter->bufused) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -static void -internal_destroy(isc_interfaceiter_t *iter) { - UNUSED(iter); /* Unused. */ - /* - * Do nothing. - */ -} - -static -void internal_first(isc_interfaceiter_t *iter) { - iter->pos = 0; -} diff --git a/contrib/bind9/lib/isc/unix/include/Makefile.in b/contrib/bind9/lib/isc/unix/include/Makefile.in deleted file mode 100644 index 5a06022fbdf1..000000000000 --- a/contrib/bind9/lib/isc/unix/include/Makefile.in +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -# $Id: Makefile.in,v 1.11.206.1 2004/03/06 08:15:03 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -SUBDIRS = isc -TARGETS = - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/lib/isc/unix/include/isc/Makefile.in b/contrib/bind9/lib/isc/unix/include/isc/Makefile.in deleted file mode 100644 index 4c5bae2c345a..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/Makefile.in +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -# $Id: Makefile.in,v 1.27.206.1 2004/03/06 08:15:03 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -HEADERS = dir.h int.h net.h netdb.h offset.h stdtime.h \ - syslog.h time.h - -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ - done diff --git a/contrib/bind9/lib/isc/unix/include/isc/dir.h b/contrib/bind9/lib/isc/unix/include/isc/dir.h deleted file mode 100644 index 53b51df087b1..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/dir.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: dir.h,v 1.15.12.3 2004/03/08 09:04:57 marka Exp $ */ - -/* Principal Authors: DCL */ - -#ifndef ISC_DIR_H -#define ISC_DIR_H 1 - -#include <sys/types.h> /* Required on some systems. */ -#include <dirent.h> - -#include <isc/lang.h> -#include <isc/result.h> - -#define ISC_DIR_NAMEMAX 256 -#define ISC_DIR_PATHMAX 1024 - -typedef struct isc_direntry { - /* - * Ideally, this should be NAME_MAX, but AIX does not define it by - * default and dynamically allocating the space based on pathconf() - * complicates things undesirably, as does adding special conditionals - * just for AIX. So a comfortably sized buffer is chosen instead. - */ - char name[ISC_DIR_NAMEMAX]; - unsigned int length; -} isc_direntry_t; - -typedef struct isc_dir { - unsigned int magic; - /* - * As with isc_direntry_t->name, making this "right" for all systems - * is slightly problematic because AIX does not define PATH_MAX. - */ - char dirname[ISC_DIR_PATHMAX]; - isc_direntry_t entry; - DIR * handle; -} isc_dir_t; - -ISC_LANG_BEGINDECLS - -void -isc_dir_init(isc_dir_t *dir); - -isc_result_t -isc_dir_open(isc_dir_t *dir, const char *dirname); - -isc_result_t -isc_dir_read(isc_dir_t *dir); - -isc_result_t -isc_dir_reset(isc_dir_t *dir); - -void -isc_dir_close(isc_dir_t *dir); - -isc_result_t -isc_dir_chdir(const char *dirname); - -isc_result_t -isc_dir_chroot(const char *dirname); - -isc_result_t -isc_dir_createunique(char *templet); -/* - * Use a templet (such as from isc_file_mktemplate()) to create a uniquely - * named, empty directory. The templet string is modified in place. - * If result == ISC_R_SUCCESS, it is the name of the directory that was - * created. - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_DIR_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/int.h b/contrib/bind9/lib/isc/unix/include/isc/int.h deleted file mode 100644 index be36ccb1a160..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/int.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: int.h,v 1.11.206.1 2004/03/06 08:15:04 marka Exp $ */ - -#ifndef ISC_INT_H -#define ISC_INT_H 1 - -typedef char isc_int8_t; -typedef unsigned char isc_uint8_t; -typedef short isc_int16_t; -typedef unsigned short isc_uint16_t; -typedef int isc_int32_t; -typedef unsigned int isc_uint32_t; -typedef long long isc_int64_t; -typedef unsigned long long isc_uint64_t; - -#define ISC_INT8_MIN -128 -#define ISC_INT8_MAX 127 -#define ISC_UINT8_MAX 255 - -#define ISC_INT16_MIN -32768 -#define ISC_INT16_MAX 32767 -#define ISC_UINT16_MAX 65535 - -/* - * Note that "int" is 32 bits on all currently supported Unix-like operating - * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit - * constants are not qualified with "L". - */ -#define ISC_INT32_MIN -2147483648 -#define ISC_INT32_MAX 2147483647 -#define ISC_UINT32_MAX 4294967295U - -#define ISC_INT64_MIN -9223372036854775808LL -#define ISC_INT64_MAX 9223372036854775807LL -#define ISC_UINT64_MAX 18446744073709551615ULL - -#endif /* ISC_INT_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/keyboard.h b/contrib/bind9/lib/isc/unix/include/isc/keyboard.h deleted file mode 100644 index 31005b10e6d0..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/keyboard.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: keyboard.h,v 1.6.206.1 2004/03/06 08:15:04 marka Exp $ */ - -#ifndef ISC_KEYBOARD_H -#define ISC_KEYBOARD_H 1 - -#include <termios.h> - -#include <isc/lang.h> -#include <isc/result.h> - -ISC_LANG_BEGINDECLS - -typedef struct { - int fd; - struct termios saved_mode; - isc_result_t result; -} isc_keyboard_t; - -isc_result_t -isc_keyboard_open(isc_keyboard_t *keyboard); - -isc_result_t -isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleepseconds); - -isc_result_t -isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp); - -isc_boolean_t -isc_keyboard_canceled(isc_keyboard_t *keyboard); - -ISC_LANG_ENDDECLS - -#endif /* ISC_KEYBOARD_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/net.h b/contrib/bind9/lib/isc/unix/include/isc/net.h deleted file mode 100644 index f1a015f5bb1d..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/net.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: net.h,v 1.31.2.2.10.8 2004/04/29 01:31:23 marka Exp $ */ - -#ifndef ISC_NET_H -#define ISC_NET_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Basic Networking Types - * - * This module is responsible for defining the following basic networking - * types: - * - * struct in_addr - * struct in6_addr - * struct in6_pktinfo - * struct sockaddr - * struct sockaddr_in - * struct sockaddr_in6 - * in_port_t - * - * It ensures that the AF_ and PF_ macros are defined. - * - * It declares ntoh[sl]() and hton[sl](). - * - * It declares inet_aton(), inet_ntop(), and inet_pton(). - * - * It ensures that INADDR_LOOPBACK, INADDR_ANY, IN6ADDR_ANY_INIT, - * in6addr_any, and in6addr_loopback are available. - * - * It ensures that IN_MULTICAST() is available to check for multicast - * addresses. - * - * MP: - * No impact. - * - * Reliability: - * No anticipated impact. - * - * Resources: - * N/A. - * - * Security: - * No anticipated impact. - * - * Standards: - * BSD Socket API - * RFC 2553 - */ - -/*** - *** Imports. - ***/ -#include <isc/platform.h> - -#include <sys/types.h> -#include <sys/socket.h> /* Contractual promise. */ - -#include <net/if.h> - -#include <netinet/in.h> /* Contractual promise. */ -#include <arpa/inet.h> /* Contractual promise. */ -#ifdef ISC_PLATFORM_NEEDNETINETIN6H -#include <netinet/in6.h> /* Required on UnixWare. */ -#endif -#ifdef ISC_PLATFORM_NEEDNETINET6IN6H -#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */ -#endif - -#ifndef ISC_PLATFORM_HAVEIPV6 -#include <isc/ipv6.h> /* Contractual promise. */ -#endif - -#include <isc/lang.h> -#include <isc/types.h> - -#ifdef ISC_PLATFORM_HAVEINADDR6 -#define in6_addr in_addr6 /* Required for pre RFC2133 implementations. */ -#endif - -#ifdef ISC_PLATFORM_HAVEIPV6 -/* - * Required for some pre RFC2133 implementations. - * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in - * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. - * If 's6_addr' is defined then assume that there is a union and three - * levels otherwise assume two levels required. - */ -#ifndef IN6ADDR_ANY_INIT -#ifdef s6_addr -#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } -#else -#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } -#endif -#endif - -#ifndef IN6ADDR_LOOPBACK_INIT -#ifdef s6_addr -#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } -#else -#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } -#endif -#endif - -#ifndef IN6_IS_ADDR_V4MAPPED -#define IN6_IS_ADDR_V4MAPPED(x) \ - (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ - (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) -#endif - -#ifndef IN6_IS_ADDR_V4COMPAT -#define IN6_IS_ADDR_V4COMPAT(x) \ - (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ - ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ - (x)->s6_addr[14] != 0 || \ - ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) -#endif - -#ifndef IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) -#endif - -#ifndef IN6_IS_ADDR_LINKLOCAL -#define IN6_IS_ADDR_LINKLOCAL(a) \ - (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) -#endif - -#ifndef IN6_IS_ADDR_SITELOCAL -#define IN6_IS_ADDR_SITELOCAL(a) \ - (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) -#endif - - -#ifndef IN6_IS_ADDR_LOOPBACK -#define IN6_IS_ADDR_LOOPBACK(x) \ - (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) -#endif -#endif - -#ifndef AF_INET6 -#define AF_INET6 99 -#endif - -#ifndef PF_INET6 -#define PF_INET6 AF_INET6 -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001UL -#endif - -#ifndef ISC_PLATFORM_HAVEIN6PKTINFO -struct in6_pktinfo { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ -}; -#endif - -/* - * Cope with a missing in6addr_any and in6addr_loopback. - */ -#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY) -extern const struct in6_addr isc_net_in6addrany; -#define in6addr_any isc_net_in6addrany -#endif - -#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) -extern const struct in6_addr isc_net_in6addrloop; -#define in6addr_loopback isc_net_in6addrloop -#endif - -/* - * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. - */ -#ifdef ISC_PLATFORM_FIXIN6ISADDR -#undef IN6_IS_ADDR_GEOGRAPHIC -#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) -#undef IN6_IS_ADDR_IPX -#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) -#undef IN6_IS_ADDR_LINKLOCAL -#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) -#undef IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) -#undef IN6_IS_ADDR_NSAP -#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) -#undef IN6_IS_ADDR_PROVIDER -#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) -#undef IN6_IS_ADDR_SITELOCAL -#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) -#endif /* ISC_PLATFORM_FIXIN6ISADDR */ - -/* - * Ensure type in_port_t is defined. - */ -#ifdef ISC_PLATFORM_NEEDPORTT -typedef isc_uint16_t in_port_t; -#endif - -/* - * If this system does not have MSG_TRUNC (as returned from recvmsg()) - * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC - * faking code in socket.c. - */ -#ifndef MSG_TRUNC -#define ISC_PLATFORM_RECVOVERFLOW -#endif - -#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) - -#define ISC_IPADDR_ISMULTICAST(i) \ - (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xe0000000)) - -#define ISC_IPADDR_ISEXPERIMENTAL(i) \ - (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ - == ISC__IPADDR(0xf0000000)) - -/*** - *** Functions. - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -isc_net_probeipv4(void); -/* - * Check if the system's kernel supports IPv4. - * - * Returns: - * - * ISC_R_SUCCESS IPv4 is supported. - * ISC_R_NOTFOUND IPv4 is not supported. - * ISC_R_DISABLED IPv4 is disabled. - * ISC_R_UNEXPECTED - */ - -isc_result_t -isc_net_probeipv6(void); -/* - * Check if the system's kernel supports IPv6. - * - * Returns: - * - * ISC_R_SUCCESS IPv6 is supported. - * ISC_R_NOTFOUND IPv6 is not supported. - * ISC_R_DISABLED IPv6 is disabled. - * ISC_R_UNEXPECTED - */ - -isc_result_t -isc_net_probe_ipv6only(void); -/* - * Check if the system's kernel supports the IPV6_V6ONLY socket option. - * - * Returns: - * - * ISC_R_SUCCESS the option is supported for both TCP and UDP. - * ISC_R_NOTFOUND IPv6 itself or the option is not supported. - * ISC_R_UNEXPECTED - */ - -isc_result_t -isc_net_probe_ipv6pktinfo(void); -/* - * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option - * for UDP sockets. - * - * Returns: - * - * ISC_R_SUCCESS the option is supported. - * ISC_R_NOTFOUND IPv6 itself or the option is not supported. - * ISC_R_UNEXPECTED - */ - -void -isc_net_disableipv4(void); - -void -isc_net_disableipv6(void); - -void -isc_net_enableipv4(void); - -void -isc_net_enableipv6(void); - -#ifdef ISC_PLATFORM_NEEDNTOP -const char * -isc_net_ntop(int af, const void *src, char *dst, size_t size); -#define inet_ntop isc_net_ntop -#endif - -#ifdef ISC_PLATFORM_NEEDPTON -int -isc_net_pton(int af, const char *src, void *dst); -#undef inet_pton -#define inet_pton isc_net_pton -#endif - -#ifdef ISC_PLATFORM_NEEDATON -int -isc_net_aton(const char *cp, struct in_addr *addr); -#define inet_aton isc_net_aton -#endif - -ISC_LANG_ENDDECLS - -#endif /* ISC_NET_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/netdb.h b/contrib/bind9/lib/isc/unix/include/isc/netdb.h deleted file mode 100644 index beb91375aeec..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/netdb.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: netdb.h,v 1.6.206.1 2004/03/06 08:15:04 marka Exp $ */ - -#ifndef ISC_NETDB_H -#define ISC_NETDB_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Portable netdb.h support. - * - * This module is responsible for defining the get<x>by<y> APIs. - * - * MP: - * No impact. - * - * Reliability: - * No anticipated impact. - * - * Resources: - * N/A. - * - * Security: - * No anticipated impact. - * - * Standards: - * BSD API - */ - -/*** - *** Imports. - ***/ - -#include <isc/net.h> - -#include <netdb.h> - -#endif /* ISC_NETDB_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/offset.h b/contrib/bind9/lib/isc/unix/include/isc/offset.h deleted file mode 100644 index 0ea136258f33..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/offset.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: offset.h,v 1.10.206.1 2004/03/06 08:15:04 marka Exp $ */ - -#ifndef ISC_OFFSET_H -#define ISC_OFFSET_H 1 - -/* - * File offsets are operating-system dependent. - */ -#include <limits.h> /* Required for CHAR_BIT. */ -#include <sys/types.h> - -typedef off_t isc_offset_t; - -/* - * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral - * types", so the maximum value is all 1s except for the high bit. - * This definition is more complex than it really needs to be because it was - * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about - * integer overflow. For example, though this is equivalent to just left - * shifting 1 to the high bit and then inverting the bits, the SunOS compiler - * is unhappy about shifting a positive "1" to negative in a signed integer. - */ -#define ISC_OFFSET_MAXIMUM \ - (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \ - << (sizeof(off_t) * CHAR_BIT - 1))) - -#endif /* ISC_OFFSET_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/stat.h b/contrib/bind9/lib/isc/unix/include/isc/stat.h deleted file mode 100644 index 430420865d38..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/stat.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: stat.h,v 1.1.2.1.4.1 2004/03/06 08:15:05 marka Exp $ */ - -#ifndef ISC_STAT_H -#define ISC_STAT_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Portable netdb.h support. - * - * This module is responsible for defining S_IS??? macros. - * - * MP: - * No impact. - * - * Reliability: - * No anticipated impact. - * - * Resources: - * N/A. - * - * Security: - * No anticipated impact. - * - */ - -/*** - *** Imports. - ***/ - -#include <sys/types.h> -#include <sys/stat.h> - -#endif /* ISC_STAT_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/stdtime.h b/contrib/bind9/lib/isc/unix/include/isc/stdtime.h deleted file mode 100644 index 9b855c70eba9..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/stdtime.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: stdtime.h,v 1.8.206.1 2004/03/06 08:15:05 marka Exp $ */ - -#ifndef ISC_STDTIME_H -#define ISC_STDTIME_H 1 - -#include <isc/lang.h> -#include <isc/int.h> - -/* - * It's public information that 'isc_stdtime_t' is an unsigned integral type. - * Applications that want maximum portability should not assume anything - * about its size. - */ -typedef isc_uint32_t isc_stdtime_t; - -ISC_LANG_BEGINDECLS - -void -isc_stdtime_get(isc_stdtime_t *t); -/* - * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970. - * - * Requires: - * - * 't' is a valid pointer. - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_STDTIME_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/strerror.h b/contrib/bind9/lib/isc/unix/include/isc/strerror.h deleted file mode 100644 index f51fbdc2d04c..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/strerror.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: strerror.h,v 1.2.12.3 2004/03/08 09:04:57 marka Exp $ */ - -#ifndef ISC_STRERROR_H -#define ISC_STRERROR_H - -#include <sys/types.h> - -#include <isc/lang.h> - -ISC_LANG_BEGINDECLS - -#define ISC_STRERRORSIZE 128 - -/* - * Provide a thread safe wrapper to strerrror(). - * - * Requires: - * 'buf' to be non NULL. - */ -void -isc__strerror(int num, char *buf, size_t bufsize); - -ISC_LANG_ENDDECLS - -#endif /* ISC_STRERROR_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/syslog.h b/contrib/bind9/lib/isc/unix/include/isc/syslog.h deleted file mode 100644 index 2c0625eb277d..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/syslog.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: syslog.h,v 1.2.206.1 2004/03/06 08:15:05 marka Exp $ */ - -#ifndef ISC_SYSLOG_H -#define ISC_SYSLOG_H 1 - -#include <isc/lang.h> -#include <isc/types.h> - -ISC_LANG_BEGINDECLS - -isc_result_t -isc_syslog_facilityfromstring(const char *str, int *facilityp); -/* - * Convert 'str' to the appropriate syslog facility constant. - * - * Requires: - * - * 'str' is not NULL - * 'facilityp' is not NULL - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_SYSLOG_H */ diff --git a/contrib/bind9/lib/isc/unix/include/isc/time.h b/contrib/bind9/lib/isc/unix/include/isc/time.h deleted file mode 100644 index 6021c13d9295..000000000000 --- a/contrib/bind9/lib/isc/unix/include/isc/time.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1998-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: time.h,v 1.25.2.1.10.4 2004/03/08 09:04:58 marka Exp $ */ - -#ifndef ISC_TIME_H -#define ISC_TIME_H 1 - -#include <isc/lang.h> -#include <isc/types.h> - -/*** - *** Intervals - ***/ - -/* - * The contents of this structure are private, and MUST NOT be accessed - * directly by callers. - * - * The contents are exposed only to allow callers to avoid dynamic allocation. - */ -struct isc_interval { - unsigned int seconds; - unsigned int nanoseconds; -}; - -extern isc_interval_t *isc_interval_zero; - -ISC_LANG_BEGINDECLS - -void -isc_interval_set(isc_interval_t *i, - unsigned int seconds, unsigned int nanoseconds); -/* - * Set 'i' to a value representing an interval of 'seconds' seconds and - * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and - * isc_time_subtract(). - * - * Requires: - * - * 't' is a valid pointer. - * nanoseconds < 1000000000. - */ - -isc_boolean_t -isc_interval_iszero(const isc_interval_t *i); -/* - * Returns ISC_TRUE iff. 'i' is the zero interval. - * - * Requires: - * - * 'i' is a valid pointer. - */ - -/*** - *** Absolute Times - ***/ - -/* - * The contents of this structure are private, and MUST NOT be accessed - * directly by callers. - * - * The contents are exposed only to allow callers to avoid dynamic allocation. - */ - -struct isc_time { - unsigned int seconds; - unsigned int nanoseconds; -}; - -extern isc_time_t *isc_time_epoch; - -void -isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); -/* - * Set 't' to a particular number of seconds + nanoseconds since the epoch. - * - * Notes: - * This call is equivalent to: - * - * isc_time_settoepoch(t); - * isc_interval_set(i, seconds, nanoseconds); - * isc_time_add(t, i, t); - * - * Requires: - * 't' is a valid pointer. - * nanoseconds < 1000000000. - */ - -void -isc_time_settoepoch(isc_time_t *t); -/* - * Set 't' to the time of the epoch. - * - * Notes: - * The date of the epoch is platform-dependent. - * - * Requires: - * - * 't' is a valid pointer. - */ - -isc_boolean_t -isc_time_isepoch(const isc_time_t *t); -/* - * Returns ISC_TRUE iff. 't' is the epoch ("time zero"). - * - * Requires: - * - * 't' is a valid pointer. - */ - -isc_result_t -isc_time_now(isc_time_t *t); -/* - * Set 't' to the current absolute time. - * - * Requires: - * - * 't' is a valid pointer. - * - * Returns: - * - * Success - * Unexpected error - * Getting the time from the system failed. - * Out of range - * The time from the system is too large to be represented - * in the current definition of isc_time_t. - */ - -isc_result_t -isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i); -/* - * Set *t to the current absolute time + i. - * - * Note: - * This call is equivalent to: - * - * isc_time_now(t); - * isc_time_add(t, i, t); - * - * Requires: - * - * 't' and 'i' are valid pointers. - * - * Returns: - * - * Success - * Unexpected error - * Getting the time from the system failed. - * Out of range - * The interval added to the time from the system is too large to - * be represented in the current definition of isc_time_t. - */ - -int -isc_time_compare(const isc_time_t *t1, const isc_time_t *t2); -/* - * Compare the times referenced by 't1' and 't2' - * - * Requires: - * - * 't1' and 't2' are valid pointers. - * - * Returns: - * - * -1 t1 < t2 (comparing times, not pointers) - * 0 t1 = t2 - * 1 t1 > t2 - */ - -isc_result_t -isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); -/* - * Add 'i' to 't', storing the result in 'result'. - * - * Requires: - * - * 't', 'i', and 'result' are valid pointers. - * - * Returns: - * Success - * Out of range - * The interval added to the time is too large to - * be represented in the current definition of isc_time_t. - */ - -isc_result_t -isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, - isc_time_t *result); -/* - * Subtract 'i' from 't', storing the result in 'result'. - * - * Requires: - * - * 't', 'i', and 'result' are valid pointers. - * - * Returns: - * Success - * Out of range - * The interval is larger than the time since the epoch. - */ - -isc_uint64_t -isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2); -/* - * Find the difference in microseconds between time t1 and time t2. - * t2 is the subtrahend of t1; ie, difference = t1 - t2. - * - * Requires: - * - * 't1' and 't2' are valid pointers. - * - * Returns: - * The difference of t1 - t2, or 0 if t1 <= t2. - */ - -isc_uint32_t -isc_time_seconds(const isc_time_t *t); -/* - * Return the number of seconds since the epoch stored in a time structure. - * - * Requires: - * - * 't' is a valid pointer. - */ - -isc_result_t -isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp); -/* - * Ensure the number of seconds in an isc_time_t is representable by a time_t. - * - * Notes: - * The number of seconds stored in an isc_time_t might be larger - * than the number of seconds a time_t is able to handle. Since - * time_t is mostly opaque according to the ANSI/ISO standard - * (essentially, all you can be sure of is that it is an arithmetic type, - * not even necessarily integral), it can be tricky to ensure that - * the isc_time_t is in the range a time_t can handle. Use this - * function in place of isc_time_seconds() any time you need to set a - * time_t from an isc_time_t. - * - * Requires: - * 't' is a valid pointer. - * - * Returns: - * Success - * Out of range - */ - -isc_uint32_t -isc_time_nanoseconds(const isc_time_t *t); -/* - * Return the number of nanoseconds stored in a time structure. - * - * Notes: - * This is the number of nanoseconds in excess of the the number - * of seconds since the epoch; it will always be less than one - * full second. - * - * Requires: - * 't' is a valid pointer. - * - * Ensures: - * The returned value is less than 1*10^9. - */ - -void -isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); -/* - * Format the time 't' into the buffer 'buf' of length 'len', - * using a format like "30-Aug-2000 04:06:47.997" and the local time zone. - * If the text does not fit in the buffer, the result is indeterminate, - * but is always guaranteed to be null terminated. - * - * Requires: - * 'len' > 0 - * 'buf' points to an array of at least len chars - * - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_TIME_H */ diff --git a/contrib/bind9/lib/isc/unix/interfaceiter.c b/contrib/bind9/lib/isc/unix/interfaceiter.c deleted file mode 100644 index 9520bdeb5670..000000000000 --- a/contrib/bind9/lib/isc/unix/interfaceiter.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: interfaceiter.c,v 1.22.2.1.10.14 2004/08/28 06:25:22 marka Exp $ */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/ioctl.h> -#ifdef HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> /* Required for ifiter_ioctl.c. */ -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> - -#include <isc/interfaceiter.h> -#include <isc/log.h> -#include <isc/magic.h> -#include <isc/mem.h> -#include <isc/msgs.h> -#include <isc/net.h> -#include <isc/print.h> -#include <isc/result.h> -#include <isc/strerror.h> -#include <isc/string.h> -#include <isc/types.h> -#include <isc/util.h> - -/* Must follow <isc/net.h>. */ -#ifdef HAVE_NET_IF6_H -#include <net/if6.h> -#endif -#include <net/if.h> - -/* Common utility functions */ - -/* - * Extract the network address part from a "struct sockaddr". - * - * The address family is given explicitly - * instead of using src->sa_family, because the latter does not work - * for copying a network mask obtained by SIOCGIFNETMASK (it does - * not have a valid address family). - */ - -static void -get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, - char *ifname) -{ - struct sockaddr_in6 *sa6; - -#if !defined(ISC_PLATFORM_HAVEIFNAMETOINDEX) || \ - !defined(ISC_PLATFORM_HAVESCOPEID) - UNUSED(ifname); -#endif - - /* clear any remaining value for safety */ - memset(dst, 0, sizeof(*dst)); - - dst->family = family; - switch (family) { - case AF_INET: - memcpy(&dst->type.in, - &((struct sockaddr_in *) src)->sin_addr, - sizeof(struct in_addr)); - break; - case AF_INET6: - sa6 = (struct sockaddr_in6 *)src; - memcpy(&dst->type.in6, &sa6->sin6_addr, - sizeof(struct in6_addr)); -#ifdef ISC_PLATFORM_HAVESCOPEID - if (sa6->sin6_scope_id != 0) - isc_netaddr_setzone(dst, sa6->sin6_scope_id); - else { - /* - * BSD variants embed scope zone IDs in the 128bit - * address as a kernel internal form. Unfortunately, - * the embedded IDs are not hidden from applications - * when getting access to them by sysctl or ioctl. - * We convert the internal format to the pure address - * part and the zone ID part. - * Since multicast addresses should not appear here - * and they cannot be distinguished from netmasks, - * we only consider unicast link-local addresses. - */ - if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) { - isc_uint16_t zone16; - - memcpy(&zone16, &sa6->sin6_addr.s6_addr[2], - sizeof(zone16)); - zone16 = ntohs(zone16); - if (zone16 != 0) { - /* the zone ID is embedded */ - isc_netaddr_setzone(dst, - (isc_uint32_t)zone16); - dst->type.in6.s6_addr[2] = 0; - dst->type.in6.s6_addr[3] = 0; -#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX - } else if (ifname != NULL) { - unsigned int zone; - - /* - * sin6_scope_id is still not provided, - * but the corresponding interface name - * is know. Use the interface ID as - * the link ID. - */ - zone = if_nametoindex(ifname); - if (zone != 0) { - isc_netaddr_setzone(dst, - (isc_uint32_t)zone); - } -#endif - } - } - } -#endif - break; - default: - INSIST(0); - break; - } -} - -/* - * Include system-dependent code. - */ - -#if HAVE_GETIFADDRS -#include "ifiter_getifaddrs.c" -#elif HAVE_IFLIST_SYSCTL -#include "ifiter_sysctl.c" -#else -#include "ifiter_ioctl.c" -#endif - -/* - * The remaining code is common to the sysctl and ioctl case. - */ - -isc_result_t -isc_interfaceiter_current(isc_interfaceiter_t *iter, - isc_interface_t *ifdata) -{ - REQUIRE(iter->result == ISC_R_SUCCESS); - memcpy(ifdata, &iter->current, sizeof(*ifdata)); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_interfaceiter_first(isc_interfaceiter_t *iter) { - isc_result_t result; - - REQUIRE(VALID_IFITER(iter)); - - internal_first(iter); - for (;;) { - result = internal_current(iter); - if (result != ISC_R_IGNORE) - break; - result = internal_next(iter); - if (result != ISC_R_SUCCESS) - break; - } - iter->result = result; - return (result); -} - -isc_result_t -isc_interfaceiter_next(isc_interfaceiter_t *iter) { - isc_result_t result; - - REQUIRE(VALID_IFITER(iter)); - REQUIRE(iter->result == ISC_R_SUCCESS); - - for (;;) { - result = internal_next(iter); - if (result != ISC_R_SUCCESS) - break; - result = internal_current(iter); - if (result != ISC_R_IGNORE) - break; - } - iter->result = result; - return (result); -} - -void -isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) -{ - isc_interfaceiter_t *iter; - REQUIRE(iterp != NULL); - iter = *iterp; - REQUIRE(VALID_IFITER(iter)); - - internal_destroy(iter); - if (iter->buf != NULL) - isc_mem_put(iter->mctx, iter->buf, iter->bufsize); - - iter->magic = 0; - isc_mem_put(iter->mctx, iter, sizeof(*iter)); - *iterp = NULL; -} diff --git a/contrib/bind9/lib/isc/unix/ipv6.c b/contrib/bind9/lib/isc/unix/ipv6.c deleted file mode 100644 index 25e0c57b09fc..000000000000 --- a/contrib/bind9/lib/isc/unix/ipv6.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: ipv6.c,v 1.7.206.1 2004/03/06 08:15:00 marka Exp $ */ - -#include <isc/ipv6.h> - -const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; -const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; diff --git a/contrib/bind9/lib/isc/unix/keyboard.c b/contrib/bind9/lib/isc/unix/keyboard.c deleted file mode 100644 index 146338aebe75..000000000000 --- a/contrib/bind9/lib/isc/unix/keyboard.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: keyboard.c,v 1.9.12.3 2004/03/08 09:04:56 marka Exp $ */ - -#include <config.h> - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/uio.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <termios.h> -#include <unistd.h> -#include <fcntl.h> - -#include <isc/keyboard.h> -#include <isc/util.h> - -isc_result_t -isc_keyboard_open(isc_keyboard_t *keyboard) { - int fd; - isc_result_t ret; - struct termios current_mode; - - REQUIRE(keyboard != NULL); - - fd = open("/dev/tty", O_RDONLY, 0); - if (fd < 0) - return (ISC_R_IOERROR); - - keyboard->fd = fd; - - if (tcgetattr(fd, &keyboard->saved_mode) < 0) { - ret = ISC_R_IOERROR; - goto errout; - } - - current_mode = keyboard->saved_mode; - - current_mode.c_iflag &= - ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - current_mode.c_oflag &= ~OPOST; - current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - current_mode.c_cflag &= ~(CSIZE|PARENB); - current_mode.c_cflag |= CS8; - - current_mode.c_cc[VMIN] = 1; - current_mode.c_cc[VTIME] = 0; - if (tcsetattr(fd, TCSAFLUSH, ¤t_mode) < 0) { - ret = ISC_R_IOERROR; - goto errout; - } - - keyboard->result = ISC_R_SUCCESS; - - return (ISC_R_SUCCESS); - - errout: - close (fd); - - return (ret); -} - -isc_result_t -isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { - REQUIRE(keyboard != NULL); - - if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) - (void)sleep(sleeptime); - - (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode); - (void)close(keyboard->fd); - - keyboard->fd = -1; - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { - ssize_t cc; - unsigned char c; - cc_t *controlchars; - - REQUIRE(keyboard != NULL); - REQUIRE(cp != NULL); - - cc = read(keyboard->fd, &c, 1); - if (cc < 0) { - keyboard->result = ISC_R_IOERROR; - return (keyboard->result); - } - - controlchars = keyboard->saved_mode.c_cc; - if (c == controlchars[VINTR] || c == controlchars[VQUIT]) { - keyboard->result = ISC_R_CANCELED; - return (keyboard->result); - } - - *cp = c; - - return (ISC_R_SUCCESS); -} - -isc_boolean_t -isc_keyboard_canceled(isc_keyboard_t *keyboard) { - return (ISC_TF(keyboard->result == ISC_R_CANCELED)); -} diff --git a/contrib/bind9/lib/isc/unix/net.c b/contrib/bind9/lib/isc/unix/net.c deleted file mode 100644 index e0aeccbbbf4d..000000000000 --- a/contrib/bind9/lib/isc/unix/net.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: net.c,v 1.22.2.2.10.9 2005/03/17 03:58:33 marka Exp $ */ - -#include <config.h> - -#include <errno.h> -#include <unistd.h> - -#include <isc/log.h> -#include <isc/msgs.h> -#include <isc/net.h> -#include <isc/once.h> -#include <isc/strerror.h> -#include <isc/string.h> -#include <isc/util.h> - -#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY) -const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT; -#endif - -#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) -const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT; -#endif - -static isc_once_t once = ISC_ONCE_INIT; -static isc_once_t once_ipv6only = ISC_ONCE_INIT; -static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; -static isc_result_t ipv4_result = ISC_R_NOTFOUND; -static isc_result_t ipv6_result = ISC_R_NOTFOUND; -static isc_result_t ipv6only_result = ISC_R_NOTFOUND; -static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; - -static isc_result_t -try_proto(int domain) { - int s; - isc_result_t result = ISC_R_SUCCESS; - char strbuf[ISC_STRERRORSIZE]; - - s = socket(domain, SOCK_STREAM, 0); - if (s == -1) { - switch (errno) { -#ifdef EAFNOSUPPORT - case EAFNOSUPPORT: -#endif -#ifdef EPROTONOSUPPORT - case EPROTONOSUPPORT: -#endif -#ifdef EINVAL - case EINVAL: -#endif - return (ISC_R_NOTFOUND); - default: - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - return (ISC_R_UNEXPECTED); - } - } - -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifdef WANT_IPV6 -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO - if (domain == PF_INET6) { - struct sockaddr_in6 sin6; - unsigned int len; - - /* - * Check to see if IPv6 is broken, as is common on Linux. - */ - len = sizeof(sin6); - if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0) - { - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "retrieving the address of an IPv6 " - "socket from the kernel failed."); - isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - "IPv6 is not supported."); - result = ISC_R_NOTFOUND; - } else { - if (len == sizeof(struct sockaddr_in6)) - result = ISC_R_SUCCESS; - else { - isc_log_write(isc_lctx, - ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, - ISC_LOG_ERROR, - "IPv6 structures in kernel and " - "user space do not match."); - isc_log_write(isc_lctx, - ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, - ISC_LOG_ERROR, - "IPv6 is not supported."); - result = ISC_R_NOTFOUND; - } - } - } -#endif -#endif -#endif - - (void)close(s); - - return (result); -} - -static void -initialize_action(void) { - ipv4_result = try_proto(PF_INET); -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifdef WANT_IPV6 -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO - ipv6_result = try_proto(PF_INET6); -#endif -#endif -#endif -} - -static void -initialize(void) { - RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); -} - -isc_result_t -isc_net_probeipv4(void) { - initialize(); - return (ipv4_result); -} - -isc_result_t -isc_net_probeipv6(void) { - initialize(); - return (ipv6_result); -} - -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifdef WANT_IPV6 -static void -try_ipv6only(void) { -#ifdef IPV6_V6ONLY - int s, on; - char strbuf[ISC_STRERRORSIZE]; -#endif - isc_result_t result; - - result = isc_net_probeipv6(); - if (result != ISC_R_SUCCESS) { - ipv6only_result = result; - return; - } - -#ifndef IPV6_V6ONLY - ipv6only_result = ISC_R_NOTFOUND; - return; -#else - /* check for TCP sockets */ - s = socket(PF_INET6, SOCK_STREAM, 0); - if (s == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - ipv6only_result = ISC_R_UNEXPECTED; - return; - } - - on = 1; - if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { - ipv6only_result = ISC_R_NOTFOUND; - goto close; - } - - close(s); - - /* check for UDP sockets */ - s = socket(PF_INET6, SOCK_DGRAM, 0); - if (s == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - ipv6only_result = ISC_R_UNEXPECTED; - return; - } - - on = 1; - if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { - ipv6only_result = ISC_R_NOTFOUND; - goto close; - } - - close(s); - - ipv6only_result = ISC_R_SUCCESS; - -close: - close(s); - return; -#endif /* IPV6_V6ONLY */ -} - -static void -initialize_ipv6only(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6only, - try_ipv6only) == ISC_R_SUCCESS); -} -#endif /* IPV6_V6ONLY */ - -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO -static void -try_ipv6pktinfo(void) { - int s, on; - char strbuf[ISC_STRERRORSIZE]; - isc_result_t result; - int optname; - - result = isc_net_probeipv6(); - if (result != ISC_R_SUCCESS) { - ipv6pktinfo_result = result; - return; - } - - /* we only use this for UDP sockets */ - s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (s == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - ipv6pktinfo_result = ISC_R_UNEXPECTED; - return; - } - -#ifdef IPV6_RECVPKTINFO - optname = IPV6_RECVPKTINFO; -#else - optname = IPV6_PKTINFO; -#endif - on = 1; - if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) { - ipv6pktinfo_result = ISC_R_NOTFOUND; - goto close; - } - - close(s); - ipv6pktinfo_result = ISC_R_SUCCESS; - -close: - close(s); - return; -} - -static void -initialize_ipv6pktinfo(void) { - RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, - try_ipv6pktinfo) == ISC_R_SUCCESS); -} -#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#endif /* WANT_IPV6 */ - -isc_result_t -isc_net_probe_ipv6only(void) { -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifdef WANT_IPV6 - initialize_ipv6only(); -#else - ipv6only_result = ISC_R_NOTFOUND; -#endif -#endif - return (ipv6only_result); -} - -isc_result_t -isc_net_probe_ipv6pktinfo(void) { -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO -#ifdef WANT_IPV6 - initialize_ipv6pktinfo(); -#else - ipv6pktinfo_result = ISC_R_NOTFOUND; -#endif -#endif -#endif - return (ipv6pktinfo_result); -} - -void -isc_net_disableipv4(void) { - initialize(); - if (ipv4_result == ISC_R_SUCCESS) - ipv4_result = ISC_R_DISABLED; -} - -void -isc_net_disableipv6(void) { - initialize(); - if (ipv6_result == ISC_R_SUCCESS) - ipv6_result = ISC_R_DISABLED; -} - -void -isc_net_enableipv4(void) { - initialize(); - if (ipv4_result == ISC_R_DISABLED) - ipv4_result = ISC_R_SUCCESS; -} - -void -isc_net_enableipv6(void) { - initialize(); - if (ipv6_result == ISC_R_DISABLED) - ipv6_result = ISC_R_SUCCESS; -} diff --git a/contrib/bind9/lib/isc/unix/os.c b/contrib/bind9/lib/isc/unix/os.c deleted file mode 100644 index 4d34d8ce6f47..000000000000 --- a/contrib/bind9/lib/isc/unix/os.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: os.c,v 1.11.12.6 2005/10/14 02:13:07 marka Exp $ */ - -#include <config.h> - -#include <isc/os.h> - - -#ifdef HAVE_SYSCONF - -#include <unistd.h> - -#ifndef __hpux -static inline long -sysconf_ncpus(void) { -#if defined(_SC_NPROCESSORS_ONLN) - return sysconf((_SC_NPROCESSORS_ONLN)); -#elif defined(_SC_NPROC_ONLN) - return sysconf((_SC_NPROC_ONLN)); -#else - return (0); -#endif -} -#endif -#endif /* HAVE_SYSCONF */ - - -#ifdef __hpux - -#include <sys/pstat.h> - -static inline int -hpux_ncpus(void) { - struct pst_dynamic psd; - if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) != -1) - return (psd.psd_proc_cnt); - else - return (0); -} - -#endif /* __hpux */ - -#if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) -#include <sys/types.h> /* for FreeBSD */ -#include <sys/param.h> /* for NetBSD */ -#include <sys/sysctl.h> - -static int -sysctl_ncpus(void) { - int ncpu, result; - size_t len; - - len = sizeof(ncpu); - result = sysctlbyname("hw.ncpu", &ncpu, &len , 0, 0); - if (result != -1) - return (ncpu); - return (0); -} -#endif - -unsigned int -isc_os_ncpus(void) { - long ncpus = 0; - -#ifdef __hpux - ncpus = hpux_ncpus(); -#elif defined(HAVE_SYSCONF) - ncpus = sysconf_ncpus(); -#endif -#if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) - if (ncpus <= 0) - ncpus = sysctl_ncpus(); -#endif - if (ncpus <= 0) - ncpus = 1; - - return ((unsigned int)ncpus); -} diff --git a/contrib/bind9/lib/isc/unix/resource.c b/contrib/bind9/lib/isc/unix/resource.c deleted file mode 100644 index b6faf32a5e4d..000000000000 --- a/contrib/bind9/lib/isc/unix/resource.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: resource.c,v 1.11.206.1 2004/03/06 08:15:01 marka Exp $ */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/time.h> /* Required on some systems for <sys/resource.h>. */ -#include <sys/resource.h> - -#include <isc/platform.h> -#include <isc/resource.h> -#include <isc/result.h> -#include <isc/util.h> - -#include "errno2result.h" - -static isc_result_t -resource2rlim(isc_resource_t resource, int *rlim_resource) { - isc_result_t result = ISC_R_SUCCESS; - - switch (resource) { - case isc_resource_coresize: - *rlim_resource = RLIMIT_CORE; - break; - case isc_resource_cputime: - *rlim_resource = RLIMIT_CPU; - break; - case isc_resource_datasize: - *rlim_resource = RLIMIT_DATA; - break; - case isc_resource_filesize: - *rlim_resource = RLIMIT_FSIZE; - break; - case isc_resource_lockedmemory: -#ifdef RLIMIT_MEMLOCK - *rlim_resource = RLIMIT_MEMLOCK; -#else - result = ISC_R_NOTIMPLEMENTED; -#endif - break; - case isc_resource_openfiles: -#ifdef RLIMIT_NOFILE - *rlim_resource = RLIMIT_NOFILE; -#else - result = ISC_R_NOTIMPLEMENTED; -#endif - break; - case isc_resource_processes: -#ifdef RLIMIT_NPROC - *rlim_resource = RLIMIT_NPROC; -#else - result = ISC_R_NOTIMPLEMENTED; -#endif - break; - case isc_resource_residentsize: -#ifdef RLIMIT_RSS - *rlim_resource = RLIMIT_RSS; -#else - result = ISC_R_NOTIMPLEMENTED; -#endif - break; - case isc_resource_stacksize: - *rlim_resource = RLIMIT_STACK; - break; - default: - /* - * This test is not very robust if isc_resource_t - * changes, but generates a clear assertion message. - */ - REQUIRE(resource >= isc_resource_coresize && - resource <= isc_resource_stacksize); - - result = ISC_R_RANGE; - break; - } - - return (result); -} - -isc_result_t -isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { - struct rlimit rl; - ISC_PLATFORM_RLIMITTYPE rlim_value; - int unixresult; - int unixresource; - isc_result_t result; - - result = resource2rlim(resource, &unixresource); - if (result != ISC_R_SUCCESS) - return (result); - - if (value == ISC_RESOURCE_UNLIMITED) - rlim_value = RLIM_INFINITY; - - else { - /* - * isc_resourcevalue_t was chosen as an unsigned 64 bit - * integer so that it could contain the maximum range of - * reasonable values. Unfortunately, this exceeds the typical - * range on Unix systems. Ensure the range of - * ISC_PLATFORM_RLIMITTYPE is not overflowed. - */ - isc_resourcevalue_t rlim_max; - isc_boolean_t rlim_t_is_signed = - ISC_TF(((double)(ISC_PLATFORM_RLIMITTYPE)-1) < 0); - - if (rlim_t_is_signed) - rlim_max = ~((ISC_PLATFORM_RLIMITTYPE)1 << - (sizeof(ISC_PLATFORM_RLIMITTYPE) * 8 - 1)); - else - rlim_max = (ISC_PLATFORM_RLIMITTYPE)-1; - - if (value > rlim_max) - value = rlim_max; - - rlim_value = value; - } - - /* - * The BIND 8 documentation reports: - * - * Note: on some operating systems the server cannot set an - * unlimited value and cannot determine the maximum number of - * open files the kernel can support. On such systems, choosing - * unlimited will cause the server to use the larger of the - * rlim_max for RLIMIT_NOFILE and the value returned by - * sysconf(_SC_OPEN_MAX). If the actual kernel limit is larger - * than this value, use limit files to specify the limit - * explicitly. - * - * The CHANGES for 8.1.2-T3A also mention: - * - * 352. [bug] Because of problems with setting an infinite - * rlim_max for RLIMIT_NOFILE on some systems, previous versions - * of the server implemented "limit files unlimited" by setting - * the limit to the value returned by sysconf(_SC_OPEN_MAX). The - * server will now use RLIM_INFINITY on systems which allow it. - * - * At some point the BIND 8 server stopped using SC_OPEN_MAX for this - * purpose at all, but it isn't clear to me when or why, as my access - * to the CVS archive is limited at the time of this writing. What - * BIND 8 *does* do is to set RLIMIT_NOFILE to either RLIMIT_INFINITY - * on a half dozen operating systems or to FD_SETSIZE on the rest, - * the latter of which is probably fewer than the real limit. (Note - * that libisc's socket module will have problems with any fd over - * FD_SETSIZE. This should be fixed in the socket module, not a - * limitation here. BIND 8's eventlib also has a problem, making - * its RLIMIT_INFINITY setting useless, because it closes and ignores - * any fd over FD_SETSIZE.) - * - * More troubling is the reference to some operating systems not being - * able to set an unlimited value for the number of open files. I'd - * hate to put in code that is really only there to support archaic - * systems that the rest of libisc won't work on anyway. So what this - * extremely verbose comment is here to say is the following: - * - * I'm aware there might be an issue with not limiting the value - * for RLIMIT_NOFILE on some systems, but since I don't know yet - * what those systems are and what the best workaround is (use - * sysconf()? rlim_max from getrlimit()? FD_SETSIZE?) so nothing - * is currently being done to clamp the value for open files. - */ - - rl.rlim_cur = rl.rlim_max = rlim_value; - unixresult = setrlimit(unixresource, &rl); - - if (unixresult == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_result_t -isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { - int unixresult; - int unixresource; - struct rlimit rl; - isc_result_t result; - - result = resource2rlim(resource, &unixresource); - if (result == ISC_R_SUCCESS) { - unixresult = getrlimit(unixresource, &rl); - INSIST(unixresult == 0); - *value = rl.rlim_max; - } - - return (result); -} diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c deleted file mode 100644 index 595990f995c5..000000000000 --- a/contrib/bind9/lib/isc/unix/socket.c +++ /dev/null @@ -1,3526 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1998-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: socket.c,v 1.207.2.19.2.22 2005/11/03 23:08:42 marka Exp $ */ - -#include <config.h> - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/uio.h> - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <isc/buffer.h> -#include <isc/bufferlist.h> -#include <isc/condition.h> -#include <isc/formatcheck.h> -#include <isc/list.h> -#include <isc/log.h> -#include <isc/mem.h> -#include <isc/msgs.h> -#include <isc/mutex.h> -#include <isc/net.h> -#include <isc/platform.h> -#include <isc/print.h> -#include <isc/region.h> -#include <isc/socket.h> -#include <isc/strerror.h> -#include <isc/task.h> -#include <isc/thread.h> -#include <isc/util.h> - -#include "errno2result.h" - -#ifndef ISC_PLATFORM_USETHREADS -#include "socket_p.h" -#endif /* ISC_PLATFORM_USETHREADS */ - -/* - * Some systems define the socket length argument as an int, some as size_t, - * some as socklen_t. This is here so it can be easily changed if needed. - */ -#ifndef ISC_SOCKADDR_LEN_T -#define ISC_SOCKADDR_LEN_T unsigned int -#endif - -/* - * Define what the possible "soft" errors can be. These are non-fatal returns - * of various network related functions, like recv() and so on. - * - * For some reason, BSDI (and perhaps others) will sometimes return <0 - * from recv() but will have errno==0. This is broken, but we have to - * work around it here. - */ -#define SOFT_ERROR(e) ((e) == EAGAIN || \ - (e) == EWOULDBLOCK || \ - (e) == EINTR || \ - (e) == 0) - -#define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x) - -/* - * DLVL(90) -- Function entry/exit and other tracing. - * DLVL(70) -- Socket "correctness" -- including returning of events, etc. - * DLVL(60) -- Socket data send/receive - * DLVL(50) -- Event tracing, including receiving/sending completion events. - * DLVL(20) -- Socket creation/destruction. - */ -#define TRACE_LEVEL 90 -#define CORRECTNESS_LEVEL 70 -#define IOEVENT_LEVEL 60 -#define EVENT_LEVEL 50 -#define CREATION_LEVEL 20 - -#define TRACE DLVL(TRACE_LEVEL) -#define CORRECTNESS DLVL(CORRECTNESS_LEVEL) -#define IOEVENT DLVL(IOEVENT_LEVEL) -#define EVENT DLVL(EVENT_LEVEL) -#define CREATION DLVL(CREATION_LEVEL) - -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) - -/* - * IPv6 control information. If the socket is an IPv6 socket we want - * to collect the destination address and interface so the client can - * set them on outgoing packets. - */ -#ifdef ISC_PLATFORM_HAVEIPV6 -#ifndef USE_CMSG -#define USE_CMSG 1 -#endif -#endif - -/* - * NetBSD and FreeBSD can timestamp packets. XXXMLG Should we have - * a setsockopt() like interface to request timestamps, and if the OS - * doesn't do it for us, call gettimeofday() on every UDP receive? - */ -#ifdef SO_TIMESTAMP -#ifndef USE_CMSG -#define USE_CMSG 1 -#endif -#endif - -/* - * The number of times a send operation is repeated if the result is EINTR. - */ -#define NRETRIES 10 - -struct isc_socket { - /* Not locked. */ - unsigned int magic; - isc_socketmgr_t *manager; - isc_mutex_t lock; - isc_sockettype_t type; - - /* Locked by socket lock. */ - ISC_LINK(isc_socket_t) link; - unsigned int references; - int fd; - int pf; - - ISC_LIST(isc_socketevent_t) send_list; - ISC_LIST(isc_socketevent_t) recv_list; - ISC_LIST(isc_socket_newconnev_t) accept_list; - isc_socket_connev_t *connect_ev; - - /* - * Internal events. Posted when a descriptor is readable or - * writable. These are statically allocated and never freed. - * They will be set to non-purgable before use. - */ - intev_t readable_ev; - intev_t writable_ev; - - isc_sockaddr_t address; /* remote address */ - - unsigned int pending_recv : 1, - pending_send : 1, - pending_accept : 1, - listener : 1, /* listener socket */ - connected : 1, - connecting : 1, /* connect pending */ - bound : 1; /* bound to local addr */ - -#ifdef ISC_NET_RECVOVERFLOW - unsigned char overflow; /* used for MSG_TRUNC fake */ -#endif - - char *recvcmsgbuf; - ISC_SOCKADDR_LEN_T recvcmsgbuflen; - char *sendcmsgbuf; - ISC_SOCKADDR_LEN_T sendcmsgbuflen; -}; - -#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) - -struct isc_socketmgr { - /* Not locked. */ - unsigned int magic; - isc_mem_t *mctx; - isc_mutex_t lock; - /* Locked by manager lock. */ - ISC_LIST(isc_socket_t) socklist; - fd_set read_fds; - fd_set write_fds; - isc_socket_t *fds[FD_SETSIZE]; - int fdstate[FD_SETSIZE]; - int maxfd; -#ifdef ISC_PLATFORM_USETHREADS - isc_thread_t watcher; - isc_condition_t shutdown_ok; - int pipe_fds[2]; -#else /* ISC_PLATFORM_USETHREADS */ - unsigned int refs; -#endif /* ISC_PLATFORM_USETHREADS */ -}; - -#ifndef ISC_PLATFORM_USETHREADS -static isc_socketmgr_t *socketmgr = NULL; -#endif /* ISC_PLATFORM_USETHREADS */ - -#define CLOSED 0 /* this one must be zero */ -#define MANAGED 1 -#define CLOSE_PENDING 2 - -/* - * send() and recv() iovec counts - */ -#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) -#ifdef ISC_NET_RECVOVERFLOW -# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER + 1) -#else -# 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 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 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 *, - struct msghdr *, struct iovec *, size_t *); - -#define SELECT_POKE_SHUTDOWN (-1) -#define SELECT_POKE_NOTHING (-2) -#define SELECT_POKE_READ (-3) -#define SELECT_POKE_ACCEPT (-3) /* Same as _READ */ -#define SELECT_POKE_WRITE (-4) -#define SELECT_POKE_CONNECT (-4) /* Same as _WRITE */ -#define SELECT_POKE_CLOSE (-5) - -#define SOCK_DEAD(s) ((s)->references == 0) - -static void -manager_log(isc_socketmgr_t *sockmgr, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); -static void -manager_log(isc_socketmgr_t *sockmgr, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - const char *fmt, ...) -{ - char msgbuf[2048]; - va_list ap; - - if (! isc_log_wouldlog(isc_lctx, level)) - return; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - isc_log_write(isc_lctx, category, module, level, - "sockmgr %p: %s", sockmgr, msgbuf); -} - -static void -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, - isc_logcategory_t *category, isc_logmodule_t *module, int level, - isc_msgcat_t *msgcat, int msgset, int message, - const char *fmt, ...) -{ - char msgbuf[2048]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - va_list ap; - - if (! isc_log_wouldlog(isc_lctx, level)) - return; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - if (address == NULL) { - isc_log_iwrite(isc_lctx, category, module, level, - msgcat, msgset, message, - "socket %p: %s", sock, msgbuf); - } else { - isc_sockaddr_format(address, peerbuf, sizeof(peerbuf)); - isc_log_iwrite(isc_lctx, category, module, level, - msgcat, msgset, message, - "socket %p %s: %s", sock, peerbuf, msgbuf); - } -} - -static void -wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) { - isc_socket_t *sock; - - /* - * This is a wakeup on a socket. If the socket is not in the - * process of being closed, start watching it for either reads - * or writes. - */ - - INSIST(fd >= 0 && fd < (int)FD_SETSIZE); - - if (manager->fdstate[fd] == CLOSE_PENDING) { - manager->fdstate[fd] = CLOSED; - FD_CLR(fd, &manager->read_fds); - FD_CLR(fd, &manager->write_fds); - (void)close(fd); - return; - } - if (manager->fdstate[fd] != MANAGED) - return; - - sock = manager->fds[fd]; - - /* - * Set requested bit. - */ - if (msg == SELECT_POKE_READ) - FD_SET(sock->fd, &manager->read_fds); - if (msg == SELECT_POKE_WRITE) - FD_SET(sock->fd, &manager->write_fds); -} - -#ifdef ISC_PLATFORM_USETHREADS -/* - * 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) { - int cc; - int buf[2]; - char strbuf[ISC_STRERRORSIZE]; - - buf[0] = fd; - buf[1] = msg; - - do { - cc = write(mgr->pipe_fds[1], buf, sizeof(buf)); -#ifdef ENOSR - /* - * Treat ENOSR as EAGAIN but loop slowly as it is - * unlikely to clear fast. - */ - if (cc < 0 && errno == ENOSR) { - sleep(1); - errno = EAGAIN; - } -#endif - } while (cc < 0 && SOFT_ERROR(errno)); - - if (cc < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - FATAL_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_WRITEFAILED, - "write() failed " - "during watcher poke: %s"), - strbuf); - } - - INSIST(cc == sizeof(buf)); -} - -/* - * Read a message on the internal fd. - */ -static void -select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) { - int buf[2]; - int cc; - char strbuf[ISC_STRERRORSIZE]; - - cc = read(mgr->pipe_fds[0], buf, sizeof(buf)); - if (cc < 0) { - *msg = SELECT_POKE_NOTHING; - *fd = -1; /* Silence compiler. */ - if (SOFT_ERROR(errno)) - return; - - isc__strerror(errno, strbuf, sizeof(strbuf)); - FATAL_ERROR(__FILE__, __LINE__, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_READFAILED, - "read() failed " - "during watcher poke: %s"), - strbuf); - - return; - } - INSIST(cc == sizeof(buf)); - - *fd = buf[0]; - *msg = buf[1]; -} -#else /* ISC_PLATFORM_USETHREADS */ -/* - * Update the state of the socketmgr when something changes. - */ -static void -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 */ - -/* - * Make a fd non-blocking. - */ -static isc_result_t -make_nonblock(int fd) { - int ret; - int flags; - char strbuf[ISC_STRERRORSIZE]; -#ifdef USE_FIONBIO_IOCTL - int on = 1; - - ret = ioctl(fd, FIONBIO, (char *)&on); -#else - flags = fcntl(fd, F_GETFL, 0); - flags |= PORT_NONBLOCK; - ret = fcntl(fd, F_SETFL, flags); -#endif - - if (ret == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, -#ifdef USE_FIONBIO_IOCTL - "ioctl(%d, FIONBIO, &on): %s", fd, -#else - "fcntl(%d, F_SETFL, %d): %s", fd, flags, -#endif - strbuf); - - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -#ifdef USE_CMSG -/* - * Not all OSes support advanced CMSG macros: CMSG_LEN and CMSG_SPACE. - * In order to ensure as much portability as possible, we provide wrapper - * functions of these macros. - * Note that cmsg_space() could run slow on OSes that do not have - * CMSG_SPACE. - */ -static inline ISC_SOCKADDR_LEN_T -cmsg_len(ISC_SOCKADDR_LEN_T len) { -#ifdef CMSG_LEN - return (CMSG_LEN(len)); -#else - ISC_SOCKADDR_LEN_T hdrlen; - - /* - * Cast NULL so that any pointer arithmetic performed by CMSG_DATA - * is correct. - */ - hdrlen = (ISC_SOCKADDR_LEN_T)CMSG_DATA(((struct cmsghdr *)NULL)); - return (hdrlen + len); -#endif -} - -static inline ISC_SOCKADDR_LEN_T -cmsg_space(ISC_SOCKADDR_LEN_T len) { -#ifdef CMSG_SPACE - return (CMSG_SPACE(len)); -#else - struct msghdr msg; - struct cmsghdr *cmsgp; - /* - * XXX: The buffer length is an ad-hoc value, but should be enough - * in a practical sense. - */ - char dummybuf[sizeof(struct cmsghdr) + 1024]; - - memset(&msg, 0, sizeof(msg)); - msg.msg_control = dummybuf; - msg.msg_controllen = sizeof(dummybuf); - - cmsgp = (struct cmsghdr *)dummybuf; - cmsgp->cmsg_len = cmsg_len(len); - - cmsgp = CMSG_NXTHDR(&msg, cmsgp); - if (cmsgp != NULL) - return ((char *)cmsgp - (char *)msg.msg_control); - else - return (0); -#endif -} -#endif /* USE_CMSG */ - -/* - * Process control messages received on a socket. - */ -static void -process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { -#ifdef USE_CMSG - struct cmsghdr *cmsgp; -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO - struct in6_pktinfo *pktinfop; -#endif -#ifdef SO_TIMESTAMP - struct timeval *timevalp; -#endif -#endif - - /* - * sock is used only when ISC_NET_BSD44MSGHDR and USE_CMSG are defined. - * msg and dev are used only when ISC_NET_BSD44MSGHDR is defined. - * They are all here, outside of the CPP tests, because it is - * more consistent with the usual ISC coding style. - */ - UNUSED(sock); - UNUSED(msg); - UNUSED(dev); - -#ifdef ISC_NET_BSD44MSGHDR - -#ifdef MSG_TRUNC - if ((msg->msg_flags & MSG_TRUNC) == MSG_TRUNC) - dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; -#endif - -#ifdef MSG_CTRUNC - if ((msg->msg_flags & MSG_CTRUNC) == MSG_CTRUNC) - dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC; -#endif - -#ifndef USE_CMSG - return; -#else - if (msg->msg_controllen == 0U || msg->msg_control == NULL) - return; - -#ifdef SO_TIMESTAMP - timevalp = NULL; -#endif -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO - pktinfop = NULL; -#endif - - cmsgp = CMSG_FIRSTHDR(msg); - while (cmsgp != NULL) { - socket_log(sock, NULL, TRACE, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PROCESSCMSG, - "processing cmsg %p", cmsgp); - -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO - if (cmsgp->cmsg_level == IPPROTO_IPV6 - && cmsgp->cmsg_type == IPV6_PKTINFO) { - - pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp); - memcpy(&dev->pktinfo, pktinfop, - sizeof(struct in6_pktinfo)); - dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO; - socket_log(sock, NULL, TRACE, - isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_IFRECEIVED, - "interface received on ifindex %u", - dev->pktinfo.ipi6_ifindex); - if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr)) - dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST; - goto next; - } -#endif - -#ifdef SO_TIMESTAMP - if (cmsgp->cmsg_level == SOL_SOCKET - && cmsgp->cmsg_type == SCM_TIMESTAMP) { - timevalp = (struct timeval *)CMSG_DATA(cmsgp); - dev->timestamp.seconds = timevalp->tv_sec; - dev->timestamp.nanoseconds = timevalp->tv_usec * 1000; - dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP; - goto next; - } -#endif - - next: - cmsgp = CMSG_NXTHDR(msg, cmsgp); - } -#endif /* USE_CMSG */ - -#endif /* ISC_NET_BSD44MSGHDR */ -} - -/* - * Construct an iov array and attach it to the msghdr passed in. This is - * the SEND constructor, which will use the used region of the buffer - * (if using a buffer list) or will use the internal region (if a single - * buffer I/O is requested). - * - * Nothing can be NULL, and the done event must list at least one buffer - * on the buffer linked list for this function to be meaningful. - * - * If write_countp != NULL, *write_countp will hold the number of bytes - * this transaction can send. - */ -static void -build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, - struct msghdr *msg, struct iovec *iov, size_t *write_countp) -{ - unsigned int iovcount; - isc_buffer_t *buffer; - isc_region_t used; - size_t write_count; - size_t skip_count; - - memset(msg, 0, sizeof(*msg)); - - if (sock->type == isc_sockettype_udp) { - msg->msg_name = (void *)&dev->address.type.sa; - msg->msg_namelen = dev->address.length; - } else { - msg->msg_name = NULL; - msg->msg_namelen = 0; - } - - buffer = ISC_LIST_HEAD(dev->bufferlist); - write_count = 0; - iovcount = 0; - - /* - * Single buffer I/O? Skip what we've done so far in this region. - */ - if (buffer == NULL) { - write_count = dev->region.length - dev->n; - iov[0].iov_base = (void *)(dev->region.base + dev->n); - iov[0].iov_len = write_count; - iovcount = 1; - - goto config; - } - - /* - * Multibuffer I/O. - * Skip the data in the buffer list that we have already written. - */ - skip_count = dev->n; - while (buffer != NULL) { - REQUIRE(ISC_BUFFER_VALID(buffer)); - if (skip_count < isc_buffer_usedlength(buffer)) - break; - skip_count -= isc_buffer_usedlength(buffer); - buffer = ISC_LIST_NEXT(buffer, link); - } - - while (buffer != NULL) { - INSIST(iovcount < MAXSCATTERGATHER_SEND); - - isc_buffer_usedregion(buffer, &used); - - if (used.length > 0) { - iov[iovcount].iov_base = (void *)(used.base - + skip_count); - iov[iovcount].iov_len = used.length - skip_count; - write_count += (used.length - skip_count); - skip_count = 0; - iovcount++; - } - buffer = ISC_LIST_NEXT(buffer, link); - } - - INSIST(skip_count == 0U); - - config: - msg->msg_iov = iov; - msg->msg_iovlen = iovcount; - -#ifdef ISC_NET_BSD44MSGHDR - msg->msg_control = NULL; - msg->msg_controllen = 0; - msg->msg_flags = 0; -#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) - if ((sock->type == isc_sockettype_udp) - && ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0)) { - struct cmsghdr *cmsgp; - struct in6_pktinfo *pktinfop; - - socket_log(sock, NULL, TRACE, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SENDTODATA, - "sendto pktinfo data, ifindex %u", - dev->pktinfo.ipi6_ifindex); - - msg->msg_controllen = cmsg_space(sizeof(struct in6_pktinfo)); - INSIST(msg->msg_controllen <= sock->sendcmsgbuflen); - msg->msg_control = (void *)sock->sendcmsgbuf; - - cmsgp = (struct cmsghdr *)sock->sendcmsgbuf; - cmsgp->cmsg_level = IPPROTO_IPV6; - cmsgp->cmsg_type = IPV6_PKTINFO; - cmsgp->cmsg_len = cmsg_len(sizeof(struct in6_pktinfo)); - pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp); - memcpy(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo)); - } -#endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */ -#else /* ISC_NET_BSD44MSGHDR */ - msg->msg_accrights = NULL; - msg->msg_accrightslen = 0; -#endif /* ISC_NET_BSD44MSGHDR */ - - if (write_countp != NULL) - *write_countp = write_count; -} - -/* - * Construct an iov array and attach it to the msghdr passed in. This is - * the RECV constructor, which will use the avialable region of the buffer - * (if using a buffer list) or will use the internal region (if a single - * buffer I/O is requested). - * - * Nothing can be NULL, and the done event must list at least one buffer - * on the buffer linked list for this function to be meaningful. - * - * If read_countp != NULL, *read_countp will hold the number of bytes - * this transaction can receive. - */ -static void -build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev, - struct msghdr *msg, struct iovec *iov, size_t *read_countp) -{ - unsigned int iovcount; - isc_buffer_t *buffer; - isc_region_t available; - size_t read_count; - - memset(msg, 0, sizeof(struct msghdr)); - - if (sock->type == isc_sockettype_udp) { - memset(&dev->address, 0, sizeof(dev->address)); - msg->msg_name = (void *)&dev->address.type.sa; - msg->msg_namelen = sizeof(dev->address.type); -#ifdef ISC_NET_RECVOVERFLOW - /* If needed, steal one iovec for overflow detection. */ - maxiov--; -#endif - } else { /* TCP */ - msg->msg_name = NULL; - msg->msg_namelen = 0; - dev->address = sock->address; - } - - buffer = ISC_LIST_HEAD(dev->bufferlist); - read_count = 0; - - /* - * Single buffer I/O? Skip what we've done so far in this region. - */ - if (buffer == NULL) { - read_count = dev->region.length - dev->n; - iov[0].iov_base = (void *)(dev->region.base + dev->n); - iov[0].iov_len = read_count; - iovcount = 1; - - goto config; - } - - /* - * Multibuffer I/O. - * Skip empty buffers. - */ - while (buffer != NULL) { - REQUIRE(ISC_BUFFER_VALID(buffer)); - if (isc_buffer_availablelength(buffer) != 0) - break; - buffer = ISC_LIST_NEXT(buffer, link); - } - - iovcount = 0; - while (buffer != NULL) { - INSIST(iovcount < MAXSCATTERGATHER_RECV); - - isc_buffer_availableregion(buffer, &available); - - if (available.length > 0) { - iov[iovcount].iov_base = (void *)(available.base); - iov[iovcount].iov_len = available.length; - read_count += available.length; - iovcount++; - } - buffer = ISC_LIST_NEXT(buffer, link); - } - - config: - - /* - * If needed, set up to receive that one extra byte. Note that - * we know there is at least one iov left, since we stole it - * at the top of this function. - */ -#ifdef ISC_NET_RECVOVERFLOW - if (sock->type == isc_sockettype_udp) { - iov[iovcount].iov_base = (void *)(&sock->overflow); - iov[iovcount].iov_len = 1; - iovcount++; - } -#endif - - msg->msg_iov = iov; - msg->msg_iovlen = iovcount; - -#ifdef ISC_NET_BSD44MSGHDR - msg->msg_control = NULL; - msg->msg_controllen = 0; - msg->msg_flags = 0; -#if defined(USE_CMSG) - if (sock->type == isc_sockettype_udp) { - msg->msg_control = sock->recvcmsgbuf; - msg->msg_controllen = sock->recvcmsgbuflen; - } -#endif /* USE_CMSG */ -#else /* ISC_NET_BSD44MSGHDR */ - msg->msg_accrights = NULL; - msg->msg_accrightslen = 0; -#endif /* ISC_NET_BSD44MSGHDR */ - - if (read_countp != NULL) - *read_countp = read_count; -} - -static void -set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock, - isc_socketevent_t *dev) -{ - if (sock->type == isc_sockettype_udp) { - if (address != NULL) - dev->address = *address; - else - dev->address = sock->address; - } else if (sock->type == isc_sockettype_tcp) { - INSIST(address == NULL); - dev->address = sock->address; - } -} - -static isc_socketevent_t * -allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype, - isc_taskaction_t action, const void *arg) -{ - isc_socketevent_t *ev; - - ev = (isc_socketevent_t *)isc_event_allocate(sock->manager->mctx, - sock, eventtype, - action, arg, - sizeof(*ev)); - - if (ev == NULL) - return (NULL); - - ev->result = ISC_R_UNEXPECTED; - ISC_LINK_INIT(ev, ev_link); - ISC_LIST_INIT(ev->bufferlist); - ev->region.base = NULL; - ev->n = 0; - ev->offset = 0; - ev->attributes = 0; - - return (ev); -} - -#if defined(ISC_SOCKET_DEBUG) -static void -dump_msg(struct msghdr *msg) { - unsigned int i; - - printf("MSGHDR %p\n", msg); - printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen); - printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen); - for (i = 0; i < (unsigned int)msg->msg_iovlen; i++) - printf("\t\t%d\tbase %p, len %d\n", i, - msg->msg_iov[i].iov_base, - msg->msg_iov[i].iov_len); -#ifdef ISC_NET_BSD44MSGHDR - printf("\tcontrol %p, controllen %d\n", msg->msg_control, - msg->msg_controllen); -#endif -} -#endif - -#define DOIO_SUCCESS 0 /* i/o ok, event sent */ -#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ -#define DOIO_HARD 2 /* i/o error, event sent */ -#define DOIO_EOF 3 /* EOF, no event sent */ - -static int -doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { - int cc; - struct iovec iov[MAXSCATTERGATHER_RECV]; - size_t read_count; - size_t actual_count; - struct msghdr msghdr; - isc_buffer_t *buffer; - int recv_errno; - char strbuf[ISC_STRERRORSIZE]; - - build_msghdr_recv(sock, dev, &msghdr, iov, &read_count); - -#if defined(ISC_SOCKET_DEBUG) - dump_msg(&msghdr); -#endif - - cc = recvmsg(sock->fd, &msghdr, 0); - recv_errno = errno; - - if (cc < 0) { - if (SOFT_ERROR(recv_errno)) - return (DOIO_SOFT); - - if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { - isc__strerror(recv_errno, strbuf, sizeof(strbuf)); - socket_log(sock, NULL, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_DOIORECV, - "doio_recv: recvmsg(%d) %d bytes, err %d/%s", - sock->fd, cc, recv_errno, strbuf); - } - -#define SOFT_OR_HARD(_system, _isc) \ - if (recv_errno == _system) { \ - if (sock->connected) { \ - dev->result = _isc; \ - return (DOIO_HARD); \ - } \ - return (DOIO_SOFT); \ - } -#define ALWAYS_HARD(_system, _isc) \ - if (recv_errno == _system) { \ - dev->result = _isc; \ - return (DOIO_HARD); \ - } - - SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); - SOFT_OR_HARD(ENETUNREACH, ISC_R_NETUNREACH); - SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); - SOFT_OR_HARD(EHOSTDOWN, ISC_R_HOSTDOWN); - /* HPUX 11.11 can return EADDRNOTAVAIL. */ - SOFT_OR_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); - ALWAYS_HARD(ENOBUFS, ISC_R_NORESOURCES); - -#undef SOFT_OR_HARD -#undef ALWAYS_HARD - - dev->result = isc__errno2result(recv_errno); - return (DOIO_HARD); - } - - /* - * On TCP, zero length reads indicate EOF, while on - * UDP, zero length reads are perfectly valid, although - * strange. - */ - if ((sock->type == isc_sockettype_tcp) && (cc == 0)) - return (DOIO_EOF); - - if (sock->type == isc_sockettype_udp) { - dev->address.length = msghdr.msg_namelen; - if (isc_sockaddr_getport(&dev->address) == 0) { - if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { - socket_log(sock, &dev->address, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_ZEROPORT, - "dropping source port zero packet"); - } - return (DOIO_SOFT); - } - } - - socket_log(sock, &dev->address, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PKTRECV, - "packet received correctly"); - - /* - * Overflow bit detection. If we received MORE bytes than we should, - * this indicates an overflow situation. Set the flag in the - * dev entry and adjust how much we read by one. - */ -#ifdef ISC_NET_RECVOVERFLOW - if ((sock->type == isc_sockettype_udp) && ((size_t)cc > read_count)) { - dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; - cc--; - } -#endif - - /* - * If there are control messages attached, run through them and pull - * out the interesting bits. - */ - if (sock->type == isc_sockettype_udp) - process_cmsg(sock, &msghdr, dev); - - /* - * update the buffers (if any) and the i/o count - */ - dev->n += cc; - actual_count = cc; - buffer = ISC_LIST_HEAD(dev->bufferlist); - while (buffer != NULL && actual_count > 0U) { - REQUIRE(ISC_BUFFER_VALID(buffer)); - if (isc_buffer_availablelength(buffer) <= actual_count) { - actual_count -= isc_buffer_availablelength(buffer); - isc_buffer_add(buffer, - isc_buffer_availablelength(buffer)); - } else { - isc_buffer_add(buffer, actual_count); - actual_count = 0; - break; - } - buffer = ISC_LIST_NEXT(buffer, link); - if (buffer == NULL) { - INSIST(actual_count == 0U); - } - } - - /* - * If we read less than we expected, update counters, - * and let the upper layer poke the descriptor. - */ - if (((size_t)cc != read_count) && (dev->n < dev->minimum)) - return (DOIO_SOFT); - - /* - * Full reads are posted, or partials if partials are ok. - */ - dev->result = ISC_R_SUCCESS; - return (DOIO_SUCCESS); -} - -/* - * Returns: - * DOIO_SUCCESS The operation succeeded. dev->result contains - * ISC_R_SUCCESS. - * - * DOIO_HARD A hard or unexpected I/O error was encountered. - * dev->result contains the appropriate error. - * - * DOIO_SOFT A soft I/O error was encountered. No senddone - * event was sent. The operation should be retried. - * - * No other return values are possible. - */ -static int -doio_send(isc_socket_t *sock, isc_socketevent_t *dev) { - int cc; - struct iovec iov[MAXSCATTERGATHER_SEND]; - size_t write_count; - struct msghdr msghdr; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - int attempts = 0; - int send_errno; - char strbuf[ISC_STRERRORSIZE]; - - build_msghdr_send(sock, dev, &msghdr, iov, &write_count); - - resend: - cc = sendmsg(sock->fd, &msghdr, 0); - send_errno = errno; - - /* - * Check for error or block condition. - */ - if (cc < 0) { - if (send_errno == EINTR && ++attempts < NRETRIES) - goto resend; - - if (SOFT_ERROR(send_errno)) - return (DOIO_SOFT); - -#define SOFT_OR_HARD(_system, _isc) \ - if (send_errno == _system) { \ - if (sock->connected) { \ - dev->result = _isc; \ - return (DOIO_HARD); \ - } \ - return (DOIO_SOFT); \ - } -#define ALWAYS_HARD(_system, _isc) \ - if (send_errno == _system) { \ - dev->result = _isc; \ - return (DOIO_HARD); \ - } - - SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); - ALWAYS_HARD(EACCES, ISC_R_NOPERM); - ALWAYS_HARD(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); - ALWAYS_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); - ALWAYS_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); -#ifdef EHOSTDOWN - ALWAYS_HARD(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif - ALWAYS_HARD(ENETUNREACH, ISC_R_NETUNREACH); - ALWAYS_HARD(ENOBUFS, ISC_R_NORESOURCES); - ALWAYS_HARD(EPERM, ISC_R_HOSTUNREACH); - ALWAYS_HARD(EPIPE, ISC_R_NOTCONNECTED); - ALWAYS_HARD(ECONNRESET, ISC_R_CONNECTIONRESET); - -#undef SOFT_OR_HARD -#undef ALWAYS_HARD - - /* - * The other error types depend on whether or not the - * socket is UDP or TCP. If it is UDP, some errors - * that we expect to be fatal under TCP are merely - * annoying, and are really soft errors. - * - * However, these soft errors are still returned as - * a status. - */ - isc_sockaddr_format(&dev->address, addrbuf, sizeof(addrbuf)); - isc__strerror(send_errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_send: %s: %s", - addrbuf, strbuf); - dev->result = isc__errno2result(send_errno); - return (DOIO_HARD); - } - - if (cc == 0) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_send: send() %s 0", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_RETURNED, "returned")); - - /* - * If we write less than we expected, update counters, poke. - */ - dev->n += cc; - if ((size_t)cc != write_count) - return (DOIO_SOFT); - - /* - * Exactly what we wanted to write. We're done with this - * entry. Post its completion event. - */ - dev->result = ISC_R_SUCCESS; - return (DOIO_SUCCESS); -} - -/* - * Kill. - * - * Caller must ensure that the socket is not locked and no external - * references exist. - */ -static void -destroy(isc_socket_t **sockp) { - 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"); - - INSIST(ISC_LIST_EMPTY(sock->accept_list)); - INSIST(ISC_LIST_EMPTY(sock->recv_list)); - INSIST(ISC_LIST_EMPTY(sock->send_list)); - INSIST(sock->connect_ev == NULL); - REQUIRE(sock->fd >= 0 && sock->fd < (int)FD_SETSIZE); - - LOCK(&manager->lock); - - /* - * No one has this socket open, so the watcher doesn't have to be - * poked, and the socket doesn't have to be locked. - */ - manager->fds[sock->fd] = NULL; - manager->fdstate[sock->fd] = CLOSE_PENDING; - select_poke(manager, sock->fd, SELECT_POKE_CLOSE); - ISC_LIST_UNLINK(manager->socklist, sock, link); - -#ifdef ISC_PLATFORM_USETHREADS - if (ISC_LIST_EMPTY(manager->socklist)) - SIGNAL(&manager->shutdown_ok); -#endif /* ISC_PLATFORM_USETHREADS */ - - /* - * XXX should reset manager->maxfd here - */ - - UNLOCK(&manager->lock); - - free_socket(sockp); -} - -static isc_result_t -allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, - isc_socket_t **socketp) -{ - isc_socket_t *sock; - isc_result_t ret; - ISC_SOCKADDR_LEN_T cmsgbuflen; - - sock = isc_mem_get(manager->mctx, sizeof(*sock)); - - if (sock == NULL) - return (ISC_R_NOMEMORY); - - ret = ISC_R_UNEXPECTED; - - sock->magic = 0; - sock->references = 0; - - sock->manager = manager; - sock->type = type; - sock->fd = -1; - - ISC_LINK_INIT(sock, link); - - sock->recvcmsgbuf = NULL; - sock->sendcmsgbuf = NULL; - - /* - * set up cmsg buffers - */ - cmsgbuflen = 0; -#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) - cmsgbuflen = cmsg_space(sizeof(struct in6_pktinfo)); -#endif -#if defined(USE_CMSG) && defined(SO_TIMESTAMP) - cmsgbuflen += cmsg_space(sizeof(struct timeval)); -#endif - sock->recvcmsgbuflen = cmsgbuflen; - if (sock->recvcmsgbuflen != 0U) { - sock->recvcmsgbuf = isc_mem_get(manager->mctx, cmsgbuflen); - if (sock->recvcmsgbuf == NULL) - goto error; - } - - cmsgbuflen = 0; -#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) - cmsgbuflen = cmsg_space(sizeof(struct in6_pktinfo)); -#endif - sock->sendcmsgbuflen = cmsgbuflen; - if (sock->sendcmsgbuflen != 0U) { - sock->sendcmsgbuf = isc_mem_get(manager->mctx, cmsgbuflen); - if (sock->sendcmsgbuf == NULL) - goto error; - } - - /* - * set up list of readers and writers to be initially empty - */ - ISC_LIST_INIT(sock->recv_list); - ISC_LIST_INIT(sock->send_list); - ISC_LIST_INIT(sock->accept_list); - sock->connect_ev = NULL; - sock->pending_recv = 0; - sock->pending_send = 0; - sock->pending_accept = 0; - sock->listener = 0; - sock->connected = 0; - sock->connecting = 0; - sock->bound = 0; - - /* - * initialize the lock - */ - if (isc_mutex_init(&sock->lock) != ISC_R_SUCCESS) { - sock->magic = 0; - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); - ret = ISC_R_UNEXPECTED; - goto error; - } - - /* - * Initialize readable and writable events - */ - ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t), - ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR, - NULL, sock, sock, NULL, NULL); - ISC_EVENT_INIT(&sock->writable_ev, sizeof(intev_t), - ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW, - NULL, sock, sock, NULL, NULL); - - sock->magic = SOCKET_MAGIC; - *socketp = sock; - - return (ISC_R_SUCCESS); - - error: - if (sock->recvcmsgbuf != NULL) - isc_mem_put(manager->mctx, sock->recvcmsgbuf, - sock->recvcmsgbuflen); - if (sock->sendcmsgbuf != NULL) - isc_mem_put(manager->mctx, sock->sendcmsgbuf, - sock->sendcmsgbuflen); - isc_mem_put(manager->mctx, sock, sizeof(*sock)); - - return (ret); -} - -/* - * This event requires that the various lists be empty, that the reference - * count be 1, and that the magic number is valid. The other socket bits, - * like the lock, must be initialized as well. The fd associated must be - * marked as closed, by setting it to -1 on close, or this routine will - * also close the socket. - */ -static void -free_socket(isc_socket_t **socketp) { - isc_socket_t *sock = *socketp; - - INSIST(sock->references == 0); - INSIST(VALID_SOCKET(sock)); - INSIST(!sock->connecting); - INSIST(!sock->pending_recv); - INSIST(!sock->pending_send); - INSIST(!sock->pending_accept); - INSIST(ISC_LIST_EMPTY(sock->recv_list)); - INSIST(ISC_LIST_EMPTY(sock->send_list)); - INSIST(ISC_LIST_EMPTY(sock->accept_list)); - INSIST(!ISC_LINK_LINKED(sock, link)); - - if (sock->recvcmsgbuf != NULL) - isc_mem_put(sock->manager->mctx, sock->recvcmsgbuf, - sock->recvcmsgbuflen); - if (sock->sendcmsgbuf != NULL) - isc_mem_put(sock->manager->mctx, sock->sendcmsgbuf, - sock->sendcmsgbuflen); - - sock->magic = 0; - - DESTROYLOCK(&sock->lock); - - isc_mem_put(sock->manager->mctx, sock, sizeof(*sock)); - - *socketp = NULL; -} - -/* - * Create a new 'type' socket managed by 'manager'. Events - * will be posted to 'task' and when dispatched 'action' will be - * 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_socket_t *sock = NULL; - isc_result_t ret; -#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) - int on = 1; -#endif - char strbuf[ISC_STRERRORSIZE]; - const char *err = "socket"; - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(socketp != NULL && *socketp == NULL); - - ret = allocate_socket(manager, type, &sock); - if (ret != ISC_R_SUCCESS) - return (ret); - - sock->pf = pf; - switch (type) { - case isc_sockettype_udp: - sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP); - break; - case isc_sockettype_tcp: - sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP); - break; - } - -#ifdef F_DUPFD - /* - * Leave a space for stdio to work in. - */ - if (sock->fd >= 0 && sock->fd < 20) { - int new, tmp; - new = fcntl(sock->fd, F_DUPFD, 20); - tmp = errno; - (void)close(sock->fd); - errno = tmp; - sock->fd = new; - err = "isc_socket_create: fcntl"; - } -#endif - - if (sock->fd >= (int)FD_SETSIZE) { - (void)close(sock->fd); - isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_TOOMANYFDS, - "%s: too many open file descriptors", "socket"); - free_socket(&sock); - return (ISC_R_NORESOURCES); - } - - if (sock->fd < 0) { - free_socket(&sock); - - switch (errno) { - case EMFILE: - case ENFILE: - case ENOBUFS: - return (ISC_R_NORESOURCES); - - case EPROTONOSUPPORT: - case EPFNOSUPPORT: - case EAFNOSUPPORT: - /* - * Linux 2.2 (and maybe others) return EINVAL instead of - * EAFNOSUPPORT. - */ - case EINVAL: - return (ISC_R_FAMILYNOSUPPORT); - - default: - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s() %s: %s", err, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - return (ISC_R_UNEXPECTED); - } - } - - if (make_nonblock(sock->fd) != ISC_R_SUCCESS) { - (void)close(sock->fd); - free_socket(&sock); - return (ISC_R_UNEXPECTED); - } - -#ifdef SO_BSDCOMPAT - if (setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT, - (void *)&on, sizeof(on)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_BSDCOMPAT) %s: %s", - sock->fd, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed"), - strbuf); - /* Press on... */ - } -#endif - -#if defined(USE_CMSG) - if (type == isc_sockettype_udp) { - -#if defined(SO_TIMESTAMP) - if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP, - (void *)&on, sizeof(on)) < 0 - && errno != ENOPROTOOPT) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, SO_TIMESTAMP) %s: %s", - sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - /* Press on... */ - } -#endif /* SO_TIMESTAMP */ - -#if defined(ISC_PLATFORM_HAVEIPV6) - if (pf == AF_INET6 && sock->recvcmsgbuflen == 0U) { - /* - * Warn explicitly because this anomaly can be hidden - * in usual operation (and unexpectedly appear later). - */ - UNEXPECTED_ERROR(__FILE__, __LINE__, - "No buffer available to receive " - "IPv6 destination"); - } -#ifdef ISC_PLATFORM_HAVEIN6PKTINFO -#ifdef IPV6_RECVPKTINFO - /* 2292bis */ - if ((pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, - (void *)&on, sizeof(on)) < 0)) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_RECVPKTINFO) " - "%s: %s", sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#else - /* 2292 */ - if ((pf == AF_INET6) - && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, - (void *)&on, sizeof(on)) < 0)) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_PKTINFO) %s: %s", - sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#endif /* IPV6_RECVPKTINFO */ -#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/ - /* use minimum MTU */ - if (pf == AF_INET6) { - (void)setsockopt(sock->fd, IPPROTO_IPV6, - IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)); - } -#endif -#endif /* ISC_PLATFORM_HAVEIPV6 */ - - } -#endif /* USE_CMSG */ - - sock->references = 1; - *socketp = sock; - - LOCK(&manager->lock); - - /* - * Note we don't have to lock the socket like we normally would because - * there are no external references to it yet. - */ - - manager->fds[sock->fd] = sock; - manager->fdstate[sock->fd] = MANAGED; - ISC_LIST_APPEND(manager->socklist, sock, link); - if (manager->maxfd < sock->fd) - manager->maxfd = sock->fd; - - UNLOCK(&manager->lock); - - socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_CREATED, "created"); - - 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) { - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(socketp != NULL && *socketp == NULL); - - LOCK(&sock->lock); - sock->references++; - UNLOCK(&sock->lock); - - *socketp = 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_boolean_t kill_socket = ISC_FALSE; - - REQUIRE(socketp != NULL); - sock = *socketp; - REQUIRE(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - REQUIRE(sock->references > 0); - sock->references--; - if (sock->references == 0) - kill_socket = ISC_TRUE; - UNLOCK(&sock->lock); - - if (kill_socket) - destroy(&sock); - - *socketp = NULL; -} - -/* - * I/O is possible on a given socket. Schedule an event to this task that - * will call an internal function to do the I/O. This will charge the - * task with the I/O operation and let our select loop handler get back - * to doing something real as fast as possible. - * - * The socket and manager must be locked before calling this function. - */ -static void -dispatch_recv(isc_socket_t *sock) { - intev_t *iev; - isc_socketevent_t *ev; - - INSIST(!sock->pending_recv); - - ev = ISC_LIST_HEAD(sock->recv_list); - if (ev == NULL) - return; - - sock->pending_recv = 1; - iev = &sock->readable_ev; - - socket_log(sock, NULL, EVENT, NULL, 0, 0, - "dispatch_recv: event %p -> task %p", ev, ev->ev_sender); - - sock->references++; - iev->ev_sender = sock; - iev->ev_action = internal_recv; - iev->ev_arg = sock; - - isc_task_send(ev->ev_sender, (isc_event_t **)&iev); -} - -static void -dispatch_send(isc_socket_t *sock) { - intev_t *iev; - isc_socketevent_t *ev; - - INSIST(!sock->pending_send); - - ev = ISC_LIST_HEAD(sock->send_list); - if (ev == NULL) - return; - - sock->pending_send = 1; - iev = &sock->writable_ev; - - socket_log(sock, NULL, EVENT, NULL, 0, 0, - "dispatch_send: event %p -> task %p", ev, ev->ev_sender); - - sock->references++; - iev->ev_sender = sock; - iev->ev_action = internal_send; - iev->ev_arg = sock; - - isc_task_send(ev->ev_sender, (isc_event_t **)&iev); -} - -/* - * Dispatch an internal accept event. - */ -static void -dispatch_accept(isc_socket_t *sock) { - intev_t *iev; - isc_socket_newconnev_t *ev; - - INSIST(!sock->pending_accept); - - /* - * Are there any done events left, or were they all canceled - * before the manager got the socket lock? - */ - ev = ISC_LIST_HEAD(sock->accept_list); - if (ev == NULL) - return; - - sock->pending_accept = 1; - iev = &sock->readable_ev; - - sock->references++; /* keep socket around for this internal event */ - iev->ev_sender = sock; - iev->ev_action = internal_accept; - iev->ev_arg = sock; - - isc_task_send(ev->ev_sender, (isc_event_t **)&iev); -} - -static void -dispatch_connect(isc_socket_t *sock) { - intev_t *iev; - isc_socket_connev_t *ev; - - iev = &sock->writable_ev; - - ev = sock->connect_ev; - INSIST(ev != NULL); /* XXX */ - - INSIST(sock->connecting); - - sock->references++; /* keep socket around for this internal event */ - iev->ev_sender = sock; - iev->ev_action = internal_connect; - iev->ev_arg = sock; - - isc_task_send(ev->ev_sender, (isc_event_t **)&iev); -} - -/* - * Dequeue an item off the given socket's read queue, set the result code - * in the done event to the one provided, and send it to the task it was - * destined for. - * - * If the event to be sent is on a list, remove it before sending. If - * asked to, send and detach from the socket as well. - * - * 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) { - isc_task_t *task; - - task = (*dev)->ev_sender; - - (*dev)->ev_sender = sock; - - if (ISC_LINK_LINKED(*dev, ev_link)) - ISC_LIST_DEQUEUE(sock->recv_list, *dev, ev_link); - - if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) - == ISC_SOCKEVENTATTR_ATTACHED) - isc_task_sendanddetach(&task, (isc_event_t **)dev); - else - isc_task_send(task, (isc_event_t **)dev); -} - -/* - * See comments for send_recvdone_event() above. - * - * 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) { - isc_task_t *task; - - INSIST(dev != NULL && *dev != NULL); - - task = (*dev)->ev_sender; - (*dev)->ev_sender = sock; - - if (ISC_LINK_LINKED(*dev, ev_link)) - ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link); - - if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) - == ISC_SOCKEVENTATTR_ATTACHED) - isc_task_sendanddetach(&task, (isc_event_t **)dev); - else - isc_task_send(task, (isc_event_t **)dev); -} - -/* - * Call accept() on a socket, to get the new file descriptor. The listen - * socket is used as a prototype to create a new isc_socket_t. The new - * socket has one outstanding reference. The task receiving the event - * will be detached from just after the event is delivered. - * - * On entry to this function, the event delivered is the internal - * readable event, and the first item on the accept_list should be - * the done event we want to send. If the list is empty, this is a no-op, - * so just unlock and return. - */ -static void -internal_accept(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; - isc_socketmgr_t *manager; - isc_socket_newconnev_t *dev; - isc_task_t *task; - ISC_SOCKADDR_LEN_T addrlen; - int fd; - isc_result_t result = ISC_R_SUCCESS; - char strbuf[ISC_STRERRORSIZE]; - const char *err = "accept"; - - UNUSED(me); - - sock = ev->ev_sender; - INSIST(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - socket_log(sock, NULL, TRACE, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, - "internal_accept called, locked socket"); - - manager = sock->manager; - INSIST(VALID_MANAGER(manager)); - - INSIST(sock->listener); - INSIST(sock->pending_accept == 1); - sock->pending_accept = 0; - - INSIST(sock->references > 0); - sock->references--; /* the internal event is done with this socket */ - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); - return; - } - - /* - * Get the first item off the accept list. - * If it is empty, unlock the socket and return. - */ - dev = ISC_LIST_HEAD(sock->accept_list); - if (dev == NULL) { - UNLOCK(&sock->lock); - return; - } - - /* - * Try to accept the new connection. If the accept fails with - * EAGAIN or EINTR, simply poke the watcher to watch this socket - * again. Also ignore ECONNRESET, which has been reported to - * be spuriously returned on Linux 2.2.19 although it is not - * a documented error for accept(). ECONNABORTED has been - * reported for Solaris 8. The rest are thrown in not because - * we have seen them but because they are ignored by other - * deamons such as BIND 8 and Apache. - */ - - addrlen = sizeof(dev->newsocket->address.type); - memset(&dev->newsocket->address.type.sa, 0, addrlen); - fd = accept(sock->fd, &dev->newsocket->address.type.sa, - (void *)&addrlen); - -#ifdef F_DUPFD - /* - * Leave a space for stdio to work in. - */ - if (fd >= 0 && fd < 20) { - int new, tmp; - new = fcntl(fd, F_DUPFD, 20); - tmp = errno; - (void)close(fd); - errno = tmp; - fd = new; - err = "fcntl"; - } -#endif - - if (fd < 0) { - if (SOFT_ERROR(errno)) - goto soft_error; - switch (errno) { - case ENOBUFS: - case ENFILE: - case ENOMEM: - case ECONNRESET: - case ECONNABORTED: - case EHOSTUNREACH: - case EHOSTDOWN: - case ENETUNREACH: - case ENETDOWN: - case ECONNREFUSED: -#ifdef EPROTO - case EPROTO: -#endif -#ifdef ENONET - case ENONET: -#endif - goto soft_error; - default: - break; - } - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_accept: %s() %s: %s", err, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - fd = -1; - result = ISC_R_UNEXPECTED; - } else { - if (addrlen == 0U) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_accept(): " - "accept() failed to return " - "remote address"); - - (void)close(fd); - goto soft_error; - } else if (dev->newsocket->address.type.sa.sa_family != - sock->pf) - { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_accept(): " - "accept() returned peer address " - "family %u (expected %u)", - dev->newsocket->address. - type.sa.sa_family, - sock->pf); - (void)close(fd); - goto soft_error; - } else if (fd >= (int)FD_SETSIZE) { - isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, - isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_TOOMANYFDS, - "%s: too many open file descriptors", - "accept"); - (void)close(fd); - goto soft_error; - } - } - - if (fd != -1) { - dev->newsocket->address.length = addrlen; - dev->newsocket->pf = sock->pf; - } - - /* - * Pull off the done event. - */ - ISC_LIST_UNLINK(sock->accept_list, dev, ev_link); - - /* - * Poke watcher if there are more pending accepts. - */ - if (!ISC_LIST_EMPTY(sock->accept_list)) - select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT); - - UNLOCK(&sock->lock); - - if (fd != -1 && (make_nonblock(fd) != ISC_R_SUCCESS)) { - (void)close(fd); - fd = -1; - result = ISC_R_UNEXPECTED; - } - - /* - * -1 means the new socket didn't happen. - */ - if (fd != -1) { - LOCK(&manager->lock); - ISC_LIST_APPEND(manager->socklist, dev->newsocket, link); - - dev->newsocket->fd = fd; - dev->newsocket->bound = 1; - dev->newsocket->connected = 1; - - /* - * Save away the remote address - */ - dev->address = dev->newsocket->address; - - manager->fds[fd] = dev->newsocket; - manager->fdstate[fd] = MANAGED; - if (manager->maxfd < fd) - manager->maxfd = fd; - - socket_log(sock, &dev->newsocket->address, CREATION, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN, - "accepted connection, new socket %p", - dev->newsocket); - - UNLOCK(&manager->lock); - } else { - dev->newsocket->references--; - free_socket(&dev->newsocket); - } - - /* - * Fill in the done event details and send it off. - */ - dev->result = result; - task = dev->ev_sender; - dev->ev_sender = sock; - - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev)); - return; - - soft_error: - select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT); - UNLOCK(&sock->lock); - return; -} - -static void -internal_recv(isc_task_t *me, isc_event_t *ev) { - isc_socketevent_t *dev; - isc_socket_t *sock; - - INSIST(ev->ev_type == ISC_SOCKEVENT_INTR); - - sock = ev->ev_sender; - INSIST(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - socket_log(sock, NULL, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, - "internal_recv: task %p got event %p", me, ev); - - INSIST(sock->pending_recv == 1); - sock->pending_recv = 0; - - INSIST(sock->references > 0); - sock->references--; /* the internal event is done with this socket */ - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); - return; - } - - /* - * Try to do as much I/O as possible on this socket. There are no - * limits here, currently. - */ - dev = ISC_LIST_HEAD(sock->recv_list); - while (dev != NULL) { - switch (doio_recv(sock, dev)) { - case DOIO_SOFT: - goto poke; - - case DOIO_EOF: - /* - * read of 0 means the remote end was closed. - * Run through the event queue and dispatch all - * the events with an EOF result code. - */ - do { - dev->result = ISC_R_EOF; - send_recvdone_event(sock, &dev); - dev = ISC_LIST_HEAD(sock->recv_list); - } while (dev != NULL); - goto poke; - - case DOIO_SUCCESS: - case DOIO_HARD: - send_recvdone_event(sock, &dev); - break; - } - - dev = ISC_LIST_HEAD(sock->recv_list); - } - - poke: - if (!ISC_LIST_EMPTY(sock->recv_list)) - select_poke(sock->manager, sock->fd, SELECT_POKE_READ); - - UNLOCK(&sock->lock); -} - -static void -internal_send(isc_task_t *me, isc_event_t *ev) { - isc_socketevent_t *dev; - 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; - INSIST(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - socket_log(sock, NULL, IOEVENT, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND, - "internal_send: task %p got event %p", me, ev); - - INSIST(sock->pending_send == 1); - sock->pending_send = 0; - - INSIST(sock->references > 0); - sock->references--; /* the internal event is done with this socket */ - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); - return; - } - - /* - * Try to do as much I/O as possible on this socket. There are no - * limits here, currently. - */ - dev = ISC_LIST_HEAD(sock->send_list); - while (dev != NULL) { - switch (doio_send(sock, dev)) { - case DOIO_SOFT: - goto poke; - - case DOIO_HARD: - case DOIO_SUCCESS: - send_senddone_event(sock, &dev); - break; - } - - dev = ISC_LIST_HEAD(sock->send_list); - } - - poke: - if (!ISC_LIST_EMPTY(sock->send_list)) - select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); - - UNLOCK(&sock->lock); -} - -static void -process_fds(isc_socketmgr_t *manager, int maxfd, - fd_set *readfds, fd_set *writefds) -{ - int i; - isc_socket_t *sock; - isc_boolean_t unlock_sock; - - REQUIRE(maxfd <= (int)FD_SETSIZE); - - /* - * Process read/writes on other fds here. Avoid locking - * and unlocking twice if both reads and writes are possible. - */ - for (i = 0; i < maxfd; i++) { -#ifdef ISC_PLATFORM_USETHREADS - if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1]) - continue; -#endif /* ISC_PLATFORM_USETHREADS */ - - if (manager->fdstate[i] == CLOSE_PENDING) { - manager->fdstate[i] = CLOSED; - FD_CLR(i, &manager->read_fds); - FD_CLR(i, &manager->write_fds); - - (void)close(i); - - continue; - } - - sock = manager->fds[i]; - unlock_sock = ISC_FALSE; - if (FD_ISSET(i, readfds)) { - if (sock == NULL) { - FD_CLR(i, &manager->read_fds); - goto check_write; - } - unlock_sock = ISC_TRUE; - LOCK(&sock->lock); - if (!SOCK_DEAD(sock)) { - if (sock->listener) - dispatch_accept(sock); - else - dispatch_recv(sock); - } - FD_CLR(i, &manager->read_fds); - } - check_write: - if (FD_ISSET(i, writefds)) { - if (sock == NULL) { - FD_CLR(i, &manager->write_fds); - continue; - } - if (!unlock_sock) { - unlock_sock = ISC_TRUE; - LOCK(&sock->lock); - } - if (!SOCK_DEAD(sock)) { - if (sock->connecting) - dispatch_connect(sock); - else - dispatch_send(sock); - } - FD_CLR(i, &manager->write_fds); - } - if (unlock_sock) - UNLOCK(&sock->lock); - } -} - -#ifdef ISC_PLATFORM_USETHREADS -/* - * This is the thread that will loop forever, always in a select or poll - * call. - * - * When select returns something to do, track down what thread gets to do - * this I/O and post the event to it. - */ -static isc_threadresult_t -watcher(void *uap) { - isc_socketmgr_t *manager = uap; - isc_boolean_t done; - int ctlfd; - int cc; - fd_set readfds; - fd_set writefds; - int msg, fd; - int maxfd; - char strbuf[ISC_STRERRORSIZE]; - - /* - * Get the control fd here. This will never change. - */ - LOCK(&manager->lock); - ctlfd = manager->pipe_fds[0]; - - done = ISC_FALSE; - while (!done) { - do { - readfds = manager->read_fds; - writefds = manager->write_fds; - maxfd = manager->maxfd + 1; - - UNLOCK(&manager->lock); - - cc = select(maxfd, &readfds, &writefds, NULL, NULL); - if (cc < 0) { - if (!SOFT_ERROR(errno)) { - isc__strerror(errno, strbuf, - sizeof(strbuf)); - FATAL_ERROR(__FILE__, __LINE__, - "select() %s: %s", - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } - } - - LOCK(&manager->lock); - } while (cc < 0); - - - /* - * Process reads on internal, control fd. - */ - if (FD_ISSET(ctlfd, &readfds)) { - for (;;) { - select_readmsg(manager, &fd, &msg); - - manager_log(manager, IOEVENT, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_SOCKET, - ISC_MSG_WATCHERMSG, - "watcher got message %d"), - msg); - - /* - * Nothing to read? - */ - if (msg == SELECT_POKE_NOTHING) - break; - - /* - * Handle shutdown message. We really should - * jump out of this loop right away, but - * it doesn't matter if we have to do a little - * more work first. - */ - if (msg == SELECT_POKE_SHUTDOWN) { - done = ISC_TRUE; - - break; - } - - /* - * This is a wakeup on a socket. Look - * at the event queue for both read and write, - * and decide if we need to watch on it now - * or not. - */ - wakeup_socket(manager, fd, msg); - } - } - - process_fds(manager, maxfd, &readfds, &writefds); - } - - manager_log(manager, TRACE, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_EXITING, "watcher exiting")); - - UNLOCK(&manager->lock); - return ((isc_threadresult_t)0); -} -#endif /* ISC_PLATFORM_USETHREADS */ - -/* - * Create a new socket manager. - */ -isc_result_t -isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { - isc_socketmgr_t *manager; -#ifdef ISC_PLATFORM_USETHREADS - char strbuf[ISC_STRERRORSIZE]; -#endif - - REQUIRE(managerp != NULL && *managerp == NULL); - -#ifndef ISC_PLATFORM_USETHREADS - if (socketmgr != NULL) { - socketmgr->refs++; - *managerp = socketmgr; - return (ISC_R_SUCCESS); - } -#endif /* ISC_PLATFORM_USETHREADS */ - - manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); - - manager->magic = SOCKET_MANAGER_MAGIC; - manager->mctx = NULL; - memset(manager->fds, 0, sizeof(manager->fds)); - ISC_LIST_INIT(manager->socklist); - if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) { - isc_mem_put(mctx, manager, sizeof(*manager)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); - return (ISC_R_UNEXPECTED); - } -#ifdef ISC_PLATFORM_USETHREADS - if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) { - DESTROYLOCK(&manager->lock); - isc_mem_put(mctx, manager, sizeof(*manager)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_condition_init() %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); - return (ISC_R_UNEXPECTED); - } - - /* - * Create the special fds that will be used to wake up the - * select/poll loop when something internal needs to be done. - */ - if (pipe(manager->pipe_fds) != 0) { - DESTROYLOCK(&manager->lock); - isc_mem_put(mctx, manager, sizeof(*manager)); - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "pipe() %s: %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed"), - strbuf); - - return (ISC_R_UNEXPECTED); - } - - RUNTIME_CHECK(make_nonblock(manager->pipe_fds[0]) == ISC_R_SUCCESS); -#if 0 - RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS); -#endif -#else /* ISC_PLATFORM_USETHREADS */ - manager->refs = 1; -#endif /* ISC_PLATFORM_USETHREADS */ - - /* - * Set up initial state for the select loop - */ - FD_ZERO(&manager->read_fds); - FD_ZERO(&manager->write_fds); -#ifdef ISC_PLATFORM_USETHREADS - FD_SET(manager->pipe_fds[0], &manager->read_fds); - manager->maxfd = manager->pipe_fds[0]; -#else /* ISC_PLATFORM_USETHREADS */ - manager->maxfd = 0; -#endif /* ISC_PLATFORM_USETHREADS */ - memset(manager->fdstate, 0, sizeof(manager->fdstate)); - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Start up the select/poll thread. - */ - if (isc_thread_create(watcher, manager, &manager->watcher) != - ISC_R_SUCCESS) { - (void)close(manager->pipe_fds[0]); - (void)close(manager->pipe_fds[1]); - DESTROYLOCK(&manager->lock); - isc_mem_put(mctx, manager, sizeof(*manager)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_thread_create() %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); - return (ISC_R_UNEXPECTED); - } -#endif /* ISC_PLATFORM_USETHREADS */ - isc_mem_attach(mctx, &manager->mctx); - -#ifndef ISC_PLATFORM_USETHREADS - socketmgr = manager; -#endif /* ISC_PLATFORM_USETHREADS */ - *managerp = manager; - - return (ISC_R_SUCCESS); -} - -void -isc_socketmgr_destroy(isc_socketmgr_t **managerp) { - isc_socketmgr_t *manager; - int i; - isc_mem_t *mctx; - - /* - * Destroy a socket manager. - */ - - REQUIRE(managerp != NULL); - manager = *managerp; - REQUIRE(VALID_MANAGER(manager)); - -#ifndef ISC_PLATFORM_USETHREADS - if (manager->refs > 1) { - manager->refs--; - *managerp = NULL; - return; - } -#endif /* ISC_PLATFORM_USETHREADS */ - - LOCK(&manager->lock); - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Wait for all sockets to be destroyed. - */ - while (!ISC_LIST_EMPTY(manager->socklist)) { - manager_log(manager, CREATION, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_SOCKETSREMAIN, - "sockets exist")); - WAIT(&manager->shutdown_ok, &manager->lock); - } -#else /* ISC_PLATFORM_USETHREADS */ - /* - * Hope all sockets have been destroyed. - */ - if (!ISC_LIST_EMPTY(manager->socklist)) { - manager_log(manager, CREATION, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_SOCKETSREMAIN, - "sockets exist")); - INSIST(0); - } -#endif /* ISC_PLATFORM_USETHREADS */ - - UNLOCK(&manager->lock); - - /* - * Here, poke our select/poll thread. Do this by closing the write - * half of the pipe, which will send EOF to the read half. - * This is currently a no-op in the non-threaded case. - */ - select_poke(manager, 0, SELECT_POKE_SHUTDOWN); - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Wait for thread to exit. - */ - if (isc_thread_join(manager->watcher, NULL) != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_thread_join() %s", - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); -#endif /* ISC_PLATFORM_USETHREADS */ - - /* - * Clean up. - */ -#ifdef ISC_PLATFORM_USETHREADS - (void)close(manager->pipe_fds[0]); - (void)close(manager->pipe_fds[1]); - (void)isc_condition_destroy(&manager->shutdown_ok); -#endif /* ISC_PLATFORM_USETHREADS */ - - for (i = 0; i < (int)FD_SETSIZE; i++) - if (manager->fdstate[i] == CLOSE_PENDING) - (void)close(i); - - DESTROYLOCK(&manager->lock); - manager->magic = 0; - mctx= manager->mctx; - isc_mem_put(mctx, manager, sizeof(*manager)); - - isc_mem_detach(&mctx); - - *managerp = NULL; -} - -static isc_result_t -socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, - unsigned int flags) -{ - int io_state; - isc_boolean_t have_lock = ISC_FALSE; - isc_task_t *ntask = NULL; - isc_result_t result = ISC_R_SUCCESS; - - dev->ev_sender = task; - - if (sock->type == isc_sockettype_udp) { - io_state = doio_recv(sock, dev); - } else { - LOCK(&sock->lock); - have_lock = ISC_TRUE; - - if (ISC_LIST_EMPTY(sock->recv_list)) - io_state = doio_recv(sock, dev); - else - io_state = DOIO_SOFT; - } - - switch (io_state) { - case DOIO_SOFT: - /* - * We couldn't read all or part of the request right now, so - * queue it. - * - * Attach to socket and to task - */ - isc_task_attach(task, &ntask); - dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; - - if (!have_lock) { - LOCK(&sock->lock); - have_lock = ISC_TRUE; - } - - /* - * Enqueue the request. If the socket was previously not being - * watched, poke the watcher to start paying attention to it. - */ - if (ISC_LIST_EMPTY(sock->recv_list)) - select_poke(sock->manager, sock->fd, SELECT_POKE_READ); - ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link); - - socket_log(sock, NULL, EVENT, NULL, 0, 0, - "socket_recv: event %p -> task %p", - dev, ntask); - - if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) - result = ISC_R_INPROGRESS; - break; - - case DOIO_EOF: - dev->result = ISC_R_EOF; - /* fallthrough */ - - case DOIO_HARD: - case DOIO_SUCCESS: - if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0) - send_recvdone_event(sock, &dev); - break; - } - - if (have_lock) - UNLOCK(&sock->lock); - - 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_socketevent_t *dev; - isc_socketmgr_t *manager; - unsigned int iocount; - isc_buffer_t *buffer; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(buflist != NULL); - REQUIRE(!ISC_LIST_EMPTY(*buflist)); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - - iocount = isc_bufferlist_availablecount(buflist); - REQUIRE(iocount > 0); - - INSIST(sock->bound); - - dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg); - if (dev == NULL) { - return (ISC_R_NOMEMORY); - } - - /* - * UDP sockets are always partial read - */ - if (sock->type == isc_sockettype_udp) - dev->minimum = 1; - else { - if (minimum == 0) - dev->minimum = iocount; - else - dev->minimum = minimum; - } - - /* - * Move each buffer from the passed in list to our internal one. - */ - buffer = ISC_LIST_HEAD(*buflist); - while (buffer != NULL) { - ISC_LIST_DEQUEUE(*buflist, buffer, link); - ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); - buffer = ISC_LIST_HEAD(*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_socketevent_t *dev; - isc_socketmgr_t *manager; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(action != NULL); - - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - - INSIST(sock->bound); - - dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg); - if (dev == NULL) - return (ISC_R_NOMEMORY); - - return (isc_socket_recv2(sock, 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) -{ - event->ev_sender = sock; - event->result = ISC_R_UNEXPECTED; - ISC_LIST_INIT(event->bufferlist); - event->region = *region; - event->n = 0; - event->offset = 0; - event->attributes = 0; - - /* - * UDP sockets are always partial read. - */ - if (sock->type == isc_sockettype_udp) - event->minimum = 1; - else { - if (minimum == 0) - event->minimum = region->length; - else - event->minimum = minimum; - } - - return (socket_recv(sock, event, task, flags)); -} - -static isc_result_t -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) -{ - int io_state; - isc_boolean_t have_lock = ISC_FALSE; - isc_task_t *ntask = NULL; - isc_result_t result = ISC_R_SUCCESS; - - dev->ev_sender = task; - - set_dev_address(address, sock, dev); - if (pktinfo != NULL) { - dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO; - dev->pktinfo = *pktinfo; - - if (!isc_sockaddr_issitelocal(address) && - !isc_sockaddr_islinklocal(address)) { - socket_log(sock, NULL, TRACE, isc_msgcat, - ISC_MSGSET_SOCKET, ISC_MSG_PKTINFOPROVIDED, - "pktinfo structure provided, ifindex %u " - "(set to 0)", pktinfo->ipi6_ifindex); - - /* - * Set the pktinfo index to 0 here, to let the - * kernel decide what interface it should send on. - */ - dev->pktinfo.ipi6_ifindex = 0; - } - } - - if (sock->type == isc_sockettype_udp) - io_state = doio_send(sock, dev); - else { - LOCK(&sock->lock); - have_lock = ISC_TRUE; - - if (ISC_LIST_EMPTY(sock->send_list)) - io_state = doio_send(sock, dev); - else - io_state = DOIO_SOFT; - } - - switch (io_state) { - case DOIO_SOFT: - /* - * We couldn't send all or part of the request right now, so - * queue it unless ISC_SOCKFLAG_NORETRY is set. - */ - if ((flags & ISC_SOCKFLAG_NORETRY) == 0) { - isc_task_attach(task, &ntask); - dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; - - if (!have_lock) { - LOCK(&sock->lock); - have_lock = ISC_TRUE; - } - - /* - * Enqueue the request. If the socket was previously - * not being watched, poke the watcher to start - * paying attention to it. - */ - if (ISC_LIST_EMPTY(sock->send_list)) - select_poke(sock->manager, sock->fd, - SELECT_POKE_WRITE); - ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link); - - socket_log(sock, NULL, EVENT, NULL, 0, 0, - "socket_send: event %p -> task %p", - dev, ntask); - - if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) - result = ISC_R_INPROGRESS; - break; - } - - case DOIO_HARD: - case DOIO_SUCCESS: - if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0) - send_senddone_event(sock, &dev); - break; - } - - if (have_lock) - UNLOCK(&sock->lock); - - 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) -{ - /* - * REQUIRE() checking is performed in isc_socket_sendto(). - */ - 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_socketevent_t *dev; - isc_socketmgr_t *manager; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(region != NULL); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - - INSIST(sock->bound); - - dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg); - if (dev == NULL) { - return (ISC_R_NOMEMORY); - } - - dev->region = *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) -{ - 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_socketevent_t *dev; - isc_socketmgr_t *manager; - unsigned int iocount; - isc_buffer_t *buffer; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(buflist != NULL); - REQUIRE(!ISC_LIST_EMPTY(*buflist)); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - - iocount = isc_bufferlist_usedcount(buflist); - REQUIRE(iocount > 0); - - dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg); - if (dev == NULL) { - return (ISC_R_NOMEMORY); - } - - /* - * Move each buffer from the passed in list to our internal one. - */ - buffer = ISC_LIST_HEAD(*buflist); - while (buffer != NULL) { - ISC_LIST_DEQUEUE(*buflist, buffer, link); - ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); - buffer = ISC_LIST_HEAD(*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) -{ - REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0); - if ((flags & ISC_SOCKFLAG_NORETRY) != 0) - REQUIRE(sock->type == isc_sockettype_udp); - event->ev_sender = sock; - event->result = ISC_R_UNEXPECTED; - ISC_LIST_INIT(event->bufferlist); - event->region = *region; - event->n = 0; - event->offset = 0; - event->attributes = 0; - - return (socket_send(sock, event, task, address, pktinfo, flags)); -} - -isc_result_t -isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) { - char strbuf[ISC_STRERRORSIZE]; - int on = 1; - - LOCK(&sock->lock); - - INSIST(!sock->bound); - - if (sock->pf != sockaddr->type.sa.sa_family) { - UNLOCK(&sock->lock); - return (ISC_R_FAMILYMISMATCH); - } - /* - * Only set SO_REUSEADDR when we want a specific port. - */ - if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 && - setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, - sizeof(on)) < 0) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d) %s", sock->fd, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, "failed")); - /* Press on... */ - } - if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) { - UNLOCK(&sock->lock); - switch (errno) { - case EACCES: - return (ISC_R_NOPERM); - case EADDRNOTAVAIL: - return (ISC_R_ADDRNOTAVAIL); - case EADDRINUSE: - return (ISC_R_ADDRINUSE); - case EINVAL: - return (ISC_R_BOUND); - default: - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s", - strbuf); - return (ISC_R_UNEXPECTED); - } - } - - socket_log(sock, sockaddr, TRACE, - isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound"); - sock->bound = 1; - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_socket_filter(isc_socket_t *sock, const char *filter) { -#ifdef SO_ACCEPTFILTER - char strbuf[ISC_STRERRORSIZE]; - struct accept_filter_arg afa; -#else - UNUSED(sock); - UNUSED(filter); -#endif - - REQUIRE(VALID_SOCKET(sock)); - -#ifdef SO_ACCEPTFILTER - bzero(&afa, sizeof(afa)); - strncpy(afa.af_name, filter, sizeof(afa.af_name)); - if (setsockopt(sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, - &afa, sizeof(afa)) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_FILTER, "setsockopt(SO_ACCEPTFILTER): %s", - strbuf); - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#else - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -/* - * Set up to listen on a given socket. We do this by creating an internal - * event that will be dispatched when the socket has read activity. The - * watcher will send the internal event to the task when there is a new - * connection. - * - * Unlike in read, we don't preallocate a done event here. Every time there - * 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) { - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - - REQUIRE(!sock->listener); - REQUIRE(sock->bound); - REQUIRE(sock->type == isc_sockettype_tcp); - - if (backlog == 0) - backlog = SOMAXCONN; - - if (listen(sock->fd, (int)backlog) < 0) { - UNLOCK(&sock->lock); - isc__strerror(errno, strbuf, sizeof(strbuf)); - - UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf); - - return (ISC_R_UNEXPECTED); - } - - sock->listener = 1; - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); -} - -/* - * This should try to do agressive accept() XXXMLG - */ -isc_result_t -isc_socket_accept(isc_socket_t *sock, - isc_task_t *task, isc_taskaction_t action, const void *arg) -{ - isc_socket_newconnev_t *dev; - isc_socketmgr_t *manager; - isc_task_t *ntask = NULL; - isc_socket_t *nsock; - isc_result_t ret; - isc_boolean_t do_poke = ISC_FALSE; - - REQUIRE(VALID_SOCKET(sock)); - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - - LOCK(&sock->lock); - - REQUIRE(sock->listener); - - /* - * Sender field is overloaded here with the task we will be sending - * this event to. Just before the actual event is delivered the - * actual ev_sender will be touched up to be the socket. - */ - dev = (isc_socket_newconnev_t *) - isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN, - action, arg, sizeof(*dev)); - if (dev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } - ISC_LINK_INIT(dev, ev_link); - - ret = allocate_socket(manager, sock->type, &nsock); - if (ret != ISC_R_SUCCESS) { - isc_event_free(ISC_EVENT_PTR(&dev)); - UNLOCK(&sock->lock); - return (ret); - } - - /* - * Attach to socket and to task. - */ - isc_task_attach(task, &ntask); - nsock->references++; - - dev->ev_sender = ntask; - dev->newsocket = nsock; - - /* - * Poke watcher here. We still have the socket locked, so there - * is no race condition. We will keep the lock for such a short - * bit of time waking it up now or later won't matter all that much. - */ - if (ISC_LIST_EMPTY(sock->accept_list)) - do_poke = ISC_TRUE; - - ISC_LIST_ENQUEUE(sock->accept_list, dev, ev_link); - - if (do_poke) - select_poke(manager, sock->fd, SELECT_POKE_ACCEPT); - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); -} - -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_socket_connev_t *dev; - isc_task_t *ntask = NULL; - isc_socketmgr_t *manager; - int cc; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(addr != NULL); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - - manager = sock->manager; - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(addr != NULL); - - if (isc_sockaddr_ismulticast(addr)) - return (ISC_R_MULTICAST); - - LOCK(&sock->lock); - - REQUIRE(!sock->connecting); - - dev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock, - ISC_SOCKEVENT_CONNECT, - action, arg, - sizeof(*dev)); - if (dev == NULL) { - UNLOCK(&sock->lock); - return (ISC_R_NOMEMORY); - } - ISC_LINK_INIT(dev, ev_link); - - /* - * Try to do the connect right away, as there can be only one - * outstanding, and it might happen to complete. - */ - sock->address = *addr; - cc = connect(sock->fd, &addr->type.sa, addr->length); - if (cc < 0) { - if (SOFT_ERROR(errno) || errno == EINPROGRESS) - goto queue; - - switch (errno) { -#define ERROR_MATCH(a, b) case a: dev->result = b; goto err_exit; - ERROR_MATCH(EACCES, ISC_R_NOPERM); - ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); - ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); - ERROR_MATCH(ECONNREFUSED, ISC_R_CONNREFUSED); - ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); -#ifdef EHOSTDOWN - ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif - ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); - ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); - ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); - ERROR_MATCH(EPIPE, ISC_R_NOTCONNECTED); - ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET); -#undef ERROR_MATCH - } - - sock->connected = 0; - - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s", errno, strbuf); - - UNLOCK(&sock->lock); - isc_event_free(ISC_EVENT_PTR(&dev)); - return (ISC_R_UNEXPECTED); - - err_exit: - sock->connected = 0; - isc_task_send(task, ISC_EVENT_PTR(&dev)); - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); - } - - /* - * If connect completed, fire off the done event. - */ - if (cc == 0) { - sock->connected = 1; - sock->bound = 1; - dev->result = ISC_R_SUCCESS; - isc_task_send(task, ISC_EVENT_PTR(&dev)); - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); - } - - queue: - - /* - * Attach to task. - */ - isc_task_attach(task, &ntask); - - sock->connecting = 1; - - dev->ev_sender = ntask; - - /* - * Poke watcher here. We still have the socket locked, so there - * is no race condition. We will keep the lock for such a short - * bit of time waking it up now or later won't matter all that much. - */ - if (sock->connect_ev == NULL) - select_poke(manager, sock->fd, SELECT_POKE_CONNECT); - - sock->connect_ev = dev; - - UNLOCK(&sock->lock); - return (ISC_R_SUCCESS); -} - -/* - * Called when a socket with a pending connect() finishes. - */ -static void -internal_connect(isc_task_t *me, isc_event_t *ev) { - isc_socket_t *sock; - isc_socket_connev_t *dev; - isc_task_t *task; - int cc; - ISC_SOCKADDR_LEN_T optlen; - char strbuf[ISC_STRERRORSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - - UNUSED(me); - INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); - - sock = ev->ev_sender; - INSIST(VALID_SOCKET(sock)); - - LOCK(&sock->lock); - - /* - * When the internal event was sent the reference count was bumped - * to keep the socket around for us. Decrement the count here. - */ - INSIST(sock->references > 0); - sock->references--; - if (sock->references == 0) { - UNLOCK(&sock->lock); - destroy(&sock); - return; - } - - /* - * Has this event been canceled? - */ - dev = sock->connect_ev; - if (dev == NULL) { - INSIST(!sock->connecting); - UNLOCK(&sock->lock); - return; - } - - INSIST(sock->connecting); - sock->connecting = 0; - - /* - * Get any possible error status here. - */ - optlen = sizeof(cc); - if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, - (void *)&cc, (void *)&optlen) < 0) - cc = errno; - else - errno = cc; - - if (errno != 0) { - /* - * If the error is EAGAIN, just re-select on this - * fd and pretend nothing strange happened. - */ - if (SOFT_ERROR(errno) || errno == EINPROGRESS) { - sock->connecting = 1; - select_poke(sock->manager, sock->fd, - SELECT_POKE_CONNECT); - UNLOCK(&sock->lock); - - return; - } - - /* - * Translate other errors into ISC_R_* flavors. - */ - switch (errno) { -#define ERROR_MATCH(a, b) case a: dev->result = b; break; - ERROR_MATCH(EACCES, ISC_R_NOPERM); - ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); - ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); - ERROR_MATCH(ECONNREFUSED, ISC_R_CONNREFUSED); - ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); -#ifdef EHOSTDOWN - ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); -#endif - ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); - ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); - ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); - ERROR_MATCH(EPIPE, ISC_R_NOTCONNECTED); - ERROR_MATCH(ETIMEDOUT, ISC_R_TIMEDOUT); - ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET); -#undef ERROR_MATCH - default: - dev->result = ISC_R_UNEXPECTED; - isc_sockaddr_format(&sock->address, peerbuf, - sizeof(peerbuf)); - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "internal_connect: connect(%s) %s", - peerbuf, strbuf); - } - } else { - dev->result = ISC_R_SUCCESS; - sock->connected = 1; - sock->bound = 1; - } - - sock->connect_ev = NULL; - - UNLOCK(&sock->lock); - - task = dev->ev_sender; - dev->ev_sender = sock; - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev)); -} - -isc_result_t -isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) { - isc_result_t ret; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(addressp != NULL); - - LOCK(&sock->lock); - - if (sock->connected) { - *addressp = sock->address; - ret = ISC_R_SUCCESS; - } else { - ret = ISC_R_NOTCONNECTED; - } - - UNLOCK(&sock->lock); - - return (ret); -} - -isc_result_t -isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { - ISC_SOCKADDR_LEN_T len; - isc_result_t ret; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(addressp != NULL); - - LOCK(&sock->lock); - - if (!sock->bound) { - ret = ISC_R_NOTBOUND; - goto out; - } - - ret = ISC_R_SUCCESS; - - len = sizeof(addressp->type); - if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", - strbuf); - ret = ISC_R_UNEXPECTED; - goto out; - } - addressp->length = (unsigned int)len; - - out: - UNLOCK(&sock->lock); - - return (ret); -} - -/* - * 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) { - - REQUIRE(VALID_SOCKET(sock)); - - /* - * Quick exit if there is nothing to do. Don't even bother locking - * in this case. - */ - if (how == 0) - return; - - LOCK(&sock->lock); - - /* - * All of these do the same thing, more or less. - * Each will: - * o If the internal event is marked as "posted" try to - * remove it from the task's queue. If this fails, mark it - * as canceled instead, and let the task clean it up later. - * o For each I/O request for that task of that type, post - * its done event with status of "ISC_R_CANCELED". - * o Reset any state needed. - */ - if (((how & ISC_SOCKCANCEL_RECV) == ISC_SOCKCANCEL_RECV) - && !ISC_LIST_EMPTY(sock->recv_list)) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; - - dev = ISC_LIST_HEAD(sock->recv_list); - - while (dev != NULL) { - current_task = dev->ev_sender; - next = ISC_LIST_NEXT(dev, ev_link); - - if ((task == NULL) || (task == current_task)) { - dev->result = ISC_R_CANCELED; - send_recvdone_event(sock, &dev); - } - dev = next; - } - } - - if (((how & ISC_SOCKCANCEL_SEND) == ISC_SOCKCANCEL_SEND) - && !ISC_LIST_EMPTY(sock->send_list)) { - isc_socketevent_t *dev; - isc_socketevent_t *next; - isc_task_t *current_task; - - dev = ISC_LIST_HEAD(sock->send_list); - - while (dev != NULL) { - current_task = dev->ev_sender; - next = ISC_LIST_NEXT(dev, ev_link); - - if ((task == NULL) || (task == current_task)) { - dev->result = ISC_R_CANCELED; - send_senddone_event(sock, &dev); - } - dev = next; - } - } - - if (((how & ISC_SOCKCANCEL_ACCEPT) == ISC_SOCKCANCEL_ACCEPT) - && !ISC_LIST_EMPTY(sock->accept_list)) { - isc_socket_newconnev_t *dev; - isc_socket_newconnev_t *next; - isc_task_t *current_task; - - dev = ISC_LIST_HEAD(sock->accept_list); - while (dev != NULL) { - current_task = dev->ev_sender; - next = ISC_LIST_NEXT(dev, ev_link); - - if ((task == NULL) || (task == current_task)) { - - ISC_LIST_UNLINK(sock->accept_list, dev, - ev_link); - - dev->newsocket->references--; - free_socket(&dev->newsocket); - - dev->result = ISC_R_CANCELED; - dev->ev_sender = sock; - isc_task_sendanddetach(¤t_task, - ISC_EVENT_PTR(&dev)); - } - - dev = next; - } - } - - /* - * Connecting is not a list. - */ - if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT) - && sock->connect_ev != NULL) { - isc_socket_connev_t *dev; - isc_task_t *current_task; - - INSIST(sock->connecting); - sock->connecting = 0; - - dev = sock->connect_ev; - current_task = dev->ev_sender; - - if ((task == NULL) || (task == current_task)) { - sock->connect_ev = NULL; - - dev->result = ISC_R_CANCELED; - dev->ev_sender = sock; - isc_task_sendanddetach(¤t_task, - ISC_EVENT_PTR(&dev)); - } - } - - UNLOCK(&sock->lock); -} - -isc_sockettype_t -isc_socket_gettype(isc_socket_t *sock) { - REQUIRE(VALID_SOCKET(sock)); - - return (sock->type); -} - -isc_boolean_t -isc_socket_isbound(isc_socket_t *sock) { - isc_boolean_t val; - - LOCK(&sock->lock); - val = ((sock->bound) ? ISC_TRUE : ISC_FALSE); - UNLOCK(&sock->lock); - - return (val); -} - -void -isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { -#if defined(IPV6_V6ONLY) - int onoff = yes ? 1 : 0; -#else - UNUSED(yes); - UNUSED(sock); -#endif - - REQUIRE(VALID_SOCKET(sock)); - -#ifdef IPV6_V6ONLY - if (sock->pf == AF_INET6) { - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, - (void *)&onoff, sizeof(onoff)); - } -#endif -} - -#ifndef ISC_PLATFORM_USETHREADS -void -isc__socketmgr_getfdsets(fd_set *readset, fd_set *writeset, int *maxfd) { - if (socketmgr == NULL) - *maxfd = 0; - else { - *readset = socketmgr->read_fds; - *writeset = socketmgr->write_fds; - *maxfd = socketmgr->maxfd + 1; - } -} - -isc_result_t -isc__socketmgr_dispatch(fd_set *readset, fd_set *writeset, int maxfd) { - isc_socketmgr_t *manager = socketmgr; - - if (manager == NULL) - return (ISC_R_NOTFOUND); - - process_fds(manager, maxfd, readset, writeset); - return (ISC_R_SUCCESS); -} -#endif /* ISC_PLATFORM_USETHREADS */ diff --git a/contrib/bind9/lib/isc/unix/socket_p.h b/contrib/bind9/lib/isc/unix/socket_p.h deleted file mode 100644 index f430bf22e1c6..000000000000 --- a/contrib/bind9/lib/isc/unix/socket_p.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: socket_p.h,v 1.6.206.1 2004/03/06 08:15:02 marka Exp $ */ - -#ifndef ISC_SOCKET_P_H -#define ISC_SOCKET_P_H - -#ifdef ISC_PLATFORM_NEEDSYSSELECTH -#include <sys/select.h> -#endif - -void -isc__socketmgr_getfdsets(fd_set *readset, fd_set *writeset, int *maxfd); - -isc_result_t -isc__socketmgr_dispatch(fd_set *readset, fd_set *writeset, int maxfd); - -#endif /* ISC_SOCKET_P_H */ diff --git a/contrib/bind9/lib/isc/unix/stdio.c b/contrib/bind9/lib/isc/unix/stdio.c deleted file mode 100644 index 794164e73a9e..000000000000 --- a/contrib/bind9/lib/isc/unix/stdio.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: stdio.c,v 1.5.206.1 2004/03/06 08:15:02 marka Exp $ */ - -#include <config.h> - -#include <errno.h> -#include <unistd.h> - -#include <isc/stdio.h> - -#include "errno2result.h" - -isc_result_t -isc_stdio_open(const char *filename, const char *mode, FILE **fp) { - FILE *f; - - f = fopen(filename, mode); - if (f == NULL) - return (isc__errno2result(errno)); - *fp = f; - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_stdio_close(FILE *f) { - int r; - - r = fclose(f); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_result_t -isc_stdio_seek(FILE *f, long offset, int whence) { - int r; - - r = fseek(f, offset, whence); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_result_t -isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { - isc_result_t result = ISC_R_SUCCESS; - size_t r; - - clearerr(f); - r = fread(ptr, size, nmemb, f); - if (r != nmemb) { - if (feof(f)) - result = ISC_R_EOF; - else - result = isc__errno2result(errno); - } - if (nret != NULL) - *nret = r; - return (result); -} - -isc_result_t -isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, - size_t *nret) -{ - isc_result_t result = ISC_R_SUCCESS; - size_t r; - - clearerr(f); - r = fwrite(ptr, size, nmemb, f); - if (r != nmemb) - result = isc__errno2result(errno); - if (nret != NULL) - *nret = r; - return (result); -} - -isc_result_t -isc_stdio_flush(FILE *f) { - int r; - - r = fflush(f); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - -isc_result_t -isc_stdio_sync(FILE *f) { - int r; - - r = fsync(fileno(f)); - if (r == 0) - return (ISC_R_SUCCESS); - else - return (isc__errno2result(errno)); -} - diff --git a/contrib/bind9/lib/isc/unix/stdtime.c b/contrib/bind9/lib/isc/unix/stdtime.c deleted file mode 100644 index b8d818dcfd7a..000000000000 --- a/contrib/bind9/lib/isc/unix/stdtime.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: stdtime.c,v 1.11.2.1.10.5 2005/06/09 23:54:31 marka Exp $ */ - -#include <config.h> - -#include <stddef.h> /* NULL */ -#include <stdlib.h> /* NULL */ -#include <syslog.h> - -#include <sys/time.h> - -#include <isc/stdtime.h> -#include <isc/util.h> - -#ifndef ISC_FIX_TV_USEC -#define ISC_FIX_TV_USEC 1 -#endif - -#define US_PER_S 1000000 - -#if ISC_FIX_TV_USEC -static inline void -fix_tv_usec(struct timeval *tv) { - isc_boolean_t fixed = ISC_FALSE; - - if (tv->tv_usec < 0) { - fixed = ISC_TRUE; - do { - tv->tv_sec -= 1; - tv->tv_usec += US_PER_S; - } while (tv->tv_usec < 0); - } else if (tv->tv_usec >= US_PER_S) { - fixed = ISC_TRUE; - do { - tv->tv_sec += 1; - tv->tv_usec -= US_PER_S; - } while (tv->tv_usec >=US_PER_S); - } - /* - * Call syslog directly as we are called from the logging functions. - */ - if (fixed) - (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); -} -#endif - -void -isc_stdtime_get(isc_stdtime_t *t) { - struct timeval tv; - - /* - * Set 't' to the number of seconds since 00:00:00 UTC, January 1, - * 1970. - */ - - REQUIRE(t != NULL); - - RUNTIME_CHECK(gettimeofday(&tv, NULL) != -1); - -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - INSIST(tv.tv_usec >= 0); -#else - INSIST(tv.tv_usec >= 0 && tv.tv_usec < US_PER_S); -#endif - - *t = (unsigned int)tv.tv_sec; -} diff --git a/contrib/bind9/lib/isc/unix/strerror.c b/contrib/bind9/lib/isc/unix/strerror.c deleted file mode 100644 index 863867e15953..000000000000 --- a/contrib/bind9/lib/isc/unix/strerror.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: strerror.c,v 1.1.2.1.10.3 2004/03/08 09:04:57 marka Exp $ */ - -#include <config.h> - -#include <stdio.h> -#include <string.h> - -#include <isc/mutex.h> -#include <isc/once.h> -#include <isc/print.h> -#include <isc/strerror.h> -#include <isc/util.h> - -#ifdef HAVE_STRERROR -/* - * We need to do this this way for profiled locks. - */ -static isc_mutex_t isc_strerror_lock; -static void init_lock(void) { - RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS); -} -#else -extern const char * const sys_errlist[]; -extern const int sys_nerr; -#endif - -void -isc__strerror(int num, char *buf, size_t size) { -#ifdef HAVE_STRERROR - char *msg; - unsigned int unum = num; - static isc_once_t once = ISC_ONCE_INIT; - - REQUIRE(buf != NULL); - - RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); - - LOCK(&isc_strerror_lock); - msg = strerror(num); - if (msg != NULL) - snprintf(buf, size, "%s", msg); - else - snprintf(buf, size, "Unknown error: %u", unum); - UNLOCK(&isc_strerror_lock); -#else - unsigned int unum = num; - - REQUIRE(buf != NULL); - - if (num >= 0 && num < sys_nerr) - snprintf(buf, size, "%s", sys_errlist[num]); - else - snprintf(buf, size, "Unknown error: %u", unum); -#endif -} diff --git a/contrib/bind9/lib/isc/unix/syslog.c b/contrib/bind9/lib/isc/unix/syslog.c deleted file mode 100644 index e53154452254..000000000000 --- a/contrib/bind9/lib/isc/unix/syslog.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: syslog.c,v 1.1.12.3 2004/03/08 09:04:57 marka Exp $ */ - -#include <config.h> - -#include <stdlib.h> -#include <string.h> -#include <syslog.h> - -#include <isc/result.h> -#include <isc/syslog.h> -#include <isc/util.h> - -static struct dsn_c_pvt_sfnt { - int val; - const char *strval; -} facilities[] = { - { LOG_KERN, "kern" }, - { LOG_USER, "user" }, - { LOG_MAIL, "mail" }, - { LOG_DAEMON, "daemon" }, - { LOG_AUTH, "auth" }, - { LOG_SYSLOG, "syslog" }, - { LOG_LPR, "lpr" }, -#ifdef LOG_NEWS - { LOG_NEWS, "news" }, -#endif -#ifdef LOG_UUCP - { LOG_UUCP, "uucp" }, -#endif -#ifdef LOG_CRON - { LOG_CRON, "cron" }, -#endif -#ifdef LOG_AUTHPRIV - { LOG_AUTHPRIV, "authpriv" }, -#endif -#ifdef LOG_FTP - { LOG_FTP, "ftp" }, -#endif - { LOG_LOCAL0, "local0"}, - { LOG_LOCAL1, "local1"}, - { LOG_LOCAL2, "local2"}, - { LOG_LOCAL3, "local3"}, - { LOG_LOCAL4, "local4"}, - { LOG_LOCAL5, "local5"}, - { LOG_LOCAL6, "local6"}, - { LOG_LOCAL7, "local7"}, - { 0, NULL } -}; - -isc_result_t -isc_syslog_facilityfromstring(const char *str, int *facilityp) { - int i; - - REQUIRE(str != NULL); - REQUIRE(facilityp != NULL); - - for (i = 0; facilities[i].strval != NULL; i++) { - if (strcasecmp(facilities[i].strval, str) == 0) { - *facilityp = facilities[i].val; - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); - -} diff --git a/contrib/bind9/lib/isc/unix/time.c b/contrib/bind9/lib/isc/unix/time.c deleted file mode 100644 index 39c851cebe9a..000000000000 --- a/contrib/bind9/lib/isc/unix/time.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1998-2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: time.c,v 1.34.2.6.2.4 2004/03/06 08:15:03 marka Exp $ */ - -#include <config.h> - -#include <errno.h> -#include <limits.h> -#include <syslog.h> -#include <time.h> - -#include <sys/time.h> /* Required for struct timeval on some platforms. */ - -#include <isc/log.h> -#include <isc/print.h> -#include <isc/strerror.h> -#include <isc/string.h> -#include <isc/time.h> -#include <isc/util.h> - -#define NS_PER_S 1000000000 /* Nanoseconds per second. */ -#define NS_PER_US 1000 /* Nanoseconds per microsecond. */ -#define US_PER_S 1000000 /* Microseconds per second. */ - -/* - * All of the INSIST()s checks of nanoseconds < NS_PER_S are for - * consistency checking of the type. In lieu of magic numbers, it - * is the best we've got. The check is only performed on functions which - * need an initialized type. - */ - -#ifndef ISC_FIX_TV_USEC -#define ISC_FIX_TV_USEC 1 -#endif - -/*** - *** Intervals - ***/ - -static isc_interval_t zero_interval = { 0, 0 }; -isc_interval_t *isc_interval_zero = &zero_interval; - -#if ISC_FIX_TV_USEC -static inline void -fix_tv_usec(struct timeval *tv) { - isc_boolean_t fixed = ISC_FALSE; - - if (tv->tv_usec < 0) { - fixed = ISC_TRUE; - do { - tv->tv_sec -= 1; - tv->tv_usec += US_PER_S; - } while (tv->tv_usec < 0); - } else if (tv->tv_usec >= US_PER_S) { - fixed = ISC_TRUE; - do { - tv->tv_sec += 1; - tv->tv_usec -= US_PER_S; - } while (tv->tv_usec >=US_PER_S); - } - /* - * Call syslog directly as was are called from the logging functions. - */ - if (fixed) - (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); -} -#endif - -void -isc_interval_set(isc_interval_t *i, - unsigned int seconds, unsigned int nanoseconds) -{ - REQUIRE(i != NULL); - REQUIRE(nanoseconds < NS_PER_S); - - i->seconds = seconds; - i->nanoseconds = nanoseconds; -} - -isc_boolean_t -isc_interval_iszero(const isc_interval_t *i) { - REQUIRE(i != NULL); - INSIST(i->nanoseconds < NS_PER_S); - - if (i->seconds == 0 && i->nanoseconds == 0) - return (ISC_TRUE); - - return (ISC_FALSE); -} - - -/*** - *** Absolute Times - ***/ - -static isc_time_t epoch = { 0, 0 }; -isc_time_t *isc_time_epoch = &epoch; - -void -isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { - REQUIRE(t != NULL); - REQUIRE(nanoseconds < NS_PER_S); - - t->seconds = seconds; - t->nanoseconds = nanoseconds; -} - -void -isc_time_settoepoch(isc_time_t *t) { - REQUIRE(t != NULL); - - t->seconds = 0; - t->nanoseconds = 0; -} - -isc_boolean_t -isc_time_isepoch(const isc_time_t *t) { - REQUIRE(t != NULL); - INSIST(t->nanoseconds < NS_PER_S); - - if (t->seconds == 0 && t->nanoseconds == 0) - return (ISC_TRUE); - - return (ISC_FALSE); -} - - -isc_result_t -isc_time_now(isc_time_t *t) { - struct timeval tv; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(t != NULL); - - if (gettimeofday(&tv, NULL) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); - return (ISC_R_UNEXPECTED); - } - - /* - * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, - * then this test will generate warnings for platforms on which it is - * unsigned. In any event, the chances of any of these problems - * happening are pretty much zero, but since the libisc library ensures - * certain things to be true ... - */ -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - if (tv.tv_sec < 0) - return (ISC_R_UNEXPECTED); -#else - if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) - return (ISC_R_UNEXPECTED); -#endif - - /* - * Ensure the tv_sec value fits in t->seconds. - */ - if (sizeof(tv.tv_sec) > sizeof(t->seconds) && - ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U) - return (ISC_R_RANGE); - - t->seconds = tv.tv_sec; - t->nanoseconds = tv.tv_usec * NS_PER_US; - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { - struct timeval tv; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(t != NULL); - REQUIRE(i != NULL); - INSIST(i->nanoseconds < NS_PER_S); - - if (gettimeofday(&tv, NULL) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); - return (ISC_R_UNEXPECTED); - } - - /* - * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, - * then this test will generate warnings for platforms on which it is - * unsigned. In any event, the chances of any of these problems - * happening are pretty much zero, but since the libisc library ensures - * certain things to be true ... - */ -#if ISC_FIX_TV_USEC - fix_tv_usec(&tv); - if (tv.tv_sec < 0) - return (ISC_R_UNEXPECTED); -#else - if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) - return (ISC_R_UNEXPECTED); -#endif - - /* - * Ensure the resulting seconds value fits in the size of an - * unsigned int. (It is written this way as a slight optimization; - * note that even if both values == INT_MAX, then when added - * and getting another 1 added below the result is UINT_MAX.) - */ - if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) && - ((long long)tv.tv_sec + i->seconds > UINT_MAX)) - return (ISC_R_RANGE); - - t->seconds = tv.tv_sec + i->seconds; - t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds; - if (t->nanoseconds > NS_PER_S) { - t->seconds++; - t->nanoseconds -= NS_PER_S; - } - - return (ISC_R_SUCCESS); -} - -int -isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) { - REQUIRE(t1 != NULL && t2 != NULL); - INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S); - - if (t1->seconds < t2->seconds) - return (-1); - if (t1->seconds > t2->seconds) - return (1); - if (t1->nanoseconds < t2->nanoseconds) - return (-1); - if (t1->nanoseconds > t2->nanoseconds) - return (1); - return (0); -} - -isc_result_t -isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) -{ - REQUIRE(t != NULL && i != NULL && result != NULL); - INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); - - /* - * Ensure the resulting seconds value fits in the size of an - * unsigned int. (It is written this way as a slight optimization; - * note that even if both values == INT_MAX, then when added - * and getting another 1 added below the result is UINT_MAX.) - */ - if ((t->seconds > INT_MAX || i->seconds > INT_MAX) && - ((long long)t->seconds + i->seconds > UINT_MAX)) - return (ISC_R_RANGE); - - result->seconds = t->seconds + i->seconds; - result->nanoseconds = t->nanoseconds + i->nanoseconds; - if (result->nanoseconds >= NS_PER_S) { - result->seconds++; - result->nanoseconds -= NS_PER_S; - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, - isc_time_t *result) -{ - REQUIRE(t != NULL && i != NULL && result != NULL); - INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); - - if ((unsigned int)t->seconds < i->seconds || - ((unsigned int)t->seconds == i->seconds && - t->nanoseconds < i->nanoseconds)) - return (ISC_R_RANGE); - - result->seconds = t->seconds - i->seconds; - if (t->nanoseconds >= i->nanoseconds) - result->nanoseconds = t->nanoseconds - i->nanoseconds; - else { - result->nanoseconds = NS_PER_S - i->nanoseconds + - t->nanoseconds; - result->seconds--; - } - - return (ISC_R_SUCCESS); -} - -isc_uint64_t -isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) { - isc_uint64_t i1, i2, i3; - - REQUIRE(t1 != NULL && t2 != NULL); - INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S); - - i1 = (isc_uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds; - i2 = (isc_uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds; - - if (i1 <= i2) - return (0); - - i3 = i1 - i2; - - /* - * Convert to microseconds. - */ - i3 = (i1 - i2) / NS_PER_US; - - return (i3); -} - -isc_uint32_t -isc_time_seconds(const isc_time_t *t) { - REQUIRE(t != NULL); - INSIST(t->nanoseconds < NS_PER_S); - - return ((isc_uint32_t)t->seconds); -} - -isc_result_t -isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) { - isc_uint64_t i; - time_t seconds; - - REQUIRE(t != NULL); - INSIST(t->nanoseconds < NS_PER_S); - - /* - * Ensure that the number of seconds represented by t->seconds - * can be represented by a time_t. Since t->seconds is an unsigned - * int and since time_t is mostly opaque, this is trickier than - * it seems. (This standardized opaqueness of time_t is *very* - * frustrating; time_t is not even limited to being an integral - * type.) - * - * The mission, then, is to avoid generating any kind of warning - * about "signed versus unsigned" while trying to determine if the - * the unsigned int t->seconds is out range for tv_sec, which is - * pretty much only true if time_t is a signed integer of the same - * size as the return value of isc_time_seconds. - * - * The use of the 64 bit integer ``i'' takes advantage of C's - * conversion rules to either zero fill or sign extend the widened - * type. - * - * Solaris 5.6 gives this warning about the left shift: - * warning: integer overflow detected: op "<<" - * if the U(nsigned) qualifier is not on the 1. - */ - seconds = (time_t)t->seconds; - - INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t)); - INSIST(sizeof(time_t) >= sizeof(isc_uint32_t)); - - if (sizeof(time_t) == sizeof(isc_uint32_t) && /* Same size. */ - (time_t)0.5 != 0.5 && /* Not a floating point type. */ - (i = (time_t)-1) != 4294967295u && /* Is signed. */ - (seconds & - (1U << (sizeof(time_t) * CHAR_BIT - 1))) != 0U) { /* Negative. */ - /* - * This UNUSED() is here to shut up the IRIX compiler: - * variable "i" was set but never used - * when the value of i *was* used in the third test. - * (Let's hope the compiler got the actual test right.) - */ - UNUSED(i); - return (ISC_R_RANGE); - } - - *secondsp = seconds; - - return (ISC_R_SUCCESS); -} - -isc_uint32_t -isc_time_nanoseconds(const isc_time_t *t) { - REQUIRE(t != NULL); - - ENSURE(t->nanoseconds < NS_PER_S); - - return ((isc_uint32_t)t->nanoseconds); -} - -void -isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { - time_t now; - unsigned int flen; - - REQUIRE(len > 0); - - now = (time_t) t->seconds; - flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now)); - INSIST(flen < len); - if (flen != 0) - snprintf(buf + flen, len - flen, - ".%03u", t->nanoseconds / 1000000); - else - snprintf(buf, len, "99-Bad-9999 99:99:99.999"); -} |