summaryrefslogtreecommitdiff
path: root/usr.sbin/bind/lib/isc
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bind/lib/isc')
-rw-r--r--usr.sbin/bind/lib/isc/Makefile.in31
-rw-r--r--usr.sbin/bind/lib/isc/api6
-rw-r--r--usr.sbin/bind/lib/isc/base64.c20
-rw-r--r--usr.sbin/bind/lib/isc/commandline.c24
-rw-r--r--usr.sbin/bind/lib/isc/entropy.c119
-rw-r--r--usr.sbin/bind/lib/isc/hash.c42
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/Makefile.in10
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/hash.h58
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/log.h508
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/platform.h.in129
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/refcount.h109
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/rwlock.h48
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/socket.h408
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/string.h165
-rw-r--r--usr.sbin/bind/lib/isc/include/isc/types.h100
-rw-r--r--usr.sbin/bind/lib/isc/inet_aton.c7
-rw-r--r--usr.sbin/bind/lib/isc/inet_ntop.c25
-rw-r--r--usr.sbin/bind/lib/isc/inet_pton.c36
-rw-r--r--usr.sbin/bind/lib/isc/lex.c46
-rw-r--r--usr.sbin/bind/lib/isc/lfsr.c6
-rw-r--r--usr.sbin/bind/lib/isc/log.c43
-rw-r--r--usr.sbin/bind/lib/isc/mem.c604
-rw-r--r--usr.sbin/bind/lib/isc/print.c2
-rw-r--r--usr.sbin/bind/lib/isc/pthreads/thread.c6
-rw-r--r--usr.sbin/bind/lib/isc/random.c6
-rw-r--r--usr.sbin/bind/lib/isc/rwlock.c433
-rw-r--r--usr.sbin/bind/lib/isc/sha1.c32
-rw-r--r--usr.sbin/bind/lib/isc/sockaddr.c120
-rw-r--r--usr.sbin/bind/lib/isc/string.c109
-rw-r--r--usr.sbin/bind/lib/isc/task.c30
-rw-r--r--usr.sbin/bind/lib/isc/unix/Makefile.in2
-rw-r--r--usr.sbin/bind/lib/isc/unix/dir.c52
-rw-r--r--usr.sbin/bind/lib/isc/unix/entropy.c14
-rw-r--r--usr.sbin/bind/lib/isc/unix/file.c8
-rw-r--r--usr.sbin/bind/lib/isc/unix/fsaccess.c7
-rw-r--r--usr.sbin/bind/lib/isc/unix/ifiter_ioctl.c18
-rw-r--r--usr.sbin/bind/lib/isc/unix/include/isc/stat.h3
-rw-r--r--usr.sbin/bind/lib/isc/unix/socket.c390
-rw-r--r--usr.sbin/bind/lib/isc/unix/time.c14
39 files changed, 2647 insertions, 1143 deletions
diff --git a/usr.sbin/bind/lib/isc/Makefile.in b/usr.sbin/bind/lib/isc/Makefile.in
index 9d48c91b6da..88478f6e177 100644
--- a/usr.sbin/bind/lib/isc/Makefile.in
+++ b/usr.sbin/bind/lib/isc/Makefile.in
@@ -1,7 +1,7 @@
-# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
-# Permission to use, copy, modify, and distribute this software for any
+# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $ISC: Makefile.in,v 1.71.2.2.2.8 2004/07/20 07:01:58 marka Exp $
+# $ISC: Makefile.in,v 1.81.18.8 2007/09/14 23:46:18 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,6 +25,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/unix/include \
-I${srcdir}/@ISC_THREAD_DIR@/include \
+ -I${srcdir}/@ISC_ARCH_DIR@/include \
-I./include \
-I${srcdir}/include
CDEFINES =
@@ -53,30 +54,32 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
OBJS = @ISC_EXTRA_OBJS@ \
assertions.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ \
- hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
- lcg.@O@ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ md5.@O@ \
+ lcg.@O@ \
+ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@\
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ md5.@O@ \
mem.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ ondestroy.@O@ \
parseint.@O@ quota.@O@ random.@O@ \
- ratelimiter.@O@ region.@O@ result.@O@ rwlock.@O@ \
- serial.@O@ sha1.@O@ sockaddr.@O@ string.@O@ strtoul.@O@ \
- symtab.@O@ task.@O@ taskpool.@O@ timer.@O@ version.@O@ \
- ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+ ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
+ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ string.@O@ \
+ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ timer.@O@ \
+ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
# Alphabetically
SRCS = @ISC_EXTRA_SRCS@ \
assertions.c base64.c bitstring.c buffer.c \
bufferlist.c commandline.c error.c event.c \
- heap.c hex.c hmacmd5.c \
- lcg.c lex.c lfsr.c lib.c log.c \
+ lcg.c \
+ heap.c hex.c hmacmd5.c hmacsha.c \
+ lex.c lfsr.c lib.c log.c \
md5.c mem.c mutexblock.c netaddr.c netscope.c ondestroy.c \
parseint.c quota.c random.c \
- ratelimiter.c result.c rwlock.c \
- serial.c sha1.c sockaddr.c string.c strtoul.c symtab.c \
+ ratelimiter.c refcount.c region.c result.c rwlock.c \
+ serial.c sha1.c sha2.c sockaddr.c string.c strtoul.c symtab.c \
task.c taskpool.c timer.c version.c
LIBS = @LIBS@
-SUBDIRS = include unix nls @ISC_THREAD_DIR@
+SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@
TARGETS = timestamp
@BIND9_MAKE_RULES@
diff --git a/usr.sbin/bind/lib/isc/api b/usr.sbin/bind/lib/isc/api
index b4d017358ad..ecadc93c94f 100644
--- a/usr.sbin/bind/lib/isc/api
+++ b/usr.sbin/bind/lib/isc/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 12
-LIBREVISION = 1
-LIBAGE = 1
+LIBINTERFACE = 32
+LIBREVISION = 5
+LIBAGE = 0
diff --git a/usr.sbin/bind/lib/isc/base64.c b/usr.sbin/bind/lib/isc/base64.c
index 444e2c2e293..b717565822f 100644
--- a/usr.sbin/bind/lib/isc/base64.c
+++ b/usr.sbin/bind/lib/isc/base64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: base64.c,v 1.23.2.2.2.3 2004/03/06 08:14:27 marka Exp $ */
+/* $ISC: base64.c,v 1.28.18.2 2005/04/29 00:16:44 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -32,7 +34,8 @@
} while (0)
-/*
+/*@{*/
+/*!
* These static functions are also present in lib/dns/rdata.c. I'm not
* sure where they should go. -- bwelling
*/
@@ -44,6 +47,7 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+/*@}*/
isc_result_t
isc_base64_totext(isc_region_t *source, int wordlength,
@@ -90,14 +94,14 @@ isc_base64_totext(isc_region_t *source, int wordlength,
return (ISC_R_SUCCESS);
}
-/*
+/*%
* State of a base64 decoding process in progress.
*/
typedef struct {
- int length; /* Desired length of binary data or -1 */
- isc_buffer_t *target; /* Buffer for resulting binary data */
- int digits; /* Number of buffered base64 digits */
- isc_boolean_t seen_end; /* True if "=" end marker seen */
+ int length; /*%< Desired length of binary data or -1 */
+ isc_buffer_t *target; /*%< Buffer for resulting binary data */
+ int digits; /*%< Number of buffered base64 digits */
+ isc_boolean_t seen_end; /*%< True if "=" end marker seen */
int val[4];
} base64_decode_ctx_t;
diff --git a/usr.sbin/bind/lib/isc/commandline.c b/usr.sbin/bind/lib/isc/commandline.c
index 4bb46e52547..57c4eb8f9cd 100644
--- a/usr.sbin/bind/lib/isc/commandline.c
+++ b/usr.sbin/bind/lib/isc/commandline.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -48,9 +48,9 @@
* SUCH DAMAGE.
*/
-/* $ISC: commandline.c,v 1.15.206.1 2004/03/06 08:14:28 marka Exp $ */
+/* $ISC: commandline.c,v 1.16.18.2 2005/04/29 00:16:45 marka Exp $ */
-/*
+/*! \file
* This file was adapted from the NetBSD project's source tree, RCS ID:
* NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp
*
@@ -59,8 +59,8 @@
*/
/*
- * Principal Authors: Computer Systems Research Group at UC Berkeley
- * Principal ISC caretaker: DCL
+ * \author Principal Authors: Computer Systems Research Group at UC Berkeley
+ * \author Principal ISC caretaker: DCL
*/
#include <config.h>
@@ -72,17 +72,17 @@
#include <isc/string.h>
#include <isc/util.h>
-/* Index into parent argv vector. */
+/*% Index into parent argv vector. */
LIBISC_EXTERNAL_DATA int isc_commandline_index = 1;
-/* Character checked for validity. */
+/*% Character checked for validity. */
LIBISC_EXTERNAL_DATA int isc_commandline_option;
-/* Argument associated with option. */
+/*% Argument associated with option. */
LIBISC_EXTERNAL_DATA char *isc_commandline_argument;
-/* For printing error messages. */
+/*% For printing error messages. */
LIBISC_EXTERNAL_DATA char *isc_commandline_progname;
-/* Print error messages. */
+/*% Print error messages. */
LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_errprint = ISC_TRUE;
-/* Reset processing. */
+/*% Reset processing. */
LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_reset = ISC_TRUE;
static char endopt = '\0';
@@ -91,7 +91,7 @@ static char endopt = '\0';
#define BADARG ':'
#define ENDOPT &endopt
-/*
+/*!
* getopt --
* Parse argc/argv argument vector.
*/
diff --git a/usr.sbin/bind/lib/isc/entropy.c b/usr.sbin/bind/lib/isc/entropy.c
index 41ba03a8904..b4c0afd839d 100644
--- a/usr.sbin/bind/lib/isc/entropy.c
+++ b/usr.sbin/bind/lib/isc/entropy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * 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
@@ -15,12 +15,16 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: entropy.c,v 1.3.2.2.2.7 2004/03/08 09:04:48 marka Exp $ */
+/* $ISC: entropy.c,v 1.11.18.3 2005/07/12 01:22:28 marka Exp $ */
-/*
+/*! \file
+ * \brief
* This is the system independent part of the entropy module. It is
* compiled via inclusion from the relevant OS source file, ie,
- * unix/entropy.c or win32/entropy.c.
+ * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c.
+ *
+ * \author Much of this code is modeled after the NetBSD /dev/random implementation,
+ * written by Michael Graff <explorer@netbsd.org>.
*/
#include <errno.h>
@@ -42,10 +46,6 @@
#include <isc/time.h>
#include <isc/util.h>
-/*
- * Much of this code is modeled after the NetBSD /dev/random implementation,
- * written by Michael Graff <explorer@netbsd.org>.
- */
#define ENTROPY_MAGIC ISC_MAGIC('E', 'n', 't', 'e')
#define SOURCE_MAGIC ISC_MAGIC('E', 'n', 't', 's')
@@ -58,26 +58,28 @@
*** you are doing.
***/
-/*
- * size of entropy pool in 32-bit words. This _MUST_ be a power of 2.
+/*%
+ * Size of entropy pool in 32-bit words. This _MUST_ be a power of 2.
*/
#define RND_POOLWORDS 128
+/*% Pool in bytes. */
#define RND_POOLBYTES (RND_POOLWORDS * 4)
+/*% Pool in bits. */
#define RND_POOLBITS (RND_POOLWORDS * 32)
-/*
+/*%
* Number of bytes returned per hash. This must be true:
* threshold * 2 <= digest_size_in_bytes
*/
#define RND_ENTROPY_THRESHOLD 10
#define THRESHOLD_BITS (RND_ENTROPY_THRESHOLD * 8)
-/*
+/*%
* Size of the input event queue in samples.
*/
#define RND_EVENTQSIZE 32
-/*
+/*%
* The number of times we'll "reseed" for pseudorandom seeds. This is an
* extremely weak pseudorandom seed. If the caller is using lots of
* pseudorandom data and they cannot provide a stronger random source,
@@ -86,12 +88,13 @@
*/
#define RND_INITIALIZE 128
+/*% Entropy Pool */
typedef struct {
- isc_uint32_t cursor; /* current add point in the pool */
- isc_uint32_t entropy; /* current entropy estimate in bits */
- isc_uint32_t pseudo; /* bits extracted in pseudorandom */
- isc_uint32_t rotate; /* how many bits to rotate by */
- isc_uint32_t pool[RND_POOLWORDS]; /* random pool data */
+ isc_uint32_t cursor; /*%< current add point in the pool */
+ isc_uint32_t entropy; /*%< current entropy estimate in bits */
+ isc_uint32_t pseudo; /*%< bits extracted in pseudorandom */
+ isc_uint32_t rotate; /*%< how many bits to rotate by */
+ isc_uint32_t pool[RND_POOLWORDS]; /*%< random pool data */
} isc_entropypool_t;
struct isc_entropy {
@@ -107,13 +110,14 @@ struct isc_entropy {
ISC_LIST(isc_entropysource_t) sources;
};
+/*% Sample Queue */
typedef struct {
- isc_uint32_t last_time; /* last time recorded */
- isc_uint32_t last_delta; /* last delta value */
- isc_uint32_t last_delta2; /* last delta2 value */
- isc_uint32_t nsamples; /* number of samples filled in */
- isc_uint32_t *samples; /* the samples */
- isc_uint32_t *extra; /* extra samples added in */
+ isc_uint32_t last_time; /*%< last time recorded */
+ isc_uint32_t last_delta; /*%< last delta value */
+ isc_uint32_t last_delta2; /*%< last delta2 value */
+ isc_uint32_t nsamples; /*%< number of samples filled in */
+ isc_uint32_t *samples; /*%< the samples */
+ isc_uint32_t *extra; /*%< extra samples added in */
} sample_queue_t;
typedef struct {
@@ -137,7 +141,7 @@ struct isc_entropysource {
unsigned int magic;
unsigned int type;
isc_entropy_t *ent;
- isc_uint32_t total; /* entropy from this source */
+ isc_uint32_t total; /*%< entropy from this source */
ISC_LINK(isc_entropysource_t) link;
char name[32];
isc_boolean_t bad;
@@ -151,12 +155,13 @@ struct isc_entropysource {
} sources;
};
-#define ENTROPY_SOURCETYPE_SAMPLE 1 /* Type is a sample source */
-#define ENTROPY_SOURCETYPE_FILE 2 /* Type is a file source */
-#define ENTROPY_SOURCETYPE_CALLBACK 3 /* Type is a callback source */
-#define ENTROPY_SOURCETYPE_USOCKET 4 /* Type is a Unix socket source */
+#define ENTROPY_SOURCETYPE_SAMPLE 1 /*%< Type is a sample source */
+#define ENTROPY_SOURCETYPE_FILE 2 /*%< Type is a file source */
+#define ENTROPY_SOURCETYPE_CALLBACK 3 /*%< Type is a callback source */
+#define ENTROPY_SOURCETYPE_USOCKET 4 /*%< Type is a Unix socket source */
-/*
+/*@{*/
+/*%
* The random pool "taps"
*/
#define TAP1 99
@@ -164,8 +169,10 @@ struct isc_entropysource {
#define TAP3 31
#define TAP4 9
#define TAP5 7
+/*@}*/
-/*
+/*@{*/
+/*%
* Declarations for function provided by the system dependent sources that
* include this file.
*/
@@ -181,6 +188,7 @@ destroyfilesource(isc_entropyfilesource_t *source);
static void
destroyusocketsource(isc_entropyusocketsource_t *source);
+/*@}*/
static void
samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) {
@@ -211,7 +219,7 @@ samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) {
return (ISC_R_SUCCESS);
}
-/*
+/*%
* Add in entropy, even when the value we're adding in could be
* very large.
*/
@@ -225,7 +233,7 @@ add_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS);
}
-/*
+/*%
* Decrement the amount of entropy the pool has.
*/
static inline void
@@ -234,7 +242,7 @@ subtract_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
ent->pool.entropy -= entropy;
}
-/*
+/*!
* Add in entropy, even when the value we're adding in could be
* very large.
*/
@@ -248,7 +256,7 @@ add_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
}
-/*
+/*!
* Decrement the amount of pseudo the pool has.
*/
static inline void
@@ -257,7 +265,7 @@ subtract_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
ent->pool.pseudo -= pseudo;
}
-/*
+/*!
* Add one word to the pool, rotating the input as needed.
*/
static inline void
@@ -292,7 +300,7 @@ entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) {
}
}
-/*
+/*!
* Add a buffer's worth of data to the pool.
*
* Requires that the lock is held on the entropy pool.
@@ -362,7 +370,7 @@ reseed(isc_entropy_t *ent) {
entropypool_adddata(ent, &pid, sizeof(pid), 0);
}
- /*
+ /*!
* After we've reseeded 100 times, only add new timing info every
* 50 requests. This will keep us from using lots and lots of
* CPU just to return bad pseudorandom data anyway.
@@ -382,7 +390,7 @@ estimate_entropy(sample_queue_t *sq, isc_uint32_t t) {
isc_int32_t delta2;
isc_int32_t delta3;
- /*
+ /*!
* If the time counter has overflowed, calculate the real difference.
* If it has not, it is simpler.
*/
@@ -661,7 +669,7 @@ isc_entropypool_invalidate(isc_entropypool_t *pool) {
isc_result_t
isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
- isc_result_t ret;
+ isc_result_t result;
isc_entropy_t *ent;
REQUIRE(mctx != NULL);
@@ -674,10 +682,9 @@ isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
/*
* We need a lock.
*/
- if (isc_mutex_init(&ent->lock) != ISC_R_SUCCESS) {
- ret = ISC_R_UNEXPECTED;
+ result = isc_mutex_init(&ent->lock);
+ if (result != ISC_R_SUCCESS)
goto errout;
- }
/*
* From here down, no failures will/can occur.
@@ -700,10 +707,10 @@ isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
errout:
isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
- return (ret);
+ return (result);
}
-/*
+/*!
* Requires "ent" be locked.
*/
static void
@@ -851,7 +858,7 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
void *arg,
isc_entropysource_t **sourcep)
{
- isc_result_t ret;
+ isc_result_t result;
isc_entropysource_t *source;
isc_cbsource_t *cbs;
@@ -863,15 +870,15 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
if (source == NULL) {
- ret = ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
goto errout;
}
source->bad = ISC_FALSE;
cbs = &source->sources.callback;
- ret = samplesource_allocate(ent, &cbs->samplequeue);
- if (ret != ISC_R_SUCCESS)
+ result = samplesource_allocate(ent, &cbs->samplequeue);
+ if (result != ISC_R_SUCCESS)
goto errout;
cbs->start_called = ISC_FALSE;
@@ -907,7 +914,7 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
UNLOCK(&ent->lock);
- return (ret);
+ return (result);
}
void
@@ -939,7 +946,7 @@ isc_result_t
isc_entropy_createsamplesource(isc_entropy_t *ent,
isc_entropysource_t **sourcep)
{
- isc_result_t ret;
+ isc_result_t result;
isc_entropysource_t *source;
sample_queue_t *sq;
@@ -950,13 +957,13 @@ isc_entropy_createsamplesource(isc_entropy_t *ent,
source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
if (source == NULL) {
- ret = ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
goto errout;
}
sq = &source->sources.sample.samplequeue;
- ret = samplesource_allocate(ent, sq);
- if (ret != ISC_R_SUCCESS)
+ result = samplesource_allocate(ent, sq);
+ if (result != ISC_R_SUCCESS)
goto errout;
/*
@@ -986,10 +993,10 @@ isc_entropy_createsamplesource(isc_entropy_t *ent,
UNLOCK(&ent->lock);
- return (ret);
+ return (result);
}
-/*
+/*!
* Add a sample, and return ISC_R_SUCCESS if the queue has become full,
* ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the
* queue was full when this function was called.
diff --git a/usr.sbin/bind/lib/isc/hash.c b/usr.sbin/bind/lib/isc/hash.c
index e3e624b1246..e4603dcbeee 100644
--- a/usr.sbin/bind/lib/isc/hash.c
+++ b/usr.sbin/bind/lib/isc/hash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,14 +15,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: hash.c,v 1.2.2.4.2.3 2006/01/04 00:37:22 marka Exp $ */
+/* $ISC: hash.c,v 1.6.18.5 2006/01/04 00:37:23 marka Exp $ */
-/*
+/*! \file
* Some portion of this code was derived from universal hash function
* libraries of Rice University.
- */
-
-/* "UH Universal Hashing Library"
+\section license UH Universal Hashing Library
Copyright ((c)) 2002, Rice University
All rights reserved.
@@ -74,28 +72,31 @@ if advised of the possibility of such damage.
#define HASH_MAGIC ISC_MAGIC('H', 'a', 's', 'h')
#define VALID_HASH(h) ISC_MAGIC_VALID((h), HASH_MAGIC)
-/*
+/*%
* A large 32-bit prime number that specifies the range of the hash output.
*/
#define PRIME32 0xFFFFFFFB /* 2^32 - 5 */
-/*
+/*@{*/
+/*%
* Types of random seed and hash accumulator. Perhaps they can be system
* dependent.
*/
typedef isc_uint32_t hash_accum_t;
typedef isc_uint16_t hash_random_t;
+/*@}*/
+/*% isc hash structure */
struct isc_hash {
unsigned int magic;
isc_mem_t *mctx;
isc_mutex_t lock;
isc_boolean_t initialized;
isc_refcount_t refcnt;
- isc_entropy_t *entropy; /* entropy source */
- unsigned int limit; /* upper limit of key length */
- size_t vectorlen; /* size of the vector below */
- hash_random_t *rndvector; /* random vector for universal hashing */
+ isc_entropy_t *entropy; /*%< entropy source */
+ unsigned int limit; /*%< upper limit of key length */
+ size_t vectorlen; /*%< size of the vector below */
+ hash_random_t *rndvector; /*%< random vector for universal hashing */
};
static isc_mutex_t createlock;
@@ -141,7 +142,7 @@ isc_result_t
isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
unsigned int limit, isc_hash_t **hctxp)
{
- isc_result_t ret;
+ isc_result_t result;
isc_hash_t *hctx;
size_t vlen;
hash_random_t *rv;
@@ -167,17 +168,16 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
vlen = sizeof(hash_random_t) * (limit + 1);
rv = isc_mem_get(mctx, vlen);
if (rv == NULL) {
- ret = ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
goto errout;
}
/*
* We need a lock.
*/
- if (isc_mutex_init(&hctx->lock) != ISC_R_SUCCESS) {
- ret = ISC_R_UNEXPECTED;
+ result = isc_mutex_init(&hctx->lock);
+ if (result != ISC_R_SUCCESS)
goto errout;
- }
/*
* From here down, no failures will/can occur.
@@ -186,7 +186,9 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
hctx->mctx = NULL;
isc_mem_attach(mctx, &hctx->mctx);
hctx->initialized = ISC_FALSE;
- isc_refcount_init(&hctx->refcnt, 1);
+ result = isc_refcount_init(&hctx->refcnt, 1);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_lock;
hctx->entropy = NULL;
hctx->limit = limit;
hctx->vectorlen = vlen;
@@ -198,12 +200,14 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
*hctxp = hctx;
return (ISC_R_SUCCESS);
+ cleanup_lock:
+ DESTROYLOCK(&hctx->lock);
errout:
isc_mem_put(mctx, hctx, sizeof(isc_hash_t));
if (rv != NULL)
isc_mem_put(mctx, rv, vlen);
- return (ret);
+ return (result);
}
static void
diff --git a/usr.sbin/bind/lib/isc/include/isc/Makefile.in b/usr.sbin/bind/lib/isc/include/isc/Makefile.in
index b3e0ed58f70..10e8e916ee7 100644
--- a/usr.sbin/bind/lib/isc/include/isc/Makefile.in
+++ b/usr.sbin/bind/lib/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $ISC: Makefile.in,v 1.50.12.6 2005/03/22 02:32:07 marka Exp $
+# $ISC: Makefile.in,v 1.54.18.4 2006/01/27 23:57:45 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -35,9 +35,9 @@ HEADERS = app.h assertions.h base64.h bitstring.h boolean.h buffer.h \
mutexblock.h netaddr.h ondestroy.h os.h parseint.h \
print.h quota.h random.h ratelimiter.h \
refcount.h region.h resource.h \
- result.h resultclass.h rwlock.h serial.h sha1.h sockaddr.h \
- socket.h stdio.h stdlib.h string.h symtab.h task.h taskpool.h \
- timer.h types.h util.h version.h
+ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
+ sockaddr.h socket.h stdio.h stdlib.h string.h symtab.h \
+ task.h taskpool.h timer.h types.h util.h version.h
SUBDIRS =
TARGETS =
diff --git a/usr.sbin/bind/lib/isc/include/isc/hash.h b/usr.sbin/bind/lib/isc/include/isc/hash.h
index c6a69aaf5d2..77fb0f16aae 100644
--- a/usr.sbin/bind/lib/isc/include/isc/hash.h
+++ b/usr.sbin/bind/lib/isc/include/isc/hash.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: hash.h,v 1.2.2.1.2.2 2004/03/06 08:14:41 marka Exp $ */
+/* $ISC: hash.h,v 1.4.18.2 2005/04/29 00:16:55 marka Exp $ */
#ifndef ISC_HASH_H
#define ISC_HASH_H 1
@@ -24,12 +24,10 @@
***** Module Info
*****/
-/*
- * Hash
- *
- * The hash API
+/*! \file
*
- * Provides an unpredictable hash value for variable length data.
+ * \brief The hash API
+ * provides an unpredictable hash value for variable length data.
* A hash object contains a random vector (which is hidden from clients
* of this API) to make the actual hash value unpredictable.
*
@@ -48,27 +46,27 @@
* it should be typical to have a single context for an entire system.
* To support such cases, the API also provides a single-context mode.
*
- * MP:
+ * \li MP:
* The hash object is almost read-only. Once the internal random vector
* is initialized, no write operation will occur, and there will be no
* need to lock the object to calculate actual hash values.
*
- * Reliability:
+ * \li Reliability:
* In some cases this module uses low-level data copy to initialize the
* random vector. Errors in this part are likely to crash the server or
* corrupt memory.
*
- * Resources:
+ * \li Resources:
* A buffer, used as a random vector for calculating hash values.
*
- * Security:
+ * \li Security:
* This module intends to provide unpredictable hash values in
* adversarial environments in order to avoid denial of service attacks
* to hash buckets.
* Its unpredictability relies on the quality of entropy to build the
* random vector.
*
- * Standards:
+ * \li Standards:
* None.
*/
@@ -88,10 +86,11 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, unsigned int limit,
isc_hash_t **hctx);
isc_result_t
isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit);
-/*
- * Create a new hash object.
+/*!<
+ * \brief Create a new hash object.
*
* isc_hash_ctxcreate() creates a different object.
+ *
* isc_hash_create() creates a module-internal object to support the
* single-context mode. It should be called only once.
*
@@ -105,15 +104,16 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit);
void
isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp);
-/*
- * Attach to a hash object.
+/*!<
+ * \brief Attach to a hash object.
+ *
* This function is only necessary for the multiple-context mode.
*/
void
isc_hash_ctxdetach(isc_hash_t **hctxp);
-/*
- * Detach from a hash object.
+/*!<
+ * \brief Detach from a hash object.
*
* This function is for the multiple-context mode, and takes a valid
* hash object as an argument.
@@ -121,19 +121,23 @@ isc_hash_ctxdetach(isc_hash_t **hctxp);
void
isc_hash_destroy(void);
-/*
- * This function is for the single-context mode, and is expected to be used
+/*!<
+ * \brief This function is for the single-context mode, and is expected to be used
* as a counterpart of isc_hash_create().
+ *
* A valid module-internal hash object must have been created, and this
* function should be called only once.
*/
+/*@{*/
void
isc_hash_ctxinit(isc_hash_t *hctx);
void
isc_hash_init(void);
-/*
- * Initialize a hash object. It fills in the random vector with a proper
+/*!<
+ * \brief Initialize a hash object.
+ *
+ * It fills in the random vector with a proper
* source of entropy, which is typically from the entropy object specified
* at the creation. Thus, it is desirable to call these functions after
* initializing the entropy object with some good entropy sources.
@@ -142,26 +146,31 @@ isc_hash_init(void);
*
* isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
* object as an argument.
+ *
* isc_hash_init() is for the single-context mode. A valid module-internal
* hash object must have been created, and this function should be called only
* once.
*/
+/*@}*/
+/*@{*/
unsigned int
isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
unsigned int keylen, isc_boolean_t case_sensitive);
unsigned int
isc_hash_calc(const unsigned char *key, unsigned int keylen,
isc_boolean_t case_sensitive);
-/*
- * Calculate a hash value.
+/*!<
+ * \brief Calculate a hash value.
*
* isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
* object as an argument.
+ *
* isc_hash_init() is for the single-context mode. A valid module-internal
* hash object must have been created.
*
* 'key' is the hash key, which is a variable length buffer.
+ *
* 'keylen' specifies the key length, which must not be larger than the limit
* specified for the corresponding hash object.
*
@@ -169,6 +178,7 @@ isc_hash_calc(const unsigned char *key, unsigned int keylen,
* case_sensitive values. It should typically be ISC_FALSE if the hash key
* is a DNS name.
*/
+/*@}*/
ISC_LANG_ENDDECLS
diff --git a/usr.sbin/bind/lib/isc/include/isc/log.h b/usr.sbin/bind/lib/isc/include/isc/log.h
index 9c2df1b9eb5..6873f9c605e 100644
--- a/usr.sbin/bind/lib/isc/include/isc/log.h
+++ b/usr.sbin/bind/lib/isc/include/isc/log.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,11 +15,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: log.h,v 1.39.2.4.2.7 2004/04/10 04:31:40 marka Exp $ */
+/* $ISC: log.h,v 1.47.18.3 2005/04/29 00:16:58 marka Exp $ */
#ifndef ISC_LOG_H
#define ISC_LOG_H 1
+/*! \file */
+
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h> /* XXXDCL NT */
@@ -29,29 +31,36 @@
#include <isc/platform.h>
#include <isc/types.h>
-/*
- * Severity levels, patterned after Unix's syslog levels.
+/*@{*/
+/*!
+ * \brief Severity levels, patterned after Unix's syslog levels.
*
- * ISC_LOG_DYNAMIC can only be used for defining channels with
- * isc_log_createchannel(), not to specify a level in isc_log_write().
*/
#define ISC_LOG_DEBUG(level) (level)
+/*!
+ * #ISC_LOG_DYNAMIC can only be used for defining channels with
+ * isc_log_createchannel(), not to specify a level in isc_log_write().
+ */
#define ISC_LOG_DYNAMIC 0
#define ISC_LOG_INFO (-1)
#define ISC_LOG_NOTICE (-2)
#define ISC_LOG_WARNING (-3)
#define ISC_LOG_ERROR (-4)
#define ISC_LOG_CRITICAL (-5)
+/*@}*/
-/*
- * Destinations.
+/*@{*/
+/*!
+ * \brief Destinations.
*/
#define ISC_LOG_TONULL 1
#define ISC_LOG_TOSYSLOG 2
#define ISC_LOG_TOFILE 3
#define ISC_LOG_TOFILEDESC 4
+/*@}*/
-/*
+/*@{*/
+/*%
* Channel flags.
*/
#define ISC_LOG_PRINTTIME 0x0001
@@ -62,18 +71,24 @@
#define ISC_LOG_PRINTALL 0x001F
#define ISC_LOG_DEBUGONLY 0x1000
#define ISC_LOG_OPENERR 0x8000 /* internal */
+/*@}*/
-/*
- * Other options.
+/*@{*/
+/*!
+ * \brief Other options.
+ *
* XXXDCL INFINITE doesn't yet work. Arguably it isn't needed, but
* since I am intend to make large number of versions work efficiently,
* INFINITE is going to be trivial to add to that.
*/
#define ISC_LOG_ROLLINFINITE (-1)
#define ISC_LOG_ROLLNEVER (-2)
+/*@}*/
-/*
- * Used to name the categories used by a library. An array of isc_logcategory
+/*!
+ * \brief Used to name the categories used by a library.
+ *
+ * An array of isc_logcategory
* structures names each category, and the id value is initialized by calling
* isc_log_registercategories.
*/
@@ -82,28 +97,30 @@ struct isc_logcategory {
unsigned int id;
};
-/*
- * Similar to isc_logcategory above, but for all the modules a library defines.
+/*%
+ * Similar to isc_logcategory, but for all the modules a library defines.
*/
struct isc_logmodule {
const char *name;
unsigned int id;
};
-/*
+/*%
* The isc_logfile structure is initialized as part of an isc_logdestination
- * before calling isc_log_createchannel(). When defining an ISC_LOG_TOFILE
+ * before calling isc_log_createchannel().
+ *
+ * When defining an #ISC_LOG_TOFILE
* channel the name, versions and maximum_size should be set before calling
- * isc_log_createchannel(). To define an ISC_LOG_TOFILEDESC channel set only
+ * isc_log_createchannel(). To define an #ISC_LOG_TOFILEDESC channel set only
* the stream before the call.
*
* Setting maximum_size to zero implies no maximum.
*/
typedef struct isc_logfile {
- FILE *stream; /* Initialized to NULL for ISC_LOG_TOFILE. */
- const char *name; /* NULL for ISC_LOG_TOFILEDESC. */
- int versions; /* >= 0, ISC_LOG_ROLLNEVER, ISC_LOG_ROLLINFINITE. */
- /*
+ FILE *stream; /*%< Initialized to NULL for #ISC_LOG_TOFILE. */
+ const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */
+ int versions; /* >= 0, #ISC_LOG_ROLLNEVER, #ISC_LOG_ROLLINFINITE. */
+ /*%
* stdio's ftell is standardized to return a long, which may well not
* be big enough for the largest file supportable by the operating
* system (though it is _probably_ big enough for the largest log
@@ -111,10 +128,10 @@ typedef struct isc_logfile {
* to a size large enough for the largest possible file on a system.
*/
isc_offset_t maximum_size;
- isc_boolean_t maximum_reached; /* Private. */
+ isc_boolean_t maximum_reached; /*%< Private. */
} isc_logfile_t;
-/*
+/*%
* Passed to isc_log_createchannel to define the attributes of either
* a stdio or a syslog log.
*/
@@ -123,7 +140,8 @@ typedef union isc_logdestination {
int facility; /* XXXDCL NT */
} isc_logdestination_t;
-/*
+/*@{*/
+/*%
* The built-in categories of libisc.
*
* Each library registering categories should provide library_LOGCATEGORY_name
@@ -133,13 +151,16 @@ typedef union isc_logdestination {
LIBISC_EXTERNAL_DATA extern isc_logcategory_t isc_categories[];
LIBISC_EXTERNAL_DATA extern isc_log_t *isc_lctx;
LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[];
+/*@}*/
-/*
+/*@{*/
+/*%
* Do not log directly to DEFAULT. Use another category. When in doubt,
* use GENERAL.
*/
#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0])
#define ISC_LOGCATEGORY_GENERAL (&isc_categories[1])
+/*@}*/
#define ISC_LOGMODULE_SOCKET (&isc_modules[0])
#define ISC_LOGMODULE_TIME (&isc_modules[1])
@@ -150,33 +171,33 @@ ISC_LANG_BEGINDECLS
isc_result_t
isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp);
-/*
+/*%<
* Establish a new logging context, with default channels.
*
* Notes:
- * isc_log_create calls isc_logconfig_create, so see its comment
+ *\li isc_log_create() calls isc_logconfig_create(), so see its comment
* below for more information.
*
* Requires:
- * mctx is a valid memory context.
- * lctxp is not null and *lctxp is null.
- * lcfgp is null or lcfgp is not null and *lcfgp is null.
+ *\li mctx is a valid memory context.
+ *\li lctxp is not null and *lctxp is null.
+ *\li lcfgp is null or lcfgp is not null and *lcfgp is null.
*
* Ensures:
- * *lctxp will point to a valid logging context if all of the necessary
+ *\li *lctxp will point to a valid logging context if all of the necessary
* memory was allocated, or NULL otherwise.
- * *lcfgp will point to a valid logging configuration if all of the
+ *\li *lcfgp will point to a valid logging configuration if all of the
* necessary memory was allocated, or NULL otherwise.
- * On failure, no additional memory is allocated.
+ *\li On failure, no additional memory is allocated.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
*/
isc_result_t
isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp);
-/*
+/*%<
* Create the data structure that holds all of the configurable information
* about where messages are actually supposed to be sent -- the information
* that could changed based on some configuration file, as opposed to the
@@ -184,190 +205,192 @@ isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp);
* into a program, or the debug_level which is dynamic state information.
*
* Notes:
- * It is necessary to specify the logging context the configuration
+ *\li It is necessary to specify the logging context the configuration
* will be used with because the number of categories and modules
* needs to be known in order to set the configuration. However,
* the configuration is not used by the logging context until the
* isc_logconfig_use function is called.
*
- * The memory context used for operations that allocate memory for
+ *\li The memory context used for operations that allocate memory for
* the configuration is that of the logging context, as specified
* in the isc_log_create call.
*
- * Four default channels are established:
+ *\li Four default channels are established:
+ *\verbatim
* default_syslog
- * - log to syslog's daemon facility ISC_LOG_INFO or higher
+ * - log to syslog's daemon facility #ISC_LOG_INFO or higher
* default_stderr
- * - log to stderr ISC_LOG_INFO or higher
+ * - log to stderr #ISC_LOG_INFO or higher
* default_debug
- * - log to stderr ISC_LOG_DEBUG dynamically
+ * - log to stderr #ISC_LOG_DEBUG dynamically
* null
* - log nothing
+ *\endverbatim
*
* Requires:
- * lctx is a valid logging context.
- * lcftp is not null and *lcfgp is null.
+ *\li lctx is a valid logging context.
+ *\li lcftp is not null and *lcfgp is null.
*
* Ensures:
- * *lcfgp will point to a valid logging context if all of the necessary
+ *\li *lcfgp will point to a valid logging context if all of the necessary
* memory was allocated, or NULL otherwise.
- * On failure, no additional memory is allocated.
+ *\li On failure, no additional memory is allocated.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
*/
isc_logconfig_t *
isc_logconfig_get(isc_log_t *lctx);
-/*
+/*%<
* Returns a pointer to the configuration currently in use by the log context.
*
* Requires:
- * lctx is a valid context.
+ *\li lctx is a valid context.
*
* Ensures:
- * The configuration pointer is non-null.
+ *\li The configuration pointer is non-null.
*
* Returns:
- * The configuration pointer.
+ *\li The configuration pointer.
*/
isc_result_t
isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg);
-/*
+/*%<
* Associate a new configuration with a logging context.
*
* Notes:
- * This is thread safe. The logging context will lock a mutex
+ *\li This is thread safe. The logging context will lock a mutex
* before attempting to swap in the new configuration, and isc_log_doit
* (the internal function used by all of isc_log_[v]write[1]) locks
* the same lock for the duration of its use of the configuration.
*
* Requires:
- * lctx is a valid logging context.
- * lcfg is a valid logging configuration.
- * lctx is the same configuration given to isc_logconfig_create
+ *\li lctx is a valid logging context.
+ *\li lcfg is a valid logging configuration.
+ *\li lctx is the same configuration given to isc_logconfig_create
* when the configuration was created.
*
* Ensures:
- * Future calls to isc_log_write will use the new configuration.
+ *\li Future calls to isc_log_write will use the new configuration.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
*/
void
isc_log_destroy(isc_log_t **lctxp);
-/*
+/*%<
* Deallocate the memory associated with a logging context.
*
* Requires:
- * *lctx is a valid logging context.
+ *\li *lctx is a valid logging context.
*
* Ensures:
- * All of the memory associated with the logging context is returned
+ *\li All of the memory associated with the logging context is returned
* to the free memory pool.
*
- * Any open files are closed.
+ *\li Any open files are closed.
*
- * The logging context is marked as invalid.
+ *\li The logging context is marked as invalid.
*/
void
isc_logconfig_destroy(isc_logconfig_t **lcfgp);
-/*
+/*%<
* Destroy a logging configuration.
*
* Notes:
- * This function cannot be used directly with the return value of
+ *\li This function cannot be used directly with the return value of
* isc_logconfig_get, because a logging context must always have
* a valid configuration associated with it.
*
* Requires:
- * lcfgp is not null and *lcfgp is a valid logging configuration.
- * The logging configuration is not in use by an existing logging context.
+ *\li lcfgp is not null and *lcfgp is a valid logging configuration.
+ *\li The logging configuration is not in use by an existing logging context.
*
* Ensures:
- * All memory allocated for the configuration is freed.
+ *\li All memory allocated for the configuration is freed.
*
- * The configuration is marked as invalid.
+ *\li The configuration is marked as invalid.
*/
void
isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]);
-/*
+/*%<
* Identify logging categories a library will use.
*
* Notes:
- * A category should only be registered once, but no mechanism enforces
+ *\li A category should only be registered once, but no mechanism enforces
* this rule.
*
- * The end of the categories array is identified by a NULL name.
+ *\li The end of the categories array is identified by a NULL name.
*
- * Because the name is used by ISC_LOG_PRINTCATEGORY, it should not
+ *\li Because the name is used by #ISC_LOG_PRINTCATEGORY, it should not
* be altered or destroyed after isc_log_registercategories().
*
- * Because each element of the categories array is used by
+ *\li Because each element of the categories array is used by
* isc_log_categorybyname, it should not be altered or destroyed
* after registration.
*
- * The value of the id integer in each structure is overwritten
+ *\li The value of the id integer in each structure is overwritten
* by this function, and so id need not be initialized to any particular
* value prior to the function call.
*
- * A subsequent call to isc_log_registercategories with the same
+ *\li A subsequent call to isc_log_registercategories with the same
* logging context (but new categories) will cause the last
* element of the categories array from the prior call to have
* its "name" member changed from NULL to point to the new
* categories array, and its "id" member set to UINT_MAX.
*
* Requires:
- * lctx is a valid logging context.
- * categories != NULL.
- * categories[0].name != NULL.
+ *\li lctx is a valid logging context.
+ *\li categories != NULL.
+ *\li categories[0].name != NULL.
*
* Ensures:
- * There are references to each category in the logging context,
+ * \li There are references to each category in the logging context,
* so they can be used with isc_log_usechannel() and isc_log_write().
*/
void
isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]);
-/*
+/*%<
* Identify logging categories a library will use.
*
* Notes:
- * A module should only be registered once, but no mechanism enforces
+ *\li A module should only be registered once, but no mechanism enforces
* this rule.
*
- * The end of the modules array is identified by a NULL name.
+ *\li The end of the modules array is identified by a NULL name.
*
- * Because the name is used by ISC_LOG_PRINTMODULE, it should not
+ *\li Because the name is used by #ISC_LOG_PRINTMODULE, it should not
* be altered or destroyed after isc_log_registermodules().
*
- * Because each element of the modules array is used by
+ *\li Because each element of the modules array is used by
* isc_log_modulebyname, it should not be altered or destroyed
* after registration.
*
- * The value of the id integer in each structure is overwritten
+ *\li The value of the id integer in each structure is overwritten
* by this function, and so id need not be initialized to any particular
* value prior to the function call.
*
- * A subsequent call to isc_log_registermodules with the same
+ *\li A subsequent call to isc_log_registermodules with the same
* logging context (but new modules) will cause the last
* element of the modules array from the prior call to have
* its "name" member changed from NULL to point to the new
* modules array, and its "id" member set to UINT_MAX.
*
* Requires:
- * lctx is a valid logging context.
- * modules != NULL.
- * modules[0].name != NULL;
+ *\li lctx is a valid logging context.
+ *\li modules != NULL.
+ *\li modules[0].name != NULL;
*
* Ensures:
- * Each module has a reference in the logging context, so they can be
+ *\li Each module has a reference in the logging context, so they can be
* used with isc_log_usechannel() and isc_log_write().
*/
@@ -376,68 +399,67 @@ isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
unsigned int type, int level,
const isc_logdestination_t *destination,
unsigned int flags);
-/*
+/*%<
* Specify the parameters of a logging channel.
*
* Notes:
- * The name argument is copied to memory in the logging context, so
+ *\li The name argument is copied to memory in the logging context, so
* it can be altered or destroyed after isc_log_createchannel().
*
- * Defining a very large number of channels will have a performance
+ *\li Defining a very large number of channels will have a performance
* impact on isc_log_usechannel(), since the names are searched
* linearly until a match is made. This same issue does not affect
* isc_log_write, however.
*
- * Channel names can be redefined; this is primarily useful for programs
+ *\li Channel names can be redefined; this is primarily useful for programs
* that want their own definition of default_syslog, default_debug
* and default_stderr.
*
- * Any channel that is redefined will not affect logging that was
+ *\li Any channel that is redefined will not affect logging that was
* already directed to its original definition, _except_ for the
* default_stderr channel. This case is handled specially so that
* the default logging category can be changed by redefining
* default_stderr. (XXXDCL Though now that I think of it, the default
* logging category can be changed with only one additional function
* call by defining a new channel and then calling isc_log_usechannel()
- * for ISC_LOGCATEGORY_DEFAULT.)
+ * for #ISC_LOGCATEGORY_DEFAULT.)
*
- * Specifying ISC_LOG_PRINTTIME or ISC_LOG_PRINTTAG for syslog is allowed,
+ *\li Specifying #ISC_LOG_PRINTTIME or #ISC_LOG_PRINTTAG for syslog is allowed,
* but probably not what you wanted to do.
*
- * ISC_LOG_DEBUGONLY will mark the channel as usable only when the
+ * #ISC_LOG_DEBUGONLY will mark the channel as usable only when the
* debug level of the logging context (see isc_log_setdebuglevel)
* is non-zero.
*
* Requires:
- * lcfg is a valid logging configuration.
+ *\li lcfg is a valid logging configuration.
*
- * name is not NULL.
+ *\li name is not NULL.
*
- * type is ISC_LOG_TOSYSLOG, ISC_LOG_TOFILE, ISC_LOG_TOFILEDESC or
- * ISC_LOG_TONULL.
+ *\li type is #ISC_LOG_TOSYSLOG, #ISC_LOG_TOFILE, #ISC_LOG_TOFILEDESC or
+ * #ISC_LOG_TONULL.
*
- * destination is not NULL unless type is ISC_LOG_TONULL.
+ *\li destination is not NULL unless type is #ISC_LOG_TONULL.
*
- * level is >= ISC_LOG_CRITICAL (the most negative logging level).
+ *\li level is >= #ISC_LOG_CRITICAL (the most negative logging level).
*
- * flags does not include any bits aside from the ISC_LOG_PRINT* bits
- * or ISC_LOG_DEBUGONLY.
+ *\li flags does not include any bits aside from the ISC_LOG_PRINT* bits
+ * or #ISC_LOG_DEBUGONLY.
*
* Ensures:
- * ISC_R_SUCCESS
+ *\li #ISC_R_SUCCESS
* A channel with the given name is usable with
* isc_log_usechannel().
*
- * ISC_R_NOMEMORY or ISC_R_UNEXPECTED
+ *\li #ISC_R_NOMEMORY or #ISC_R_UNEXPECTED
* No additional memory is being used by the logging context.
- *
* Any channel that previously existed with the given name
* is not redefined.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource limit: Out of memory
- * ISC_R_UNEXPECTED type was out of range and REQUIRE()
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_UNEXPECTED type was out of range and REQUIRE()
* was disabled.
*/
@@ -445,166 +467,186 @@ isc_result_t
isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
const isc_logcategory_t *category,
const isc_logmodule_t *module);
-/*
+/*%<
* Associate a named logging channel with a category and module that
* will use it.
*
* Notes:
- * The name is searched for linearly in the set of known channel names
+ *\li The name is searched for linearly in the set of known channel names
* until a match is found. (Note the performance impact of a very large
* number of named channels.) When multiple channels of the same
* name are defined, the most recent definition is found.
*
- * Specifing a very large number of channels for a category will have
+ *\li Specifing a very large number of channels for a category will have
* a moderate impact on performance in isc_log_write(), as each
* call looks up the category for the start of a linked list, which
* it follows all the way to the end to find matching modules. The
* test for matching modules is integral, though.
*
- * If category is NULL, then the channel is associated with the indicated
+ *\li If category is NULL, then the channel is associated with the indicated
* module for all known categories (including the "default" category).
*
- * If module is NULL, then the channel is associated with every module
+ *\li If module is NULL, then the channel is associated with every module
* that uses that category.
*
- * Passing both category and module as NULL would make every log message
+ *\li Passing both category and module as NULL would make every log message
* use the indicated channel.
*
- * Specifying a channel that is ISC_LOG_TONULL for a category/module pair
+ * \li Specifying a channel that is #ISC_LOG_TONULL for a category/module pair
* has no effect on any other channels associated with that pair,
* regardless of ordering. Thus you cannot use it to "mask out" one
* category/module pair when you have specified some other channel that
* is also used by that category/module pair.
*
* Requires:
- * lcfg is a valid logging configuration.
+ *\li lcfg is a valid logging configuration.
*
- * category is NULL or has an id that is in the range of known ids.
+ *\li category is NULL or has an id that is in the range of known ids.
*
* module is NULL or has an id that is in the range of known ids.
*
* Ensures:
- * ISC_R_SUCCESS
+ *\li #ISC_R_SUCCESS
* The channel will be used by the indicated category/module
* arguments.
*
- * ISC_R_NOMEMORY
+ *\li #ISC_R_NOMEMORY
* If assignment for a specific category has been requested,
* the channel has not been associated with the indicated
* category/module arguments and no additional memory is
* used by the logging context.
- *
* If assignment for all categories has been requested
* then _some_ may have succeeded (starting with category
* "default" and progressing through the order of categories
- * passed to isc_log_registercategories) and additional memory
+ * passed to isc_log_registercategories()) and additional memory
* is being used by whatever assignments succeeded.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
*/
-void
-isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
- isc_logmodule_t *module, int level,
- const char *format, ...)
-ISC_FORMAT_PRINTF(5, 6);
-/*
+/* Attention: next four comments PRECEED code */
+/*!
+ * \brief
* Write a message to the log channels.
*
* Notes:
- * Log messages containing natural language text should be logged with
+ *\li Log messages containing natural language text should be logged with
* isc_log_iwrite() to allow for localization.
*
- * lctx can be NULL; this is allowed so that programs which use
+ *\li lctx can be NULL; this is allowed so that programs which use
* libraries that use the ISC logging system are not required to
* also use it.
*
- * The format argument is a printf(3) string, with additional arguments
+ *\li The format argument is a printf(3) string, with additional arguments
* as necessary.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*
- * The category and module arguments must have ids that are in the
+ *\li The category and module arguments must have ids that are in the
* range of known ids, as estabished by isc_log_registercategories()
* and isc_log_registermodules().
*
- * level != ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
* channels, and explicit debugging level must be identified for
* isc_log_write() via ISC_LOG_DEBUG(level).
*
- * format != NULL.
+ *\li format != NULL.
*
* Ensures:
- * The log message is written to every channel associated with the
+ *\li The log message is written to every channel associated with the
* indicated category/module pair.
*
* Returns:
- * Nothing. Failure to log a message is not construed as a
+ *\li Nothing. Failure to log a message is not construed as a
* meaningful error.
*/
-
void
-isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level,
- const char *format, va_list args)
-ISC_FORMAT_PRINTF(5, 0);
-/*
+ const char *format, ...)
+
+ISC_FORMAT_PRINTF(5, 6);
+
+/*%
* Write a message to the log channels.
*
* Notes:
- * lctx can be NULL; this is allowed so that programs which use
+ *\li lctx can be NULL; this is allowed so that programs which use
* libraries that use the ISC logging system are not required to
* also use it.
*
- * The format argument is a printf(3) string, with additional arguments
+ *\li The format argument is a printf(3) string, with additional arguments
* as necessary.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*
- * The category and module arguments must have ids that are in the
+ *\li The category and module arguments must have ids that are in the
* range of known ids, as estabished by isc_log_registercategories()
* and isc_log_registermodules().
*
- * level != ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
* channels, and explicit debugging level must be identified for
* isc_log_write() via ISC_LOG_DEBUG(level).
*
- * format != NULL.
+ *\li format != NULL.
*
* Ensures:
- * The log message is written to every channel associated with the
+ *\li The log message is written to every channel associated with the
* indicated category/module pair.
*
* Returns:
- * Nothing. Failure to log a message is not construed as a
+ *\li Nothing. Failure to log a message is not construed as a
* meaningful error.
*/
+void
+isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+
+ISC_FORMAT_PRINTF(5, 0);
+/*%
+ * Write a message to the log channels, pruning duplicates that occur within
+ * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
+ * This function is otherwise identical to isc_log_write().
+ */
void
isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level, const char *format, ...)
+
ISC_FORMAT_PRINTF(5, 6);
-/*
+
+/*%
* Write a message to the log channels, pruning duplicates that occur within
* a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
- * This function is otherwise identical to isc_log_write().
+ * This function is otherwise identical to isc_log_vwrite().
*/
-
void
isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level, const char *format,
va_list args)
+
ISC_FORMAT_PRINTF(5, 0);
-/*
- * Write a message to the log channels, pruning duplicates that occur within
- * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
- * This function is otherwise identical to isc_log_vwrite().
- */
+/*%
+ * These are four internationalized versions of the the isc_log_[v]write[1]
+ * functions.
+ *
+ * The only difference is that they take arguments for a message
+ * catalog, message set, and message number, all immediately preceding the
+ * format argument. The format argument becomes the default text, a la
+ * isc_msgcat_get. If the message catalog is NULL, no lookup is attempted
+ * for a message -- which makes the message set and message number irrelevant,
+ * and the non-internationalized call should have probably been used instead.
+ *
+ * Yes, that means there are now *eight* interfaces to logging a message.
+ * Sheesh. Make the madness stop!
+ */
+/*@{*/
void
isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
isc_logmodule_t *module, int level,
@@ -632,72 +674,61 @@ isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
isc_msgcat_t *msgcat, int msgset, int message,
const char *format, va_list args)
ISC_FORMAT_PRINTF(8, 0);
-/*
- * These are four internationalized versions of the the isc_log_[v]write[1]
- * functions. The only difference is that they take arguments for a message
- * catalog, message set, and message number, all immediately preceding the
- * format argument. The format argument becomes the default text, a la
- * isc_msgcat_get. If the message catalog is NULL, no lookup is attempted
- * for a message -- which makes the message set and message number irrelevant,
- * and the non-internationalized call should have probably been used instead.
- *
- * Yes, that means there are now *eight* interfaces to logging a message.
- * Sheesh. Make the madness stop!
- */
+/*@}*/
void
isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level);
-/*
+/*%<
* Set the debugging level used for logging.
*
* Notes:
- * Setting the debugging level to 0 disables debugging log messages.
+ *\li Setting the debugging level to 0 disables debugging log messages.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*
* Ensures:
- * The debugging level is set to the requested value.
+ *\li The debugging level is set to the requested value.
*/
unsigned int
isc_log_getdebuglevel(isc_log_t *lctx);
-/*
+/*%<
* Get the current debugging level.
*
* Notes:
- * This is provided so that a program can have a notion of
+ *\li This is provided so that a program can have a notion of
* "increment debugging level" or "decrement debugging level"
* without needing to keep track of what the current level is.
*
- * A return value of 0 indicates that debugging messages are disabled.
+ *\li A return value of 0 indicates that debugging messages are disabled.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*
* Ensures:
- * The current logging debugging level is returned.
+ *\li The current logging debugging level is returned.
*/
isc_boolean_t
isc_log_wouldlog(isc_log_t *lctx, int level);
-/*
+/*%<
* Determine whether logging something to 'lctx' at 'level' would
* actually cause something to be logged somewhere.
*
- * If ISC_FALSE is returned, it is guaranteed that nothing would
+ * If #ISC_FALSE is returned, it is guaranteed that nothing would
* be logged, allowing the caller to omit unnecessary
* isc_log_write() calls and possible message preformatting.
*/
void
isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval);
-/*
+/*%<
* Set the interval over which duplicate log messages will be ignored
* by isc_log_[v]write1(), in seconds.
*
* Notes:
- * Increasing the duplicate interval from X to Y will not necessarily
+ *\li Increasing the duplicate interval from X to Y will not necessarily
* filter out duplicates of messages logged in Y - X seconds since the
* increase. (Example: Message1 is logged at midnight. Message2
* is logged at 00:01:00, when the interval is only 30 seconds, causing
@@ -707,43 +738,43 @@ isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval);
* passed since the first occurrence.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*/
unsigned int
isc_log_getduplicateinterval(isc_logconfig_t *lcfg);
-/*
+/*%<
* Get the current duplicate filtering interval.
*
* Requires:
- * lctx is a valid logging context.
+ *\li lctx is a valid logging context.
*
* Returns:
- * The current duplicate filtering interval.
+ *\li The current duplicate filtering interval.
*/
isc_result_t
isc_log_settag(isc_logconfig_t *lcfg, const char *tag);
-/*
- * Set the program name or other identifier for ISC_LOG_PRINTTAG.
+/*%<
+ * Set the program name or other identifier for #ISC_LOG_PRINTTAG.
*
* Requires:
- * lcfg is a valid logging configuration.
+ *\li lcfg is a valid logging configuration.
*
* Notes:
- * If this function has not set the tag to a non-NULL, non-empty value,
- * then the ISC_LOG_PRINTTAG channel flag will not print anything.
+ *\li If this function has not set the tag to a non-NULL, non-empty value,
+ * then the #ISC_LOG_PRINTTAG channel flag will not print anything.
* Unlike some implementations of syslog on Unix systems, you *must* set
* the tag in order to get it logged. It is not implicitly derived from
* the program name (which is pretty impossible to infer portably).
*
- * Setting the tag to NULL or the empty string will also cause the
- * ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the
+ *\li Setting the tag to NULL or the empty string will also cause the
+ * #ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the
* empty string, calls to isc_log_gettag will return NULL.
*
* Returns:
- * ISC_R_SUCCESS Success
- * ISC_R_NOMEMORY Resource Limit: Out of memory
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource Limit: Out of memory
*
* XXXDCL when creating a new isc_logconfig_t, it might be nice if the tag
* of the currently active isc_logconfig_t was inherited. this does not
@@ -752,33 +783,35 @@ isc_log_settag(isc_logconfig_t *lcfg, const char *tag);
char *
isc_log_gettag(isc_logconfig_t *lcfg);
-/*
- * Get the current identifier printed with ISC_LOG_PRINTTAG.
+/*%<
+ * Get the current identifier printed with #ISC_LOG_PRINTTAG.
*
* Requires:
- * lcfg is a valid logging configuration.
+ *\li lcfg is a valid logging configuration.
*
* Notes:
- * Since isc_log_settag() will not associate a zero-length string
+ *\li Since isc_log_settag() will not associate a zero-length string
* with the logging configuration, attempts to do so will cause
* this function to return NULL. However, a determined programmer
* will observe that (currently) a tag of length greater than zero
* could be set, and then modified to be zero length.
*
* Returns:
- * A pointer to the current identifier, or NULL if none has been set.
+ *\li A pointer to the current identifier, or NULL if none has been set.
*/
void
isc_log_opensyslog(const char *tag, int options, int facility);
-/*
+/*%<
* Initialize syslog logging.
*
* Notes:
- * XXXDCL NT
+ *\li XXXDCL NT
* This is currently equivalent to openlog(), but is not going to remain
* that way. In the meantime, the arguments are all identical to
* those used by openlog(3), as follows:
+ *
+ * \code
* tag: The string to use in the position of the program
* name in syslog messages. Most (all?) syslogs
* will use basename(argv[0]) if tag is NULL.
@@ -789,89 +822,90 @@ isc_log_opensyslog(const char *tag, int options, int facility);
* facility: The default syslog facility. This is irrelevant
* since isc_log_write will ALWAYS use the channel's
* declared facility.
+ * \endcode
*
- * Zero effort has been made (yet) to accomodate systems with openlog()
+ *\li Zero effort has been made (yet) to accomodate systems with openlog()
* that only takes two arguments, or to identify valid syslog
* facilities or options for any given architecture.
*
- * It is necessary to call isc_log_opensyslog() to initialize
+ *\li It is necessary to call isc_log_opensyslog() to initialize
* syslogging on machines which do not support network connections to
* syslogd because they require a Unix domain socket to be used. Since
* this is a chore to determine at run-time, it is suggested that it
* always be called by programs using the ISC logging system.
*
* Requires:
- * Nothing.
+ *\li Nothing.
*
* Ensures:
- * openlog() is called to initialize the syslog system.
+ *\li openlog() is called to initialize the syslog system.
*/
void
isc_log_closefilelogs(isc_log_t *lctx);
-/*
- * Close all open files used by ISC_LOG_TOFILE channels.
+/*%<
+ * Close all open files used by #ISC_LOG_TOFILE channels.
*
* Notes:
- * This function is provided for programs that want to use their own
+ *\li This function is provided for programs that want to use their own
* log rolling mechanism rather than the one provided internally.
* For example, a program that wanted to keep daily logs would define
- * a channel which used ISC_LOG_ROLLNEVER, then once a day would
+ * a channel which used #ISC_LOG_ROLLNEVER, then once a day would
* rename the log file and call isc_log_closefilelogs().
*
- * ISC_LOG_TOFILEDESC channels are unaffected.
+ *\li #ISC_LOG_TOFILEDESC channels are unaffected.
*
* Requires:
- * lctx is a valid context.
+ *\li lctx is a valid context.
*
* Ensures:
- * The open files are closed and will be reopened when they are
+ *\li The open files are closed and will be reopened when they are
* next needed.
*/
isc_logcategory_t *
isc_log_categorybyname(isc_log_t *lctx, const char *name);
-/*
+/*%<
* Find a category by its name.
*
* Notes:
- * The string name of a category is not required to be unique.
+ *\li The string name of a category is not required to be unique.
*
* Requires:
- * lctx is a valid context.
- * name is not NULL.
+ *\li lctx is a valid context.
+ *\li name is not NULL.
*
* Returns:
- * A pointer to the _first_ isc_logcategory_t structure used by "name".
+ *\li A pointer to the _first_ isc_logcategory_t structure used by "name".
*
- * NULL if no category exists by that name.
+ *\li NULL if no category exists by that name.
*/
isc_logmodule_t *
isc_log_modulebyname(isc_log_t *lctx, const char *name);
-/*
+/*%<
* Find a module by its name.
*
* Notes:
- * The string name of a module is not required to be unique.
+ *\li The string name of a module is not required to be unique.
*
* Requires:
- * lctx is a valid context.
- * name is not NULL.
+ *\li lctx is a valid context.
+ *\li name is not NULL.
*
* Returns:
- * A pointer to the _first_ isc_logmodule_t structure used by "name".
+ *\li A pointer to the _first_ isc_logmodule_t structure used by "name".
*
- * NULL if no module exists by that name.
+ *\li NULL if no module exists by that name.
*/
void
isc_log_setcontext(isc_log_t *lctx);
-/*
+/*%<
* Sets the context used by the libisc for logging.
*
* Requires:
- * lctx be a valid context.
+ *\li lctx be a valid context.
*/
ISC_LANG_ENDDECLS
diff --git a/usr.sbin/bind/lib/isc/include/isc/platform.h.in b/usr.sbin/bind/lib/isc/include/isc/platform.h.in
index 2ebd5cb2636..125dfca86aa 100644
--- a/usr.sbin/bind/lib/isc/include/isc/platform.h.in
+++ b/usr.sbin/bind/lib/isc/include/isc/platform.h.in
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,208 +15,259 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: platform.h.in,v 1.24.2.1.10.11 2004/03/08 09:04:52 marka Exp $ */
+/* $ISC: platform.h.in,v 1.34.18.9 2007/09/13 05:04:01 each Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
+/*! \file */
+
/*****
***** Platform-dependent defines.
*****/
+/*
+ * Define if the platform has <strings.h>.
+ */
+@ISC_PLATFORM_HAVESTRINGSH@
+
/***
*** Network.
***/
-/*
+/*! \brief
* Define if this system needs the <netinet/in6.h> header file included
* for full IPv6 support (pretty much only UnixWare).
*/
@ISC_PLATFORM_NEEDNETINETIN6H@
-/*
+/*! \brief
* Define if this system needs the <netinet6/in6.h> header file included
* to support in6_pkinfo (pretty much only BSD/OS).
*/
@ISC_PLATFORM_NEEDNETINET6IN6H@
-/*
+/*! \brief
* If sockaddrs on this system have an sa_len field, ISC_PLATFORM_HAVESALEN
* will be defined.
*/
@ISC_PLATFORM_HAVESALEN@
-/*
+/*! \brief
* If this system has the IPv6 structure definitions, ISC_PLATFORM_HAVEIPV6
* will be defined.
*/
@ISC_PLATFORM_HAVEIPV6@
-/*
+/*! \brief
* If this system is missing in6addr_any, ISC_PLATFORM_NEEDIN6ADDRANY will
* be defined.
*/
@ISC_PLATFORM_NEEDIN6ADDRANY@
-/*
+/*! \brief
* If this system is missing in6addr_loopback, ISC_PLATFORM_NEEDIN6ADDRLOOPBACK
* will be defined.
*/
@ISC_PLATFORM_NEEDIN6ADDRLOOPBACK@
-/*
+/*! \brief
* If this system has in6_pktinfo, ISC_PLATFORM_HAVEIN6PKTINFO will be
* defined.
*/
@ISC_PLATFORM_HAVEIN6PKTINFO@
-/*
+/*! \brief
* If this system has in_addr6, rather than in6_addr, ISC_PLATFORM_HAVEINADDR6
* will be defined.
*/
@ISC_PLATFORM_HAVEINADDR6@
-/*
+/*! \brief
* If this system has sin6_scope_id, ISC_PLATFORM_HAVESCOPEID will be defined.
*/
@ISC_PLATFORM_HAVESCOPEID@
-/*
+/*! \brief
* If this system needs inet_ntop(), ISC_PLATFORM_NEEDNTOP will be defined.
*/
@ISC_PLATFORM_NEEDNTOP@
-/*
+/*! \brief
* If this system needs inet_pton(), ISC_PLATFORM_NEEDPTON will be defined.
*/
@ISC_PLATFORM_NEEDPTON@
-/*
+/*! \brief
* If this system needs inet_aton(), ISC_PLATFORM_NEEDATON will be defined.
*/
@ISC_PLATFORM_NEEDATON@
-/*
+/*! \brief
* If this system needs in_port_t, ISC_PLATFORM_NEEDPORTT will be defined.
*/
@ISC_PLATFORM_NEEDPORTT@
-/*
+/*! \brief
* If the system needs strsep(), ISC_PLATFORM_NEEDSTRSEP will be defined.
*/
@ISC_PLATFORM_NEEDSTRSEP@
-/*
+/*! \brief
* If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined.
*/
@ISC_PLATFORM_NEEDSTRLCPY@
-/*
+/*! \brief
* If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined.
*/
@ISC_PLATFORM_NEEDSTRLCAT@
-/*
+/*! \brief
* Define either ISC_PLATFORM_BSD44MSGHDR or ISC_PLATFORM_BSD43MSGHDR.
*/
@ISC_PLATFORM_MSGHDRFLAVOR@
-/*
+/*! \brief
* Define if PTHREAD_ONCE_INIT should be surrounded by braces to
* prevent compiler warnings (such as with gcc on Solaris 2.8).
*/
@ISC_PLATFORM_BRACEPTHREADONCEINIT@
-/*
+/*! \brief
* Define on some UnixWare systems to fix erroneous definitions of various
* IN6_IS_ADDR_* macros.
*/
@ISC_PLATFORM_FIXIN6ISADDR@
-/***
+/*
*** Printing.
***/
-/*
+/*! \brief
* If this system needs vsnprintf() and snprintf(), ISC_PLATFORM_NEEDVSNPRINTF
* will be defined.
*/
@ISC_PLATFORM_NEEDVSNPRINTF@
-/*
+/*! \brief
* If this system need a modern sprintf() that returns (int) not (char*).
*/
@ISC_PLATFORM_NEEDSPRINTF@
-/*
+/*! \brief
* The printf format string modifier to use with isc_uint64_t values.
*/
@ISC_PLATFORM_QUADFORMAT@
-/*
+/*! \brief
* Defined if we are using threads.
*/
@ISC_PLATFORM_USETHREADS@
-/*
+/*! \brief
* Defined if unistd.h does not cause fd_set to be delared.
*/
@ISC_PLATFORM_NEEDSYSSELECTH@
-/*
+/*! \brief
* Type used for resource limits.
*/
@ISC_PLATFORM_RLIMITTYPE@
-/*
+/*! \brief
* Define if your compiler supports "long long int".
*/
@ISC_PLATFORM_HAVELONGLONG@
-/*
+/*! \brief
* Define if the system has struct lifconf which is a extended struct ifconf
* for IPv6.
*/
@ISC_PLATFORM_HAVELIFCONF@
-/*
+/*! \brief
* Define if the system has struct if_laddrconf which is a extended struct
* ifconf for IPv6.
*/
@ISC_PLATFORM_HAVEIF_LADDRCONF@
-/*
+/*! \brief
* Define if the system has struct if_laddrreq.
*/
@ISC_PLATFORM_HAVEIF_LADDRREQ@
-/*
+/*! \brief
* Used to control how extern data is linked; needed for Win32 platforms.
*/
@ISC_PLATFORM_USEDECLSPEC@
-/*
+/*! \brief
* Define if the system supports if_nametoindex.
*/
@ISC_PLATFORM_HAVEIFNAMETOINDEX@
-/*
+/*! \brief
* Define if this system needs strtoul.
*/
@ISC_PLATFORM_NEEDSTRTOUL@
-/*
+/*! \brief
* Define if this system needs memmove.
*/
@ISC_PLATFORM_NEEDMEMMOVE@
+/*
+ * Define if the platform has <sys/un.h>.
+ */
+@ISC_PLATFORM_HAVESYSUNH@
+
+/*
+ * If the "xadd" operation is available on this architecture,
+ * ISC_PLATFORM_HAVEXADD will be defined.
+ */
+@ISC_PLATFORM_HAVEXADD@
+
+/*
+ * If the "atomic swap" operation is available on this architecture,
+ * ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
+ */
+@ISC_PLATFORM_HAVEATOMICSTORE@
+
+/*
+ * If the "compare-and-exchange" operation is available on this architecture,
+ * ISC_PLATFORM_HAVECMPXCHG will be defined.
+ */
+@ISC_PLATFORM_HAVECMPXCHG@
+
+/*
+ * Define if gcc ASM extension is available
+ */
+@ISC_PLATFORM_USEGCCASM@
+
+/*
+ * Define if Tru64 style ASM syntax must be used.
+ */
+@ISC_PLATFORM_USEOSFASM@
+
+/*
+ * Define if the standard __asm function must be used.
+ */
+@ISC_PLATFORM_USESTDASM@
+
+/*
+ * Define if MacOS style of PPC assembly must be used.
+ * e.g. "r6", not "6", for register six.
+ */
+@ISC_PLATFORM_USEMACASM@
+
#ifndef ISC_PLATFORM_USEDECLSPEC
#define LIBISC_EXTERNAL_DATA
#define LIBDNS_EXTERNAL_DATA
#define LIBISCCC_EXTERNAL_DATA
#define LIBISCCFG_EXTERNAL_DATA
#define LIBBIND9_EXTERNAL_DATA
-#else /* ISC_PLATFORM_USEDECLSPEC */
+#else /*! \brief ISC_PLATFORM_USEDECLSPEC */
#ifdef LIBISC_EXPORTS
#define LIBISC_EXTERNAL_DATA __declspec(dllexport)
#else
@@ -242,7 +293,7 @@
#else
#define LIBBIND9_EXTERNAL_DATA __declspec(dllimport)
#endif
-#endif /* ISC_PLATFORM_USEDECLSPEC */
+#endif /*! \brief ISC_PLATFORM_USEDECLSPEC */
/*
* Tell emacs to use C mode for this file.
diff --git a/usr.sbin/bind/lib/isc/include/isc/refcount.h b/usr.sbin/bind/lib/isc/include/isc/refcount.h
index 0e1ebf2e288..8dd87399762 100644
--- a/usr.sbin/bind/lib/isc/include/isc/refcount.h
+++ b/usr.sbin/bind/lib/isc/include/isc/refcount.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,19 +15,22 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: refcount.h,v 1.3.2.2.2.2 2004/04/14 05:12:25 marka Exp $ */
+/* $ISC: refcount.h,v 1.6.18.5 2005/07/12 01:22:31 marka Exp $ */
#ifndef ISC_REFCOUNT_H
#define ISC_REFCOUNT_H 1
+#include <isc/atomic.h>
#include <isc/lang.h>
#include <isc/mutex.h>
#include <isc/platform.h>
#include <isc/types.h>
#include <isc/util.h>
-/*
- * Implements a locked reference counter. These functions may actually be
+/*! \file
+ * \brief Implements a locked reference counter.
+ *
+ * These functions may actually be
* implemented using macros, and implementations of these macros are below.
* The isc_refcount_t type should not be accessed directly, as its contents
* depend on the implementation.
@@ -39,8 +42,8 @@ ISC_LANG_BEGINDECLS
* Function prototypes
*/
-/*
- * void
+/*
+ * isc_result_t
* isc_refcount_init(isc_refcount_t *ref, unsigned int n);
*
* Initialize the reference counter. There will be 'n' initial references.
@@ -63,9 +66,14 @@ ISC_LANG_BEGINDECLS
/*
* void
* isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp);
+ * isc_refcount_increment0(isc_refcount_t *ref, unsigned int *targetp);
*
* Increments the reference count, returning the new value in targetp if it's
- * not NULL.
+ * not NULL. The reference counter typically begins with the initial counter
+ * of 1, and will be destroyed once the counter reaches 0. Thus,
+ * isc_refcount_increment() additionally requires the previous counter be
+ * larger than 0 so that an error which violates the usage can be easily
+ * caught. isc_refcount_increment0() does not have this restriction.
*
* Requires:
* ref != NULL.
@@ -87,20 +95,54 @@ ISC_LANG_BEGINDECLS
* Sample implementations
*/
#ifdef ISC_PLATFORM_USETHREADS
+#ifdef ISC_PLATFORM_HAVEXADD
+
+#define ISC_REFCOUNT_HAVEATOMIC 1
typedef struct isc_refcount {
- int refs;
- isc_mutex_t lock;
+ isc_int32_t refs;
} isc_refcount_t;
-#define isc_refcount_init(rp, n) \
- do { \
- isc_result_t _r; \
- (rp)->refs = (n); \
- _r = isc_mutex_init(&(rp)->lock); \
- RUNTIME_CHECK(_r == ISC_R_SUCCESS); \
+#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
} while (0)
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
+ } while (0)
+
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, -1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev - 1; \
+ } while (0)
+
+#else /* ISC_PLATFORM_HAVEXADD */
+
+typedef struct isc_refcount {
+ int refs;
+ isc_mutex_t lock;
+} isc_refcount_t;
+
+/*% Destroys a reference counter. */
#define isc_refcount_destroy(rp) \
do { \
REQUIRE((rp)->refs == 0); \
@@ -109,6 +151,17 @@ typedef struct isc_refcount {
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+/*% Increments the reference count, returning the new value in targetp if it's not NULL. */
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ ++((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
#define isc_refcount_increment(rp, tp) \
do { \
unsigned int *_tmp = (unsigned int *)(tp); \
@@ -120,6 +173,7 @@ typedef struct isc_refcount {
UNLOCK(&(rp)->lock); \
} while (0)
+/*% Decrements the reference count, returning the new value in targetp if it's not NULL. */
#define isc_refcount_decrement(rp, tp) \
do { \
unsigned int *_tmp = (unsigned int *)(tp); \
@@ -131,17 +185,17 @@ typedef struct isc_refcount {
UNLOCK(&(rp)->lock); \
} while (0)
-#else
+#endif /* ISC_PLATFORM_HAVEXADD */
+#else /* ISC_PLATFORM_USETHREADS */
typedef struct isc_refcount {
int refs;
} isc_refcount_t;
-#define isc_refcount_init(rp, n) ((rp)->refs = (n))
#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
-#define isc_refcount_increment(rp, tp) \
+#define isc_refcount_increment0(rp, tp) \
do { \
unsigned int *_tmp = (unsigned int *)(tp); \
int _n = ++(rp)->refs; \
@@ -149,15 +203,30 @@ typedef struct isc_refcount {
*_tmp = _n; \
} while (0)
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = ++(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
#define isc_refcount_decrement(rp, tp) \
do { \
unsigned int *_tmp = (unsigned int *)(tp); \
- int _n = --(rp)->refs; \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = --(rp)->refs; \
if (_tmp != NULL) \
*_tmp = _n; \
} while (0)
-#endif
+#endif /* ISC_PLATFORM_USETHREADS */
+
+isc_result_t
+isc_refcount_init(isc_refcount_t *ref, unsigned int n);
ISC_LANG_ENDDECLS
diff --git a/usr.sbin/bind/lib/isc/include/isc/rwlock.h b/usr.sbin/bind/lib/isc/include/isc/rwlock.h
index c13e1166f0b..78a591a4f7a 100644
--- a/usr.sbin/bind/lib/isc/include/isc/rwlock.h
+++ b/usr.sbin/bind/lib/isc/include/isc/rwlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,11 +15,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rwlock.h,v 1.18.2.3.2.1 2004/03/06 08:14:47 marka Exp $ */
+/* $ISC: rwlock.h,v 1.21.18.3 2005/06/04 06:23:44 jinmei Exp $ */
#ifndef ISC_RWLOCK_H
#define ISC_RWLOCK_H 1
+/*! \file */
+
#include <isc/condition.h>
#include <isc/lang.h>
#include <isc/platform.h>
@@ -34,19 +36,56 @@ typedef enum {
} isc_rwlocktype_t;
#ifdef ISC_PLATFORM_USETHREADS
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+#define ISC_RWLOCK_USEATOMIC 1
+#endif
+
struct isc_rwlock {
/* Unlocked. */
unsigned int magic;
isc_mutex_t lock;
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+ /*
+ * When some atomic instructions with hardware assistance are
+ * available, rwlock will use those so that concurrent readers do not
+ * interfere with each other through mutex as long as no writers
+ * appear, massively reducing the lock overhead in the typical case.
+ *
+ * The basic algorithm of this approach is the "simple
+ * writer-preference lock" shown in the following URL:
+ * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
+ * but our implementation does not rely on the spin lock unlike the
+ * original algorithm to be more portable as a user space application.
+ */
+
+ /* Read or modified atomically. */
+ isc_int32_t write_requests;
+ isc_int32_t write_completions;
+ isc_int32_t cnt_and_flag;
+
/* Locked by lock. */
isc_condition_t readable;
isc_condition_t writeable;
+ unsigned int readers_waiting;
+
+ /* Locked by rwlock itself. */
+ unsigned int write_granted;
+
+ /* Unlocked. */
+ unsigned int write_quota;
+
+#else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+
+ /*%< Locked by lock. */
+ isc_condition_t readable;
+ isc_condition_t writeable;
isc_rwlocktype_t type;
- /* The number of threads that have the lock. */
+ /*% The number of threads that have the lock. */
unsigned int active;
- /*
+ /*%
* The number of lock grants made since the lock was last switched
* from reading to writing or vice versa; used in determining
* when the quota is reached and it is time to switch.
@@ -58,6 +97,7 @@ struct isc_rwlock {
unsigned int read_quota;
unsigned int write_quota;
isc_rwlocktype_t original;
+#endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
};
#else /* ISC_PLATFORM_USETHREADS */
struct isc_rwlock {
diff --git a/usr.sbin/bind/lib/isc/include/isc/socket.h b/usr.sbin/bind/lib/isc/include/isc/socket.h
index b30acf1e276..e5e76cab964 100644
--- a/usr.sbin/bind/lib/isc/include/isc/socket.h
+++ b/usr.sbin/bind/lib/isc/include/isc/socket.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket.h,v 1.54.12.4 2004/03/08 09:04:53 marka Exp $ */
+/* $ISC: socket.h,v 1.57.18.6 2006/06/07 00:29:45 marka Exp $ */
#ifndef ISC_SOCKET_H
#define ISC_SOCKET_H 1
@@ -24,36 +24,32 @@
***** Module Info
*****/
-/*
- * Sockets
- *
- * Provides TCP and UDP sockets for network I/O. The sockets are event
+/*! \file
+ * \brief Provides TCP and UDP sockets for network I/O. The sockets are event
* sources in the task system.
*
* When I/O completes, a completion event for the socket is posted to the
* event queue of the task which requested the I/O.
*
- * MP:
+ * \li MP:
* The module ensures appropriate synchronization of data structures it
* creates and manipulates.
- *
* Clients of this module must not be holding a socket's task's lock when
* making a call that affects that socket. Failure to follow this rule
* can result in deadlock.
- *
* The caller must ensure that isc_socketmgr_destroy() is called only
* once for a given manager.
*
- * Reliability:
+ * \li Reliability:
* No anticipated impact.
*
- * Resources:
- * <TBS>
+ * \li Resources:
+ * TBS
*
- * Security:
+ * \li Security:
* No anticipated impact.
*
- * Standards:
+ * \li Standards:
* None.
*/
@@ -75,7 +71,7 @@ ISC_LANG_BEGINDECLS
*** Constants
***/
-/*
+/*%
* Maximum number of buffers in a scatter/gather read/write. The operating
* system in use must support at least this number (plus one on some.)
*/
@@ -87,33 +83,35 @@ ISC_LANG_BEGINDECLS
struct isc_socketevent {
ISC_EVENT_COMMON(isc_socketevent_t);
- isc_result_t result; /* OK, EOF, whatever else */
- unsigned int minimum; /* minimum i/o for event */
- unsigned int n; /* bytes read or written */
- unsigned int offset; /* offset into buffer list */
- isc_region_t region; /* for single-buffer i/o */
- isc_bufferlist_t bufferlist; /* list of buffers */
- isc_sockaddr_t address; /* source address */
- isc_time_t timestamp; /* timestamp of packet recv */
- struct in6_pktinfo pktinfo; /* ipv6 pktinfo */
- isc_uint32_t attributes; /* see below */
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ unsigned int minimum; /*%< minimum i/o for event */
+ unsigned int n; /*%< bytes read or written */
+ unsigned int offset; /*%< offset into buffer list */
+ isc_region_t region; /*%< for single-buffer i/o */
+ isc_bufferlist_t bufferlist; /*%< list of buffers */
+ isc_sockaddr_t address; /*%< source address */
+ isc_time_t timestamp; /*%< timestamp of packet recv */
+ struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
+ isc_uint32_t attributes; /*%< see below */
+ isc_eventdestructor_t destroy; /*%< original destructor */
};
typedef struct isc_socket_newconnev isc_socket_newconnev_t;
struct isc_socket_newconnev {
ISC_EVENT_COMMON(isc_socket_newconnev_t);
isc_socket_t * newsocket;
- isc_result_t result; /* OK, EOF, whatever else */
- isc_sockaddr_t address; /* source address */
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ isc_sockaddr_t address; /*%< source address */
};
typedef struct isc_socket_connev isc_socket_connev_t;
struct isc_socket_connev {
ISC_EVENT_COMMON(isc_socket_connev_t);
- isc_result_t result; /* OK, EOF, whatever else */
+ isc_result_t result; /*%< OK, EOF, whatever else */
};
-/*
+/*@{*/
+/*!
* _ATTACHED: Internal use only.
* _TRUNC: Packet was truncated on receive.
* _CTRUNC: Packet control information was truncated. This can
@@ -129,6 +127,7 @@ struct isc_socket_connev {
#define ISC_SOCKEVENTATTR_TIMESTAMP 0x00200000U /* public */
#define ISC_SOCKEVENTATTR_PKTINFO 0x00100000U /* public */
#define ISC_SOCKEVENTATTR_MULTICAST 0x00080000U /* public */
+/*@}*/
#define ISC_SOCKEVENT_ANYEVENT (0)
#define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1)
@@ -144,30 +143,37 @@ struct isc_socket_connev {
typedef enum {
isc_sockettype_udp = 1,
- isc_sockettype_tcp = 2
+ isc_sockettype_tcp = 2,
+ isc_sockettype_unix = 3
} isc_sockettype_t;
-/*
+/*@{*/
+/*!
* How a socket should be shutdown in isc_socket_shutdown() calls.
*/
-#define ISC_SOCKSHUT_RECV 0x00000001 /* close read side */
-#define ISC_SOCKSHUT_SEND 0x00000002 /* close write side */
-#define ISC_SOCKSHUT_ALL 0x00000003 /* close them all */
+#define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */
+#define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */
+#define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */
+/*@}*/
-/*
+/*@{*/
+/*!
* What I/O events to cancel in isc_socket_cancel() calls.
*/
-#define ISC_SOCKCANCEL_RECV 0x00000001 /* cancel recv */
-#define ISC_SOCKCANCEL_SEND 0x00000002 /* cancel send */
-#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /* cancel accept */
-#define ISC_SOCKCANCEL_CONNECT 0x00000008 /* cancel connect */
-#define ISC_SOCKCANCEL_ALL 0x0000000f /* cancel everything */
-
-/*
+#define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */
+#define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */
+#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */
+#define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */
+#define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */
+/*@}*/
+
+/*@{*/
+/*!
* Flags for isc_socket_send() and isc_socket_recv() calls.
*/
-#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /* send event only if needed */
-#define ISC_SOCKFLAG_NORETRY 0x00000002 /* drop failed UDP sends */
+#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */
+#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */
+/*@}*/
/***
*** Socket and Socket Manager Functions
@@ -181,18 +187,18 @@ isc_socket_create(isc_socketmgr_t *manager,
int pf,
isc_sockettype_t type,
isc_socket_t **socketp);
-/*
+/*%<
* Create a new 'type' socket managed by 'manager'.
*
* Note:
*
- * 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
+ *\li 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
*
* Requires:
*
- * 'manager' is a valid manager
+ *\li 'manager' is a valid manager
*
- * 'socketp' is a valid pointer, and *socketp == NULL
+ *\li 'socketp' is a valid pointer, and *socketp == NULL
*
* Ensures:
*
@@ -200,16 +206,16 @@ isc_socket_create(isc_socketmgr_t *manager,
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_NORESOURCES
- * ISC_R_UNEXPECTED
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NORESOURCES
+ *\li #ISC_R_UNEXPECTED
*/
void
isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
unsigned int how);
-/*
+/*%<
* Cancel pending I/O of the type specified by "how".
*
* Note: if "task" is NULL, then the cancel applies to all tasks using the
@@ -217,45 +223,45 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
*
* Requires:
*
- * "socket" is a valid socket
+ * \li "socket" is a valid socket
*
- * "task" is NULL or a valid task
+ * \li "task" is NULL or a valid task
*
* "how" is a bitmask describing the type of cancelation to perform.
* The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this
* socket.
*
- * ISC_SOCKCANCEL_RECV:
+ * \li ISC_SOCKCANCEL_RECV:
* Cancel pending isc_socket_recv() calls.
*
- * ISC_SOCKCANCEL_SEND:
+ * \li ISC_SOCKCANCEL_SEND:
* Cancel pending isc_socket_send() and isc_socket_sendto() calls.
*
- * ISC_SOCKCANCEL_ACCEPT:
+ * \li ISC_SOCKCANCEL_ACCEPT:
* Cancel pending isc_socket_accept() calls.
*
- * ISC_SOCKCANCEL_CONNECT:
+ * \li ISC_SOCKCANCEL_CONNECT:
* Cancel pending isc_socket_connect() call.
*/
void
isc_socket_shutdown(isc_socket_t *sock, unsigned int how);
-/*
+/*%<
* Shutdown 'socket' according to 'how'.
*
* Requires:
*
- * 'socket' is a valid socket.
+ * \li 'socket' is a valid socket.
*
- * 'task' is NULL or is a valid task.
+ * \li 'task' is NULL or is a valid task.
*
- * If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
+ * \li If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
*
* The read queue must be empty.
*
* No further read requests may be made.
*
- * If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
+ * \li If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
*
* The write queue must be empty.
*
@@ -264,39 +270,39 @@ isc_socket_shutdown(isc_socket_t *sock, unsigned int how);
void
isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
-/*
+/*%<
* Attach *socketp to socket.
*
* Requires:
*
- * 'socket' is a valid socket.
+ * \li 'socket' is a valid socket.
*
- * 'socketp' points to a NULL socket.
+ * \li 'socketp' points to a NULL socket.
*
* Ensures:
*
- * *socketp is attached to socket.
+ * \li *socketp is attached to socket.
*/
void
isc_socket_detach(isc_socket_t **socketp);
-/*
+/*%<
* Detach *socketp from its socket.
*
* Requires:
*
- * 'socketp' points to a valid socket.
+ * \li 'socketp' points to a valid socket.
*
- * If '*socketp' is the last reference to the socket,
+ * \li If '*socketp' is the last reference to the socket,
* then:
*
* There must be no pending I/O requests.
*
* Ensures:
*
- * *socketp is NULL.
+ * \li *socketp is NULL.
*
- * If '*socketp' is the last reference to the socket,
+ * \li If '*socketp' is the last reference to the socket,
* then:
*
* The socket will be shutdown (both reading and writing)
@@ -307,23 +313,23 @@ isc_socket_detach(isc_socket_t **socketp);
isc_result_t
isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp);
-/*
+/*%<
* Bind 'socket' to '*addressp'.
*
* Requires:
*
- * 'socket' is a valid socket
+ * \li 'socket' is a valid socket
*
- * 'addressp' points to a valid isc_sockaddr.
+ * \li 'addressp' points to a valid isc_sockaddr.
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_NOPERM
- * ISC_R_ADDRNOTAVAIL
- * ISC_R_ADDRINUSE
- * ISC_R_BOUND
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOPERM
+ * \li ISC_R_ADDRNOTAVAIL
+ * \li ISC_R_ADDRINUSE
+ * \li ISC_R_BOUND
+ * \li ISC_R_UNEXPECTED
*/
isc_result_t
@@ -331,124 +337,125 @@ isc_socket_privsep(int);
isc_result_t
isc_socket_filter(isc_socket_t *sock, const char *filter);
-/*
+/*%<
* Inform the kernel that it should perform accept filtering.
* If filter is NULL the current filter will be removed.:w
*/
isc_result_t
isc_socket_listen(isc_socket_t *sock, unsigned int backlog);
-/*
+/*%<
* Set listen mode on the socket. After this call, the only function that
* can be used (other than attach and detach) is isc_socket_accept().
*
* Notes:
*
- * 'backlog' is as in the UNIX system call listen() and may be
+ * \li 'backlog' is as in the UNIX system call listen() and may be
* ignored by non-UNIX implementations.
*
- * If 'backlog' is zero, a reasonable system default is used, usually
+ * \li If 'backlog' is zero, a reasonable system default is used, usually
* SOMAXCONN.
*
* Requires:
*
- * 'socket' is a valid, bound TCP socket.
+ * \li 'socket' is a valid, bound TCP socket or a valid, bound UNIX socket.
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_UNEXPECTED
*/
isc_result_t
isc_socket_accept(isc_socket_t *sock,
isc_task_t *task, isc_taskaction_t action, const void *arg);
-/*
+/*%<
* Queue accept event. When a new connection is received, the task will
* get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen
* socket. The new socket structure is sent inside the isc_socket_newconnev_t
* event type, and is attached to the task 'task'.
*
* REQUIRES:
- * 'socket' is a valid TCP socket that isc_socket_listen() was called
+ * \li 'socket' is a valid TCP socket that isc_socket_listen() was called
* on.
*
- * 'task' is a valid task
+ * \li 'task' is a valid task
*
- * 'action' is a valid action
+ * \li 'action' is a valid action
*
* RETURNS:
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
*/
isc_result_t
isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addressp,
isc_task_t *task, isc_taskaction_t action,
const void *arg);
-/*
+/*%<
* Connect 'socket' to peer with address *saddr. When the connection
* succeeds, or when an error occurs, a CONNECT event with action 'action'
* and arg 'arg' will be posted to the event queue for 'task'.
*
* Requires:
*
- * 'socket' is a valid TCP socket
+ * \li 'socket' is a valid TCP socket
*
- * 'addressp' points to a valid isc_sockaddr
+ * \li 'addressp' points to a valid isc_sockaddr
*
- * 'task' is a valid task
+ * \li 'task' is a valid task
*
- * 'action' is a valid action
+ * \li 'action' is a valid action
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
*
* Posted event's result code:
*
- * ISC_R_SUCCESS
- * ISC_R_TIMEDOUT
- * ISC_R_CONNREFUSED
- * ISC_R_NETUNREACH
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TIMEDOUT
+ * \li ISC_R_CONNREFUSED
+ * \li ISC_R_NETUNREACH
+ * \li ISC_R_UNEXPECTED
*/
isc_result_t
isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
-/*
+/*%<
* Get the name of the peer connected to 'socket'.
*
* Requires:
*
- * 'socket' is a valid TCP socket.
+ * \li 'socket' is a valid TCP socket.
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_TOOSMALL
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
*/
isc_result_t
isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
-/*
+/*%<
* Get the name of 'socket'.
*
* Requires:
*
- * 'socket' is a valid socket.
+ * \li 'socket' is a valid socket.
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_TOOSMALL
- * ISC_R_UNEXPECTED
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
*/
+/*@{*/
isc_result_t
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
unsigned int minimum,
@@ -463,39 +470,39 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
unsigned int minimum, isc_task_t *task,
isc_socketevent_t *event, unsigned int flags);
-/*
+/*!
* Receive from 'socket', storing the results in region.
*
* Notes:
*
- * Let 'length' refer to the length of 'region' or to the sum of all
+ *\li Let 'length' refer to the length of 'region' or to the sum of all
* available regions in the list of buffers '*buflist'.
*
- * If 'minimum' is non-zero and at least that many bytes are read,
+ *\li If 'minimum' is non-zero and at least that many bytes are read,
* the completion event will be posted to the task 'task.' If minimum
* is zero, the exact number of bytes requested in the region must
* be read for an event to be posted. This only makes sense for TCP
* connections, and is always set to 1 byte for UDP.
*
- * The read will complete when the desired number of bytes have been
+ *\li The read will complete when the desired number of bytes have been
* read, if end-of-input occurs, or if an error occurs. A read done
* event with the given 'action' and 'arg' will be posted to the
* event queue of 'task'.
*
- * The caller may not modify 'region', the buffers which are passed
+ *\li The caller may not modify 'region', the buffers which are passed
* into this function, or any data they refer to until the completion
* event is received.
*
- * For isc_socket_recvv():
+ *\li For isc_socket_recvv():
* On successful completion, '*buflist' will be empty, and the list of
* all buffers will be returned in the done event's 'bufferlist'
* member. On error return, '*buflist' will be unchanged.
*
- * For isc_socket_recv2():
+ *\li For isc_socket_recv2():
* 'event' is not NULL, and the non-socket specific fields are
* expected to be initialized.
*
- * For isc_socket_recv2():
+ *\li For isc_socket_recv2():
* The only defined value for 'flags' is ISC_SOCKFLAG_IMMEDIATE. If
* set and the operation completes, the return value will be
* ISC_R_SUCCESS and the event will be filled in and not sent. If the
@@ -505,36 +512,38 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
*
* Requires:
*
- * 'socket' is a valid, bound socket.
+ *\li 'socket' is a valid, bound socket.
*
- * For isc_socket_recv():
+ *\li For isc_socket_recv():
* 'region' is a valid region
*
- * For isc_socket_recvv():
+ *\li For isc_socket_recvv():
* 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
*
- * 'task' is a valid task
+ *\li 'task' is a valid task
*
- * For isc_socket_recv() and isc_socket_recvv():
+ *\li For isc_socket_recv() and isc_socket_recvv():
* action != NULL and is a valid action
*
- * For isc_socket_recv2():
+ *\li For isc_socket_recv2():
* event != NULL
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_INPROGRESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
*
* Event results:
*
- * ISC_R_SUCCESS
- * ISC_R_UNEXPECTED
- * XXX needs other net-type errors
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
*/
+/*@}*/
+/*@{*/
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);
@@ -555,41 +564,41 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
isc_socketevent_t *event, unsigned int flags);
-/*
+/*!
* Send the contents of 'region' to the socket's peer.
*
* Notes:
*
- * Shutting down the requestor's task *may* result in any
+ *\li Shutting down the requestor's task *may* result in any
* still pending writes being dropped or completed, depending on the
* underlying OS implementation.
*
- * If 'action' is NULL, then no completion event will be posted.
+ *\li If 'action' is NULL, then no completion event will be posted.
*
- * The caller may not modify 'region', the buffers which are passed
+ *\li The caller may not modify 'region', the buffers which are passed
* into this function, or any data they refer to until the completion
* event is received.
*
- * For isc_socket_sendv() and isc_socket_sendtov():
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
* On successful completion, '*buflist' will be empty, and the list of
* all buffers will be returned in the done event's 'bufferlist'
* member. On error return, '*buflist' will be unchanged.
*
- * For isc_socket_sendto2():
+ *\li For isc_socket_sendto2():
* 'event' is not NULL, and the non-socket specific fields are
* expected to be initialized.
*
- * For isc_socket_sendto2():
+ *\li For isc_socket_sendto2():
* The only defined values for 'flags' are ISC_SOCKFLAG_IMMEDIATE
* and ISC_SOCKFLAG_NORETRY.
*
- * If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the
+ *\li If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the
* return value will be ISC_R_SUCCESS and the event will be filled
* in and not sent. If the operation does not complete, the return
* value will be ISC_R_INPROGRESS and the event will be sent when
* the operation completes.
*
- * ISC_SOCKFLAG_NORETRY can only be set for UDP sockets. If set
+ *\li ISC_SOCKFLAG_NORETRY can only be set for UDP sockets. If set
* and the send operation fails due to a transient error, the send
* will not be retried and the error will be indicated in the event.
* Using this option along with ISC_SOCKFLAG_IMMEDIATE allows the caller
@@ -597,109 +606,148 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
*
* Requires:
*
- * 'socket' is a valid, bound socket.
+ *\li 'socket' is a valid, bound socket.
*
- * For isc_socket_send():
+ *\li For isc_socket_send():
* 'region' is a valid region
*
- * For isc_socket_sendv() and isc_socket_sendtov():
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
* 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
*
- * 'task' is a valid task
+ *\li 'task' is a valid task
*
- * For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and
+ *\li For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and
* isc_socket_sendto():
* action == NULL or is a valid action
*
- * For isc_socket_sendto2():
+ *\li For isc_socket_sendto2():
* event != NULL
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_INPROGRESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
*
* Event results:
*
- * ISC_R_SUCCESS
- * ISC_R_UNEXPECTED
- * XXX needs other net-type errors
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
*/
+/*@}*/
isc_result_t
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
-/*
+/*%<
* Create a socket manager.
*
* Notes:
*
- * All memory will be allocated in memory context 'mctx'.
+ *\li All memory will be allocated in memory context 'mctx'.
*
* Requires:
*
- * 'mctx' is a valid memory context.
+ *\li 'mctx' is a valid memory context.
*
- * 'managerp' points to a NULL isc_socketmgr_t.
+ *\li 'managerp' points to a NULL isc_socketmgr_t.
*
* Ensures:
*
- * '*managerp' is a valid isc_socketmgr_t.
+ *\li '*managerp' is a valid isc_socketmgr_t.
*
* Returns:
*
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
*/
void
isc_socketmgr_destroy(isc_socketmgr_t **managerp);
-/*
+/*%<
* Destroy a socket manager.
*
* Notes:
*
- * This routine blocks until there are no sockets left in the manager,
+ *\li This routine blocks until there are no sockets left in the manager,
* so if the caller holds any socket references using the manager, it
* must detach them before calling isc_socketmgr_destroy() or it will
* block forever.
*
* Requires:
*
- * '*managerp' is a valid isc_socketmgr_t.
+ *\li '*managerp' is a valid isc_socketmgr_t.
*
- * All sockets managed by this manager are fully detached.
+ *\li All sockets managed by this manager are fully detached.
*
* Ensures:
*
- * *managerp == NULL
+ *\li *managerp == NULL
*
- * All resources used by the manager have been freed.
+ *\li All resources used by the manager have been freed.
*/
isc_sockettype_t
isc_socket_gettype(isc_socket_t *sock);
-/*
+/*%<
* Returns the socket type for "sock."
*
* Requires:
*
- * "sock" is a valid socket.
+ *\li "sock" is a valid socket.
*/
+/*@{*/
isc_boolean_t
isc_socket_isbound(isc_socket_t *sock);
void
isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
-/*
+/*%<
* If the socket is an IPv6 socket set/clear the IPV6_IPV6ONLY socket
* option if the host OS supports this option.
*
* Requires:
- * 'sock' is a valid socket.
+ *\li 'sock' is a valid socket.
+ */
+/*@}*/
+
+void
+isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active);
+
+/*%<
+ * Cleanup UNIX domain sockets in the file-system. If 'active' is true
+ * then just unlink the socket. If 'active' is false try to determine
+ * if there is a listener of the socket or not. If no listener is found
+ * then unlink socket.
+ *
+ * Prior to unlinking the path is tested to see if it a socket.
+ *
+ * Note: there are a number of race conditions which cannot be avoided
+ * both in the filesystem and any application using UNIX domain
+ * sockets (e.g. socket is tested between bind() and listen(),
+ * the socket is deleted and replaced in the file-system between
+ * stat() and unlink()).
+ */
+
+isc_result_t
+isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group);
+/*%<
+ * Set ownership and file permissions on the UNIX domain socket.
+ *
+ * Note: On Solaris and SunOS this secures the directory containing
+ * the socket as Solaris and SunOS do not honour the filesytem
+ * permissions on the socket.
+ *
+ * Requires:
+ * \li 'sockaddr' to be a valid UNIX domain sockaddr.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_FAILURE
*/
ISC_LANG_ENDDECLS
diff --git a/usr.sbin/bind/lib/isc/include/isc/string.h b/usr.sbin/bind/lib/isc/include/isc/string.h
index 742b620ecf1..5931750c01b 100644
--- a/usr.sbin/bind/lib/isc/include/isc/string.h
+++ b/usr.sbin/bind/lib/isc/include/isc/string.h
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,22 +15,32 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: string.h,v 1.9.164.3 2004/03/06 08:14:49 marka Exp $ */
+/* $ISC: string.h,v 1.12.18.6 2007/09/13 05:04:01 each Exp $ */
#ifndef ISC_STRING_H
#define ISC_STRING_H 1
-#include <string.h>
+/*! \file */
+#include <isc/formatcheck.h>
#include <isc/int.h>
#include <isc/lang.h>
#include <isc/platform.h>
+#include <isc/types.h>
+
+#include <string.h>
+
+#ifdef ISC_PLATFORM_HAVESTRINGSH
+#include <strings.h>
+#endif
+
+#define ISC_STRING_MAGIC 0x5e
ISC_LANG_BEGINDECLS
isc_uint64_t
isc_string_touint64(char *source, char **endp, int base);
-/*
+/*%<
* Convert the string pointed to by 'source' to isc_uint64_t.
*
* On successful conversion 'endp' points to the first character
@@ -43,6 +53,151 @@ isc_string_touint64(char *source, char **endp, int base);
* On error 'endp' points to 'source'.
*/
+isc_result_t
+isc_string_copy(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be copied since 'target'
+ * is too small.
+ */
+
+void
+isc_string_copy_truncate(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_append(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be appended since 'target'
+ * is too small.
+ */
+
+void
+isc_string_append_truncate(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_printf(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'.
+ * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it
+ * is too small.
+ */
+
+void
+isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+
+char *
+isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source);
+/*
+ * Copy the region pointed to by r to a NUL terminated string
+ * allocated from the memory context pointed to by mctx.
+ *
+ * The result should be deallocated using isc_mem_free()
+ *
+ * Requires:
+ * 'mctx' is a point to a valid memory context.
+ * 'source' is a pointer to a valid region.
+ *
+ * Returns:
+ * a pointer to a NUL terminated string or
+ * NULL if memory for the copy could not be allocated
+ *
+ */
char *
isc_string_separate(char **stringp, const char *delim);
diff --git a/usr.sbin/bind/lib/isc/include/isc/types.h b/usr.sbin/bind/lib/isc/include/isc/types.h
index 79bb73238e5..c421239af34 100644
--- a/usr.sbin/bind/lib/isc/include/isc/types.h
+++ b/usr.sbin/bind/lib/isc/include/isc/types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * 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
@@ -15,12 +15,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: types.h,v 1.32.2.3.2.1 2004/03/06 08:14:50 marka Exp $ */
+/* $ISC: types.h,v 1.35.18.2 2005/04/29 00:17:04 marka Exp $ */
#ifndef ISC_TYPES_H
#define ISC_TYPES_H 1
-/*
+/*! \file
+ * \brief
* OS-specific types, from the OS-specific include directories.
*/
#include <isc/int.h>
@@ -37,57 +38,56 @@
*/
#include <isc/list.h>
-/***
- *** Core Types. Alphabetized by defined type.
- ***/
+/* Core Types. Alphabetized by defined type. */
-typedef struct isc_bitstring isc_bitstring_t;
-typedef struct isc_buffer isc_buffer_t;
-typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t;
-typedef struct isc_constregion isc_constregion_t;
-typedef struct isc_consttextregion isc_consttextregion_t;
-typedef struct isc_entropy isc_entropy_t;
-typedef struct isc_entropysource isc_entropysource_t;
-typedef struct isc_event isc_event_t;
-typedef ISC_LIST(isc_event_t) isc_eventlist_t;
-typedef unsigned int isc_eventtype_t;
-typedef isc_uint32_t isc_fsaccess_t;
-typedef struct isc_hash isc_hash_t;
-typedef struct isc_interface isc_interface_t;
-typedef struct isc_interfaceiter isc_interfaceiter_t;
-typedef struct isc_interval isc_interval_t;
-typedef struct isc_lex isc_lex_t;
-typedef struct isc_log isc_log_t;
-typedef struct isc_logcategory isc_logcategory_t;
-typedef struct isc_logconfig isc_logconfig_t;
-typedef struct isc_logmodule isc_logmodule_t;
-typedef struct isc_mem isc_mem_t;
-typedef struct isc_mempool isc_mempool_t;
-typedef struct isc_msgcat isc_msgcat_t;
-typedef struct isc_ondestroy isc_ondestroy_t;
-typedef struct isc_netaddr isc_netaddr_t;
-typedef struct isc_quota isc_quota_t;
-typedef struct isc_random isc_random_t;
-typedef struct isc_ratelimiter isc_ratelimiter_t;
-typedef struct isc_region isc_region_t;
-typedef isc_uint64_t isc_resourcevalue_t;
-typedef unsigned int isc_result_t;
-typedef struct isc_rwlock isc_rwlock_t;
-typedef struct isc_sockaddr isc_sockaddr_t;
-typedef struct isc_socket isc_socket_t;
-typedef struct isc_socketevent isc_socketevent_t;
-typedef struct isc_socketmgr isc_socketmgr_t;
-typedef struct isc_symtab isc_symtab_t;
-typedef struct isc_task isc_task_t;
-typedef ISC_LIST(isc_task_t) isc_tasklist_t;
-typedef struct isc_taskmgr isc_taskmgr_t;
-typedef struct isc_textregion isc_textregion_t;
-typedef struct isc_time isc_time_t;
-typedef struct isc_timer isc_timer_t;
-typedef struct isc_timermgr isc_timermgr_t;
+typedef struct isc_bitstring isc_bitstring_t; /*%< Bitstring */
+typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
+typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
+typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+typedef struct isc_event isc_event_t; /*%< Event */
+typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */
+typedef unsigned int isc_eventtype_t; /*%< Event Type */
+typedef isc_uint32_t isc_fsaccess_t; /*%< FS Access */
+typedef struct isc_hash isc_hash_t; /*%< Hash */
+typedef struct isc_interface isc_interface_t; /*%< Interface */
+typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */
+typedef struct isc_interval isc_interval_t; /*%< Interval */
+typedef struct isc_lex isc_lex_t; /*%< Lex */
+typedef struct isc_log isc_log_t; /*%< Log */
+typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */
+typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */
+typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */
+typedef struct isc_mem isc_mem_t; /*%< Memory */
+typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */
+typedef struct isc_msgcat isc_msgcat_t; /*%< Message Catalog */
+typedef struct isc_ondestroy isc_ondestroy_t; /*%< On Destroy */
+typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */
+typedef struct isc_quota isc_quota_t; /*%< Quota */
+typedef struct isc_random isc_random_t; /*%< Random */
+typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */
+typedef struct isc_region isc_region_t; /*%< Region */
+typedef isc_uint64_t isc_resourcevalue_t; /*%< Resource Value */
+typedef unsigned int isc_result_t; /*%< Result */
+typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */
+typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */
+typedef struct isc_socket isc_socket_t; /*%< Socket */
+typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */
+typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */
+typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */
+typedef struct isc_task isc_task_t; /*%< Task */
+typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */
+typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */
+typedef struct isc_textregion isc_textregion_t; /*%< Text Region */
+typedef struct isc_time isc_time_t; /*%< Time */
+typedef struct isc_timer isc_timer_t; /*%< Timer */
+typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */
typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
+/*% Resource */
typedef enum {
isc_resource_coresize = 1,
isc_resource_cputime,
diff --git a/usr.sbin/bind/lib/isc/inet_aton.c b/usr.sbin/bind/lib/isc/inet_aton.c
index e88525b1109..ba9d3c28bf2 100644
--- a/usr.sbin/bind/lib/isc/inet_aton.c
+++ b/usr.sbin/bind/lib/isc/inet_aton.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -67,10 +67,11 @@
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
+/*! \file */
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-static char rcsid[] = "$ISC: inet_aton.c,v 1.15.12.3 2004/03/08 09:04:49 marka Exp $";
+static char rcsid[] = "$ISC: inet_aton.c,v 1.17.18.2 2005/04/29 00:16:46 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
@@ -81,7 +82,7 @@ static char rcsid[] = "$ISC: inet_aton.c,v 1.15.12.3 2004/03/08 09:04:49 marka E
#include <isc/types.h>
#include <isc/net.h>
-/*
+/*%
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
diff --git a/usr.sbin/bind/lib/isc/inet_ntop.c b/usr.sbin/bind/lib/isc/inet_ntop.c
index daa94209f03..13fdfa54e20 100644
--- a/usr.sbin/bind/lib/isc/inet_ntop.c
+++ b/usr.sbin/bind/lib/isc/inet_ntop.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,9 +15,11 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+/*! \file */
+
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] =
- "$ISC: inet_ntop.c,v 1.12.12.4 2004/08/28 06:25:21 marka Exp $";
+ "$ISC: inet_ntop.c,v 1.14.18.3 2005/04/29 00:16:46 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
@@ -45,12 +47,12 @@ static const char *inet_ntop6(const unsigned char *src, char *dst,
size_t size);
#endif
-/* char *
+/*! char *
* isc_net_ntop(af, src, dst, size)
* convert a network format address to presentation format.
- * return:
+ * \return
* pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
+ * \author
* Paul Vixie, 1996.
*/
const char *
@@ -70,15 +72,16 @@ isc_net_ntop(int af, const void *src, char *dst, size_t size)
/* NOTREACHED */
}
-/* const char *
+/*! const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address
- * return:
+ * \return
* `dst' (as a const)
- * notes:
+ * \note
* (1) uses no statics
+ * \note
* (2) takes a unsigned char* not an in_addr as input
- * author:
+ * \author
* Paul Vixie, 1996.
*/
static const char *
@@ -97,10 +100,10 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size)
return (dst);
}
-/* const char *
+/*! const char *
* isc_inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
- * author:
+ * \author
* Paul Vixie, 1996.
*/
#ifdef AF_INET6
diff --git a/usr.sbin/bind/lib/isc/inet_pton.c b/usr.sbin/bind/lib/isc/inet_pton.c
index 75b8c4161bc..c45819c52dd 100644
--- a/usr.sbin/bind/lib/isc/inet_pton.c
+++ b/usr.sbin/bind/lib/isc/inet_pton.c
@@ -15,9 +15,11 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+/*! \file */
+
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] =
- "$ISC: inet_pton.c,v 1.10.2.4.2.3 2005/03/31 23:56:14 marka Exp $";
+ "$ISC: inet_pton.c,v 1.13.18.4 2005/04/29 00:16:46 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
@@ -27,8 +29,11 @@ static char rcsid[] =
#include <isc/net.h>
+/*% INT16 Size */
#define NS_INT16SZ 2
+/*% IPv4 Address Size */
#define NS_INADDRSZ 4
+/*% IPv6 Address Size */
#define NS_IN6ADDRSZ 16
/*
@@ -39,15 +44,14 @@ static char rcsid[] =
static int inet_pton4(const char *src, unsigned char *dst);
static int inet_pton6(const char *src, unsigned char *dst);
-/* int
- * isc_net_pton(af, src, dst)
+/*%
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
- * return:
+ * \return
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
+ * \author
* Paul Vixie, 1996.
*/
int
@@ -64,14 +68,14 @@ isc_net_pton(int af, const char *src, void *dst) {
/* NOTREACHED */
}
-/* int
- * inet_pton4(src, dst)
+/*!\fn static int inet_pton4(const char *src, unsigned char *dst)
+ * \brief
* like inet_aton() but without all the hexadecimal and shorthand.
- * return:
+ * \return
* 1 if `src' is a valid dotted quad, else 0.
- * notice:
+ * \note
* does not touch `dst' unless it's returning 1.
- * author:
+ * \author
* Paul Vixie, 1996.
*/
static int
@@ -113,17 +117,17 @@ inet_pton4(const char *src, unsigned char *dst) {
return (1);
}
-/* int
- * inet_pton6(src, dst)
+/*%
* convert presentation level address to network order binary form.
- * return:
+ * \return
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
+ * \note
* (1) does not touch `dst' unless it's returning 1.
+ * \note
* (2) :: in a full address is silently ignored.
- * credit:
+ * \author
* inspired by Mark Andrews.
- * author:
+ * \author
* Paul Vixie, 1996.
*/
static int
diff --git a/usr.sbin/bind/lib/isc/lex.c b/usr.sbin/bind/lib/isc/lex.c
index ac355926bc6..ae98ac92fc0 100644
--- a/usr.sbin/bind/lib/isc/lex.c
+++ b/usr.sbin/bind/lib/isc/lex.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * 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
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: lex.c,v 1.66.2.6.2.10 2006/01/04 23:50:21 marka Exp $ */
+/* $ISC: lex.c,v 1.78.18.5 2005/11/30 03:44:39 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -563,7 +565,11 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
} else if (isdigit((unsigned char)c) &&
(options & ISC_LEXOPT_NUMBER) != 0) {
lex->last_was_eol = ISC_FALSE;
- state = lexstate_number;
+ if ((options & ISC_LEXOPT_OCTAL) != 0 &&
+ (c == '8' || c == '9'))
+ state = lexstate_string;
+ else
+ state = lexstate_number;
goto no_read;
} else {
lex->last_was_eol = ISC_FALSE;
@@ -584,7 +590,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
c == '\n' || c == EOF ||
lex->specials[c]) {
int base;
- if ((options & ISC_LEXOPT_CNUMBER) != 0)
+ if ((options & ISC_LEXOPT_OCTAL) != 0)
+ base = 8;
+ else if ((options & ISC_LEXOPT_CNUMBER) != 0)
base = 0;
else
base = 10;
@@ -620,6 +628,9 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
/* Above test supports hex numbers */
state = lexstate_string;
}
+ } else if ((options & ISC_LEXOPT_OCTAL) != 0 &&
+ (c == '8' || c == '9')) {
+ state = lexstate_string;
}
if (remaining == 0U) {
result = grow_data(lex, &remaining,
@@ -821,6 +832,33 @@ isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token,
return (ISC_R_SUCCESS);
}
+isc_result_t
+isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol)
+{
+ unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
+ ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE|
+ ISC_LEXOPT_NUMBER | ISC_LEXOPT_OCTAL;
+ isc_result_t result;
+
+ result = isc_lex_gettoken(lex, options, token);
+ if (result == ISC_R_RANGE)
+ isc_lex_ungettoken(lex, token);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (eol && ((token->type == isc_tokentype_eol) ||
+ (token->type == isc_tokentype_eof)))
+ return (ISC_R_SUCCESS);
+ if (token->type != isc_tokentype_number) {
+ isc_lex_ungettoken(lex, token);
+ if (token->type == isc_tokentype_eol ||
+ token->type == isc_tokentype_eof)
+ return (ISC_R_UNEXPECTEDEND);
+ return (ISC_R_BADNUMBER);
+ }
+ return (ISC_R_SUCCESS);
+}
+
void
isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp) {
inputsource *source;
diff --git a/usr.sbin/bind/lib/isc/lfsr.c b/usr.sbin/bind/lib/isc/lfsr.c
index c317744b3a1..2792156466d 100644
--- a/usr.sbin/bind/lib/isc/lfsr.c
+++ b/usr.sbin/bind/lib/isc/lfsr.c
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: lfsr.c,v 1.11.2.2.2.6 2005/10/14 01:38:50 marka Exp $ */
+/* $ISC: lfsr.c,v 1.14.18.4 2005/10/14 01:28:29 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -50,7 +52,7 @@ isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits,
lfsr->state = 0xffffffffU >> (32 - lfsr->bits);
}
-/*
+/*!
* Return the next state of the lfsr.
*/
static inline isc_uint32_t
diff --git a/usr.sbin/bind/lib/isc/log.c b/usr.sbin/bind/lib/isc/log.c
index 68f27152290..b7433cb7049 100644
--- a/usr.sbin/bind/lib/isc/log.c
+++ b/usr.sbin/bind/lib/isc/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,9 +15,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: log.c,v 1.70.2.8.2.14 2006/03/02 00:37:20 marka Exp $ */
+/* $ISC: log.c,v 1.84.18.8 2006/03/02 00:37:22 marka Exp $ */
-/* Principal Authors: DCL */
+/*! \file
+ * \author Principal Authors: DCL */
#include <config.h>
@@ -56,7 +57,7 @@
#define PATH_MAX 1024 /* AIX and others don't define this. */
#endif
-/*
+/*!
* This is the structure that holds each named channel. A simple linked
* list chains all of the channels together, so an individual channel is
* found by doing strcmp()s with the names down the list. Their should
@@ -76,7 +77,7 @@ struct isc_logchannel {
ISC_LINK(isc_logchannel_t) link;
};
-/*
+/*!
* The logchannellist structure associates categories and modules with
* channels. First the appropriate channellist is found based on the
* category, and then each structure in the linked list is checked for
@@ -92,7 +93,7 @@ struct isc_logchannellist {
ISC_LINK(isc_logchannellist_t) link;
};
-/*
+/*!
* This structure is used to remember messages for pruning via
* isc_log_[v]write1().
*/
@@ -104,7 +105,7 @@ struct isc_logmessage {
ISC_LINK(isc_logmessage_t) link;
};
-/*
+/*!
* The isc_logconfig structure is used to store the configurable information
* about where messages are actually supposed to be sent -- the information
* that could changed based on some configuration file, as opposed to the
@@ -123,7 +124,7 @@ struct isc_logconfig {
isc_boolean_t dynamic;
};
-/*
+/*!
* This isc_log structure provides the context for the isc_log functions.
* The log context locks itself in isc_log_doit, the internal backend to
* isc_log_write. The locking is necessary both to provide exclusive access
@@ -156,7 +157,7 @@ struct isc_log {
ISC_LIST(isc_logmessage_t) messages;
};
-/*
+/*!
* Used when ISC_LOG_PRINTLEVEL is enabled for a channel.
*/
static const char *log_level_strings[] = {
@@ -168,7 +169,7 @@ static const char *log_level_strings[] = {
"critical"
};
-/*
+/*!
* Used to convert ISC_LOG_* priorities into syslog priorities.
* XXXDCL This will need modification for NT.
*/
@@ -181,7 +182,7 @@ static const int syslog_map[] = {
LOG_CRIT
};
-/*
+/*!
* When adding new categories, a corresponding ISC_LOGCATEGORY_foo
* definition needs to be added to <isc/log.h>.
*
@@ -195,8 +196,8 @@ LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = {
{ NULL, 0 }
};
-/*
- * See above comment for categories, and apply it to modules.
+/*!
+ * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules.
*/
LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = {
{ "socket", 0 },
@@ -206,19 +207,19 @@ LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = {
{ NULL, 0 }
};
-/*
+/*!
* This essentially constant structure must be filled in at run time,
* because its channel member is pointed to a channel that is created
* dynamically with isc_log_createchannel.
*/
static isc_logchannellist_t default_channel;
-/*
+/*!
* libisc logs to this context.
*/
LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL;
-/*
+/*!
* Forward declarations.
*/
static isc_result_t
@@ -241,7 +242,8 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
const char *format, va_list args)
ISC_FORMAT_PRINTF(9, 0);
-/*
+/*@{*/
+/*!
* Convenience macros.
*/
@@ -252,6 +254,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
#define FILE_MAXSIZE(channel) (channel->destination.file.maximum_size)
#define FILE_MAXREACHED(channel) (channel->destination.file.maximum_reached)
+/*@}*/
/****
**** Public interfaces.
****/
@@ -280,7 +283,11 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) {
ISC_LIST_INIT(lctx->messages);
- RUNTIME_CHECK(isc_mutex_init(&lctx->lock) == ISC_R_SUCCESS);
+ result = isc_mutex_init(&lctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, lctx, sizeof(*lctx));
+ return (result);
+ }
/*
* Normally setting the magic number is the last step done
diff --git a/usr.sbin/bind/lib/isc/mem.c b/usr.sbin/bind/lib/isc/mem.c
index 4a5ea4b33df..f7533b9b949 100644
--- a/usr.sbin/bind/lib/isc/mem.c
+++ b/usr.sbin/bind/lib/isc/mem.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: mem.c,v 1.98.2.7.2.7 2005/03/17 03:58:32 marka Exp $ */
+/* $ISC: mem.c,v 1.116.18.18 2007/10/30 23:31:43 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -28,35 +30,29 @@
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/msgs.h>
+#include <isc/once.h>
#include <isc/ondestroy.h>
#include <isc/string.h>
#include <isc/mutex.h>
#include <isc/util.h>
+#define MCTXLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) LOCK(l)
+#define MCTXUNLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) UNLOCK(l)
+
#ifndef ISC_MEM_DEBUGGING
#define ISC_MEM_DEBUGGING 0
#endif
LIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING;
/*
- * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
- * implementation in preference to the system one. The internal malloc()
- * is very space-efficient, and quite fast on uniprocessor systems. It
- * performs poorly on multiprocessor machines.
- */
-#ifndef ISC_MEM_USE_INTERNAL_MALLOC
-#define ISC_MEM_USE_INTERNAL_MALLOC 0
-#endif
-
-/*
* Constants.
*/
#define DEF_MAX_SIZE 1100
#define DEF_MEM_TARGET 4096
-#define ALIGNMENT_SIZE 8 /* must be a power of 2 */
-#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
+#define ALIGNMENT_SIZE 8 /*%< must be a power of 2 */
+#define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */
#define TABLE_INCREMENT 1024
#define DEBUGLIST_COUNT 1024
@@ -87,11 +83,12 @@ struct element {
};
typedef struct {
- /*
+ /*!
* This structure must be ALIGNMENT_SIZE bytes.
*/
union {
size_t size;
+ isc_mem_t *ctx;
char bytes[ALIGNMENT_SIZE];
} u;
} size_info;
@@ -99,10 +96,8 @@ typedef struct {
struct stats {
unsigned long gets;
unsigned long totalgets;
-#if ISC_MEM_USE_INTERNAL_MALLOC
unsigned long blocks;
unsigned long freefrags;
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
};
#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C')
@@ -112,9 +107,16 @@ struct stats {
typedef ISC_LIST(debuglink_t) debuglist_t;
#endif
+/* List of all active memory contexts. */
+
+static ISC_LIST(isc_mem_t) contexts;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_mutex_t lock;
+
struct isc_mem {
unsigned int magic;
isc_ondestroy_t ondestroy;
+ unsigned int flags;
isc_mutex_t lock;
isc_memalloc_t memalloc;
isc_memfree_t memfree;
@@ -134,7 +136,7 @@ struct isc_mem {
void * water_arg;
ISC_LIST(isc_mempool_t) pools;
-#if ISC_MEM_USE_INTERNAL_MALLOC
+ /* ISC_MEMFLAG_INTERNAL */
size_t mem_target;
element ** freelists;
element * basic_blocks;
@@ -143,13 +145,13 @@ struct isc_mem {
unsigned int basic_table_size;
unsigned char * lowest;
unsigned char * highest;
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES
debuglist_t * debuglist;
#endif
unsigned int memalloc_failures;
+ ISC_LINK(isc_mem_t) link;
};
#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
@@ -157,24 +159,24 @@ struct isc_mem {
struct isc_mempool {
/* always unlocked */
- unsigned int magic; /* magic number */
- isc_mutex_t *lock; /* optional lock */
- isc_mem_t *mctx; /* our memory context */
- /* locked via the memory context's lock */
- ISC_LINK(isc_mempool_t) link; /* next pool in this mem context */
- /* optionally locked from here down */
- element *items; /* low water item list */
- size_t size; /* size of each item on this pool */
- unsigned int maxalloc; /* max number of items allowed */
- unsigned int allocated; /* # of items currently given out */
- unsigned int freecount; /* # of items on reserved list */
- unsigned int freemax; /* # of items allowed on free list */
- unsigned int fillcount; /* # of items to fetch on each fill */
- /* Stats only. */
- unsigned int gets; /* # of requests to this pool */
- /* Debugging only. */
+ unsigned int magic; /*%< magic number */
+ isc_mutex_t *lock; /*%< optional lock */
+ isc_mem_t *mctx; /*%< our memory context */
+ /*%< locked via the memory context's lock */
+ ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
+ /*%< optionally locked from here down */
+ element *items; /*%< low water item list */
+ size_t size; /*%< size of each item on this pool */
+ unsigned int maxalloc; /*%< max number of items allowed */
+ unsigned int allocated; /*%< # of items currently given out */
+ unsigned int freecount; /*%< # of items on reserved list */
+ unsigned int freemax; /*%< # of items allowed on free list */
+ unsigned int fillcount; /*%< # of items to fetch on each fill */
+ /*%< Stats only. */
+ unsigned int gets; /*%< # of requests to this pool */
+ /*%< Debugging only. */
#if ISC_MEMPOOL_NAMES
- char name[16]; /* printed name in stats reports */
+ char name[16]; /*%< printed name in stats reports */
#endif
};
@@ -198,7 +200,7 @@ struct isc_mempool {
static void
print_active(isc_mem_t *ctx, FILE *out);
-/*
+/*!
* mctx must be locked.
*/
static inline void
@@ -309,7 +311,6 @@ delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
}
#endif /* ISC_MEM_TRACKLINES */
-#if ISC_MEM_USE_INTERNAL_MALLOC
static inline size_t
rmsize(size_t size) {
/*
@@ -320,13 +321,13 @@ rmsize(size_t size) {
static inline size_t
quantize(size_t size) {
- /*
+ /*!
* Round up the result in order to get a size big
* enough to satisfy the request and be aligned on ALIGNMENT_SIZE
* byte boundaries.
*/
- if (size == 0)
+ if (size == 0U)
return (ALIGNMENT_SIZE);
return ((size + ALIGNMENT_SIZE - 1) & (~(ALIGNMENT_SIZE - 1)));
}
@@ -347,7 +348,7 @@ more_basic_blocks(isc_mem_t *ctx) {
* Did we hit the quota for this context?
*/
increment = NUM_BASIC_BLOCKS * ctx->mem_target;
- if (ctx->quota != 0 && ctx->total + increment > ctx->quota)
+ if (ctx->quota != 0U && ctx->total + increment > ctx->quota)
return (ISC_FALSE);
INSIST(ctx->basic_table_count <= ctx->basic_table_size);
@@ -408,7 +409,7 @@ more_frags(isc_mem_t *ctx, size_t new_size) {
void *new;
unsigned char *curr, *next;
- /*
+ /*!
* Try to get more fragments by chopping up a basic block.
*/
@@ -448,7 +449,7 @@ more_frags(isc_mem_t *ctx, size_t new_size) {
* Add the remaining fragment of the basic block to a free list.
*/
total_size = rmsize(total_size);
- if (total_size > 0) {
+ if (total_size > 0U) {
((element *)next)->next = ctx->freelists[total_size];
ctx->freelists[total_size] = (element *)next;
ctx->stats[total_size].freefrags++;
@@ -472,7 +473,7 @@ mem_getunlocked(isc_mem_t *ctx, size_t size) {
/*
* memget() was called on something beyond our upper limit.
*/
- if (ctx->quota != 0 && ctx->total + size > ctx->quota) {
+ if (ctx->quota != 0U && ctx->total + size > ctx->quota) {
ret = NULL;
goto done;
}
@@ -556,7 +557,7 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
memset(mem, 0xde, size); /* Mnemonic for "dead". */
#endif
(ctx->memfree)(ctx->arg, mem);
- INSIST(ctx->stats[ctx->max_size].gets != 0);
+ INSIST(ctx->stats[ctx->max_size].gets != 0U);
ctx->stats[ctx->max_size].gets--;
INSIST(size <= ctx->total);
ctx->inuse -= size;
@@ -583,15 +584,13 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
* max. size (max_size) ends up getting recorded as a call to
* max_size.
*/
- INSIST(ctx->stats[size].gets != 0);
+ INSIST(ctx->stats[size].gets != 0U);
ctx->stats[size].gets--;
ctx->stats[new_size].freefrags++;
ctx->inuse -= new_size;
}
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
-
-/*
+/*!
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
static inline void *
@@ -619,7 +618,7 @@ mem_get(isc_mem_t *ctx, size_t size) {
return (ret);
}
-/*
+/*!
* Perform a free, doing memory filling and overrun detection as necessary.
*/
static inline void
@@ -635,7 +634,7 @@ mem_put(isc_mem_t *ctx, void *mem, size_t size) {
(ctx->memfree)(ctx->arg, mem);
}
-/*
+/*!
* Update internal counters after a memory get.
*/
static inline void
@@ -652,7 +651,7 @@ mem_getstats(isc_mem_t *ctx, size_t size) {
}
}
-/*
+/*!
* Update internal counters after a memory put.
*/
static inline void
@@ -671,8 +670,6 @@ mem_putstats(isc_mem_t *ctx, void *ptr, size_t size) {
}
}
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
-
/*
* Private.
*/
@@ -691,6 +688,12 @@ default_memfree(void *arg, void *ptr) {
free(ptr);
}
+static void
+initialize_action(void) {
+ RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
+ ISC_LIST_INIT(contexts);
+}
+
/*
* Public.
*/
@@ -700,6 +703,16 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
isc_mem_t **ctxp)
{
+ return (isc_mem_createx2(init_max_size, target_size, memalloc, memfree,
+ arg, ctxp, ISC_MEMFLAG_DEFAULT));
+
+}
+
+isc_result_t
+isc_mem_createx2(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags)
+{
isc_mem_t *ctx;
isc_result_t result;
@@ -709,27 +722,25 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
INSIST((ALIGNMENT_SIZE & (ALIGNMENT_SIZE - 1)) == 0);
-#if !ISC_MEM_USE_INTERNAL_MALLOC
- UNUSED(target_size);
-#endif
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
ctx = (memalloc)(arg, sizeof(*ctx));
if (ctx == NULL)
return (ISC_R_NOMEMORY);
- if (isc_mutex_init(&ctx->lock) != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- (memfree)(arg, ctx);
- return (ISC_R_UNEXPECTED);
+ if ((flags & ISC_MEMFLAG_NOLOCK) == 0) {
+ result = isc_mutex_init(&ctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ (memfree)(arg, ctx);
+ return (result);
+ }
}
if (init_max_size == 0U)
ctx->max_size = DEF_MAX_SIZE;
else
ctx->max_size = init_max_size;
+ ctx->flags = flags;
ctx->references = 1;
ctx->quota = 0;
ctx->total = 0;
@@ -751,10 +762,13 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
ctx->debuglist = NULL;
#endif
ISC_LIST_INIT(ctx->pools);
-
-#if ISC_MEM_USE_INTERNAL_MALLOC
ctx->freelists = NULL;
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ ctx->basic_blocks = NULL;
+ ctx->basic_table = NULL;
+ ctx->basic_table_count = 0;
+ ctx->basic_table_size = 0;
+ ctx->lowest = NULL;
+ ctx->highest = NULL;
ctx->stats = (memalloc)(arg,
(ctx->max_size+1) * sizeof(struct stats));
@@ -764,25 +778,20 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
}
memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats));
-#if ISC_MEM_USE_INTERNAL_MALLOC
- if (target_size == 0)
- ctx->mem_target = DEF_MEM_TARGET;
- else
- ctx->mem_target = target_size;
- ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof(element *));
- if (ctx->freelists == NULL) {
- result = ISC_R_NOMEMORY;
- goto error;
+ if ((flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ if (target_size == 0U)
+ ctx->mem_target = DEF_MEM_TARGET;
+ else
+ ctx->mem_target = target_size;
+ ctx->freelists = (memalloc)(arg, ctx->max_size *
+ sizeof(element *));
+ if (ctx->freelists == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+ memset(ctx->freelists, 0,
+ ctx->max_size * sizeof(element *));
}
- memset(ctx->freelists, 0,
- ctx->max_size * sizeof(element *));
- ctx->basic_blocks = NULL;
- ctx->basic_table = NULL;
- ctx->basic_table_count = 0;
- ctx->basic_table_size = 0;
- ctx->lowest = NULL;
- ctx->highest = NULL;
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES
if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) {
@@ -801,6 +810,10 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
ctx->memalloc_failures = 0;
+ LOCK(&lock);
+ ISC_LIST_INITANDAPPEND(contexts, ctx, link);
+ UNLOCK(&lock);
+
*ctxp = ctx;
return (ISC_R_SUCCESS);
@@ -808,15 +821,14 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
if (ctx != NULL) {
if (ctx->stats != NULL)
(memfree)(arg, ctx->stats);
-#if ISC_MEM_USE_INTERNAL_MALLOC
if (ctx->freelists != NULL)
(memfree)(arg, ctx->freelists);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES
if (ctx->debuglist != NULL)
(ctx->memfree)(ctx->arg, ctx->debuglist);
#endif /* ISC_MEM_TRACKLINES */
- DESTROYLOCK(&ctx->lock);
+ if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
+ DESTROYLOCK(&ctx->lock);
(memfree)(arg, ctx);
}
@@ -827,9 +839,18 @@ isc_result_t
isc_mem_create(size_t init_max_size, size_t target_size,
isc_mem_t **ctxp)
{
- return (isc_mem_createx(init_max_size, target_size,
- default_memalloc, default_memfree, NULL,
- ctxp));
+ return (isc_mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, ISC_MEMFLAG_DEFAULT));
+}
+
+isc_result_t
+isc_mem_create2(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags)
+{
+ return (isc_mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, flags));
}
static void
@@ -839,9 +860,11 @@ destroy(isc_mem_t *ctx) {
ctx->magic = 0;
-#if ISC_MEM_USE_INTERNAL_MALLOC
+ LOCK(&lock);
+ ISC_LIST_UNLINK(contexts, ctx, link);
+ UNLOCK(&lock);
+
INSIST(ISC_LIST_EMPTY(ctx->pools));
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES
if (ctx->debuglist != NULL) {
@@ -880,16 +903,17 @@ destroy(isc_mem_t *ctx) {
(ctx->memfree)(ctx->arg, ctx->stats);
-#if ISC_MEM_USE_INTERNAL_MALLOC
- for (i = 0; i < ctx->basic_table_count; i++)
- (ctx->memfree)(ctx->arg, ctx->basic_table[i]);
- (ctx->memfree)(ctx->arg, ctx->freelists);
- (ctx->memfree)(ctx->arg, ctx->basic_table);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ for (i = 0; i < ctx->basic_table_count; i++)
+ (ctx->memfree)(ctx->arg, ctx->basic_table[i]);
+ (ctx->memfree)(ctx->arg, ctx->freelists);
+ (ctx->memfree)(ctx->arg, ctx->basic_table);
+ }
ondest = ctx->ondestroy;
- DESTROYLOCK(&ctx->lock);
+ if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
+ DESTROYLOCK(&ctx->lock);
(ctx->memfree)(ctx->arg, ctx);
isc_ondestroy_notify(&ondest, ctx);
@@ -900,9 +924,9 @@ isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
REQUIRE(VALID_CONTEXT(source));
REQUIRE(targetp != NULL && *targetp == NULL);
- LOCK(&source->lock);
+ MCTXLOCK(source, &source->lock);
source->references++;
- UNLOCK(&source->lock);
+ MCTXUNLOCK(source, &source->lock);
*targetp = source;
}
@@ -916,12 +940,12 @@ isc_mem_detach(isc_mem_t **ctxp) {
ctx = *ctxp;
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
INSIST(ctx->references > 0);
ctx->references--;
if (ctx->references == 0)
want_destroy = ISC_TRUE;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
if (want_destroy)
destroy(ctx);
@@ -943,6 +967,8 @@ void
isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
isc_mem_t *ctx;
isc_boolean_t want_destroy = ISC_FALSE;
+ size_info *si;
+ size_t oldsize;
REQUIRE(ctxp != NULL);
ctx = *ctxp;
@@ -955,14 +981,35 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
*/
*ctxp = NULL;
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&ctx->lock);
- mem_putunlocked(ctx, ptr, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- mem_put(ctx, ptr, size);
- LOCK(&ctx->lock);
- mem_putstats(ctx, ptr, size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
+ if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
+ si = &(((size_info *)ptr)[-1]);
+ oldsize = si->u.size - ALIGNMENT_SIZE;
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
+ oldsize -= ALIGNMENT_SIZE;
+ INSIST(oldsize == size);
+ }
+ isc__mem_free(ctx, ptr FLARG_PASS);
+
+ MCTXLOCK(ctx, &ctx->lock);
+ ctx->references--;
+ if (ctx->references == 0)
+ want_destroy = ISC_TRUE;
+ MCTXUNLOCK(ctx, &ctx->lock);
+ if (want_destroy)
+ destroy(ctx);
+
+ return;
+ }
+
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putunlocked(ctx, ptr, size);
+ } else {
+ mem_put(ctx, ptr, size);
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putstats(ctx, ptr, size);
+ }
DELETE_TRACE(ctx, ptr, size, file, line);
INSIST(ctx->references > 0);
@@ -970,7 +1017,7 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
if (ctx->references == 0)
want_destroy = ISC_TRUE;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
if (want_destroy)
destroy(ctx);
@@ -989,14 +1036,14 @@ isc_mem_destroy(isc_mem_t **ctxp) {
ctx = *ctxp;
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
#if ISC_MEM_TRACKLINES
if (ctx->references != 1)
print_active(ctx, stderr);
#endif
REQUIRE(ctx->references == 1);
ctx->references--;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
destroy(ctx);
@@ -1007,9 +1054,9 @@ isc_result_t
isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
isc_result_t res;
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
res = isc_ondestroy_register(&ctx->ondestroy, task, event);
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
return (res);
}
@@ -1022,15 +1069,18 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
REQUIRE(VALID_CONTEXT(ctx));
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&ctx->lock);
- ptr = mem_getunlocked(ctx, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- ptr = mem_get(ctx, size);
- LOCK(&ctx->lock);
- if (ptr != NULL)
- mem_getstats(ctx, size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)
+ return (isc__mem_allocate(ctx, size FLARG_PASS));
+
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(ctx, &ctx->lock);
+ ptr = mem_getunlocked(ctx, size);
+ } else {
+ ptr = mem_get(ctx, size);
+ MCTXLOCK(ctx, &ctx->lock);
+ if (ptr != NULL)
+ mem_getstats(ctx, size);
+ }
ADD_TRACE(ctx, ptr, size, file, line);
if (ctx->hi_water != 0U && !ctx->hi_called &&
@@ -1045,7 +1095,7 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
fprintf(stderr, "maxinuse = %lu\n",
(unsigned long)ctx->inuse);
}
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
@@ -1057,18 +1107,32 @@ void
isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
{
isc_boolean_t call_water = ISC_FALSE;
+ size_info *si;
+ size_t oldsize;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL);
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&ctx->lock);
- mem_putunlocked(ctx, ptr, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- mem_put(ctx, ptr, size);
- LOCK(&ctx->lock);
- mem_putstats(ctx, ptr, size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
+ if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
+ si = &(((size_info *)ptr)[-1]);
+ oldsize = si->u.size - ALIGNMENT_SIZE;
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
+ oldsize -= ALIGNMENT_SIZE;
+ INSIST(oldsize == size);
+ }
+ isc__mem_free(ctx, ptr FLARG_PASS);
+ return;
+ }
+
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putunlocked(ctx, ptr, size);
+ } else {
+ mem_put(ctx, ptr, size);
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putstats(ctx, ptr, size);
+ }
DELETE_TRACE(ctx, ptr, size, file, line);
@@ -1084,7 +1148,7 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
if (ctx->water != NULL)
call_water = ISC_TRUE;
}
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
@@ -1141,7 +1205,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
const isc_mempool_t *pool;
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
for (i = 0; i <= ctx->max_size; i++) {
s = &ctx->stats[i];
@@ -1151,11 +1215,10 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
fprintf(out, "%s%5lu: %11lu gets, %11lu rem",
(i == ctx->max_size) ? ">=" : " ",
(unsigned long) i, s->totalgets, s->gets);
-#if ISC_MEM_USE_INTERNAL_MALLOC
- if (s->blocks != 0 || s->freefrags != 0)
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0 &&
+ (s->blocks != 0U || s->freefrags != 0U))
fprintf(out, " (%lu bl, %lu ff)",
s->blocks, s->freefrags);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
fputc('\n', out);
}
@@ -1203,7 +1266,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
print_active(ctx, out);
#endif
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
}
/*
@@ -1216,13 +1279,20 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
size_info *si;
size += ALIGNMENT_SIZE;
-#if ISC_MEM_USE_INTERNAL_MALLOC
- si = mem_getunlocked(ctx, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- si = mem_get(ctx, size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
+ size += ALIGNMENT_SIZE;
+
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0)
+ si = mem_getunlocked(ctx, size);
+ else
+ si = mem_get(ctx, size);
+
if (si == NULL)
return (NULL);
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
+ si->u.ctx = ctx;
+ si++;
+ }
si->u.size = size;
return (&si[1]);
}
@@ -1230,24 +1300,39 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
void *
isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
size_info *si;
+ isc_boolean_t call_water = ISC_FALSE;
REQUIRE(VALID_CONTEXT(ctx));
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&ctx->lock);
- si = isc__mem_allocateunlocked(ctx, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- si = isc__mem_allocateunlocked(ctx, size);
- LOCK(&ctx->lock);
- if (si != NULL)
- mem_getstats(ctx, si[-1].u.size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(ctx, &ctx->lock);
+ si = isc__mem_allocateunlocked(ctx, size);
+ } else {
+ si = isc__mem_allocateunlocked(ctx, size);
+ MCTXLOCK(ctx, &ctx->lock);
+ if (si != NULL)
+ mem_getstats(ctx, si[-1].u.size);
+ }
#if ISC_MEM_TRACKLINES
ADD_TRACE(ctx, si, si[-1].u.size, file, line);
#endif
+ if (ctx->hi_water != 0U && !ctx->hi_called &&
+ ctx->inuse > ctx->hi_water) {
+ ctx->hi_called = ISC_TRUE;
+ call_water = ISC_TRUE;
+ }
+ if (ctx->inuse > ctx->maxinuse) {
+ ctx->maxinuse = ctx->inuse;
+ if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
+ (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0)
+ fprintf(stderr, "maxinuse = %lu\n",
+ (unsigned long)ctx->inuse);
+ }
+ MCTXUNLOCK(ctx, &ctx->lock);
- UNLOCK(&ctx->lock);
+ if (call_water)
+ (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
return (si);
}
@@ -1256,25 +1341,47 @@ void
isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
size_info *si;
size_t size;
+ isc_boolean_t call_water= ISC_FALSE;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL);
- si = &(((size_info *)ptr)[-1]);
- size = si->u.size;
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
+ si = &(((size_info *)ptr)[-2]);
+ REQUIRE(si->u.ctx == ctx);
+ size = si[1].u.size;
+ } else {
+ si = &(((size_info *)ptr)[-1]);
+ size = si->u.size;
+ }
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&ctx->lock);
- mem_putunlocked(ctx, si, size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- mem_put(ctx, si, size);
- LOCK(&ctx->lock);
- mem_putstats(ctx, si, size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putunlocked(ctx, si, size);
+ } else {
+ mem_put(ctx, si, size);
+ MCTXLOCK(ctx, &ctx->lock);
+ mem_putstats(ctx, si, size);
+ }
DELETE_TRACE(ctx, ptr, size, file, line);
- UNLOCK(&ctx->lock);
+ /*
+ * The check against ctx->lo_water == 0 is for the condition
+ * when the context was pushed over hi_water but then had
+ * isc_mem_setwater() called with 0 for hi_water and lo_water.
+ */
+ if (ctx->hi_called &&
+ (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
+ ctx->hi_called = ISC_FALSE;
+
+ if (ctx->water != NULL)
+ call_water = ISC_TRUE;
+ }
+ MCTXUNLOCK(ctx, &ctx->lock);
+
+ if (call_water)
+ (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
}
@@ -1303,11 +1410,11 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
void
isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
ctx->checkfree = flag;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
}
/*
@@ -1317,11 +1424,11 @@ isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
void
isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
ctx->quota = quota;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
}
size_t
@@ -1329,11 +1436,11 @@ isc_mem_getquota(isc_mem_t *ctx) {
size_t quota;
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
quota = ctx->quota;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
return (quota);
}
@@ -1343,11 +1450,11 @@ isc_mem_inuse(isc_mem_t *ctx) {
size_t inuse;
REQUIRE(VALID_CONTEXT(ctx));
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
inuse = ctx->inuse;
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
return (inuse);
}
@@ -1356,24 +1463,38 @@ void
isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater)
{
+ isc_boolean_t callwater = ISC_FALSE;
+ isc_mem_water_t oldwater;
+ void *oldwater_arg;
+
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(hiwater >= lowater);
- LOCK(&ctx->lock);
+ MCTXLOCK(ctx, &ctx->lock);
+ oldwater = ctx->water;
+ oldwater_arg = ctx->water_arg;
if (water == NULL) {
+ callwater = ctx->hi_called;
ctx->water = NULL;
ctx->water_arg = NULL;
ctx->hi_water = 0;
ctx->lo_water = 0;
ctx->hi_called = ISC_FALSE;
} else {
+ if (ctx->hi_called &&
+ (ctx->water != water || ctx->water_arg != water_arg ||
+ ctx->inuse < lowater || lowater == 0U))
+ callwater = ISC_TRUE;
ctx->water = water;
ctx->water_arg = water_arg;
ctx->hi_water = hiwater;
ctx->lo_water = lowater;
ctx->hi_called = ISC_FALSE;
}
- UNLOCK(&ctx->lock);
+ MCTXUNLOCK(ctx, &ctx->lock);
+
+ if (callwater && oldwater != NULL)
+ (oldwater)(oldwater_arg, ISC_MEM_LOWATER);
}
/*
@@ -1413,9 +1534,9 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
*mpctxp = mpctx;
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
return (ISC_R_SUCCESS);
}
@@ -1467,28 +1588,28 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
/*
* Return any items on the free list
*/
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
while (mpctx->items != NULL) {
INSIST(mpctx->freecount > 0);
mpctx->freecount--;
item = mpctx->items;
mpctx->items = item->next;
-#if ISC_MEM_USE_INTERNAL_MALLOC
- mem_putunlocked(mctx, item, mpctx->size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- mem_put(mctx, item, mpctx->size);
- mem_putstats(mctx, item, mpctx->size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ mem_putunlocked(mctx, item, mpctx->size);
+ } else {
+ mem_put(mctx, item, mpctx->size);
+ mem_putstats(mctx, item, mpctx->size);
+ }
}
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
/*
* Remove our linked list entry from the memory context.
*/
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
ISC_LIST_UNLINK(mctx->pools, mpctx, link);
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
mpctx->magic = 0;
@@ -1547,22 +1668,22 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
* We need to dip into the well. Lock the memory context here and
* fill up our free list.
*/
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
for (i = 0; i < mpctx->fillcount; i++) {
-#if ISC_MEM_USE_INTERNAL_MALLOC
- item = mem_getunlocked(mctx, mpctx->size);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- item = mem_get(mctx, mpctx->size);
- if (item != NULL)
- mem_getstats(mctx, mpctx->size);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ item = mem_getunlocked(mctx, mpctx->size);
+ } else {
+ item = mem_get(mctx, mpctx->size);
+ if (item != NULL)
+ mem_getstats(mctx, mpctx->size);
+ }
if (item == NULL)
break;
item->next = mpctx->items;
mpctx->items = item;
mpctx->freecount++;
}
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
/*
* If we didn't get any items, return NULL.
@@ -1582,9 +1703,9 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
#if ISC_MEM_TRACKLINES
if (item != NULL) {
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
ADD_TRACE(mctx, item, mpctx->size, file, line);
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
}
#endif /* ISC_MEM_TRACKLINES */
@@ -1608,25 +1729,25 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
mpctx->allocated--;
#if ISC_MEM_TRACKLINES
- LOCK(&mctx->lock);
+ MCTXLOCK(mctx, &mctx->lock);
DELETE_TRACE(mctx, mem, mpctx->size, file, line);
- UNLOCK(&mctx->lock);
+ MCTXUNLOCK(mctx, &mctx->lock);
#endif /* ISC_MEM_TRACKLINES */
/*
* If our free list is full, return this to the mctx directly.
*/
if (mpctx->freecount >= mpctx->freemax) {
-#if ISC_MEM_USE_INTERNAL_MALLOC
- LOCK(&mctx->lock);
- mem_putunlocked(mctx, mem, mpctx->size);
- UNLOCK(&mctx->lock);
-#else /* ISC_MEM_USE_INTERNAL_MALLOC */
- mem_put(mctx, mem, mpctx->size);
- LOCK(&mctx->lock);
- mem_putstats(mctx, mem, mpctx->size);
- UNLOCK(&mctx->lock);
-#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
+ if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ MCTXLOCK(mctx, &mctx->lock);
+ mem_putunlocked(mctx, mem, mpctx->size);
+ MCTXUNLOCK(mctx, &mctx->lock);
+ } else {
+ mem_put(mctx, mem, mpctx->size);
+ MCTXLOCK(mctx, &mctx->lock);
+ mem_putstats(mctx, mem, mpctx->size);
+ MCTXUNLOCK(mctx, &mctx->lock);
+ }
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return;
@@ -1774,3 +1895,60 @@ isc_mempool_getfillcount(isc_mempool_t *mpctx) {
return (fillcount);
}
+
+void
+isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
+
+ REQUIRE(VALID_CONTEXT(ctx));
+ REQUIRE(file != NULL);
+
+#if !ISC_MEM_TRACKLINES
+ UNUSED(ctx);
+ UNUSED(file);
+#else
+ print_active(ctx, file);
+#endif
+}
+
+void
+isc_mem_printallactive(FILE *file) {
+#if !ISC_MEM_TRACKLINES
+ UNUSED(file);
+#else
+ isc_mem_t *ctx;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+
+ LOCK(&lock);
+ for (ctx = ISC_LIST_HEAD(contexts);
+ ctx != NULL;
+ ctx = ISC_LIST_NEXT(ctx, link)) {
+ fprintf(file, "context: %p\n", ctx);
+ print_active(ctx, file);
+ }
+ UNLOCK(&lock);
+#endif
+}
+
+void
+isc_mem_checkdestroyed(FILE *file) {
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+
+ LOCK(&lock);
+ if (!ISC_LIST_EMPTY(contexts)) {
+#if ISC_MEM_TRACKLINES
+ isc_mem_t *ctx;
+
+ for (ctx = ISC_LIST_HEAD(contexts);
+ ctx != NULL;
+ ctx = ISC_LIST_NEXT(ctx, link)) {
+ fprintf(file, "context: %p\n", ctx);
+ print_active(ctx, file);
+ }
+ fflush(file);
+#endif
+ INSIST(0);
+ }
+ UNLOCK(&lock);
+}
diff --git a/usr.sbin/bind/lib/isc/print.c b/usr.sbin/bind/lib/isc/print.c
index 696ad3cb7df..d0436316d27 100644
--- a/usr.sbin/bind/lib/isc/print.c
+++ b/usr.sbin/bind/lib/isc/print.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: print.c,v 1.22.2.3.2.4 2006/04/17 18:27:20 explorer Exp $ */
+/* $ISC: print.c,v 1.27.18.3 2006/04/17 18:27:33 explorer Exp $ */
/*! \file */
diff --git a/usr.sbin/bind/lib/isc/pthreads/thread.c b/usr.sbin/bind/lib/isc/pthreads/thread.c
index 459e65a9dfe..fd216c2054d 100644
--- a/usr.sbin/bind/lib/isc/pthreads/thread.c
+++ b/usr.sbin/bind/lib/isc/pthreads/thread.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: thread.c,v 1.9.2.2.2.2 2004/12/04 06:50:03 marka Exp $ */
+/* $ISC: thread.c,v 1.12.18.3 2005/04/29 00:17:05 marka Exp $ */
+
+/*! \file */
#include <config.h>
diff --git a/usr.sbin/bind/lib/isc/random.c b/usr.sbin/bind/lib/isc/random.c
index 2d4f9495930..442d35cd485 100644
--- a/usr.sbin/bind/lib/isc/random.c
+++ b/usr.sbin/bind/lib/isc/random.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * 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
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: random.c,v 1.15.74.5 2004/03/08 09:04:49 marka Exp $ */
+/* $ISC: random.c,v 1.21.18.2 2005/04/29 00:16:48 marka Exp $ */
+
+/*! \file */
#include <config.h>
diff --git a/usr.sbin/bind/lib/isc/rwlock.c b/usr.sbin/bind/lib/isc/rwlock.c
index 8cec462b9d4..ba0bd8ba9b8 100644
--- a/usr.sbin/bind/lib/isc/rwlock.c
+++ b/usr.sbin/bind/lib/isc/rwlock.c
@@ -15,12 +15,15 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rwlock.c,v 1.33.2.4.2.3 2005/03/17 03:58:32 marka Exp $ */
+/* $ISC: rwlock.c,v 1.37.18.5 2005/07/12 01:22:30 marka Exp $ */
+
+/*! \file */
#include <config.h>
#include <stddef.h>
+#include <isc/atomic.h>
#include <isc/magic.h>
#include <isc/msgs.h>
#include <isc/platform.h>
@@ -81,6 +84,20 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
*/
rwl->magic = 0;
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+ rwl->write_requests = 0;
+ rwl->write_completions = 0;
+ rwl->cnt_and_flag = 0;
+ rwl->readers_waiting = 0;
+ rwl->write_granted = 0;
+ if (read_quota != 0) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "read quota is not supported");
+ }
+ if (write_quota == 0)
+ write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
+ rwl->write_quota = write_quota;
+#else
rwl->type = isc_rwlocktype_read;
rwl->original = isc_rwlocktype_none;
rwl->active = 0;
@@ -93,15 +110,12 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
if (write_quota == 0)
write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
rwl->write_quota = write_quota;
+#endif
+
result = isc_mutex_init(&rwl->lock);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s: %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"),
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
result = isc_condition_init(&rwl->readable);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -111,7 +125,6 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
isc_result_totext(result));
result = ISC_R_UNEXPECTED;
goto destroy_lock;
-
}
result = isc_condition_init(&rwl->writeable);
if (result != ISC_R_SUCCESS) {
@@ -136,6 +149,389 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
return (result);
}
+void
+isc_rwlock_destroy(isc_rwlock_t *rwl) {
+ REQUIRE(VALID_RWLOCK(rwl));
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+ REQUIRE(rwl->write_requests == rwl->write_completions &&
+ rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
+#else
+ LOCK(&rwl->lock);
+ REQUIRE(rwl->active == 0 &&
+ rwl->readers_waiting == 0 &&
+ rwl->writers_waiting == 0);
+ UNLOCK(&rwl->lock);
+#endif
+
+ rwl->magic = 0;
+ (void)isc_condition_destroy(&rwl->readable);
+ (void)isc_condition_destroy(&rwl->writeable);
+ DESTROYLOCK(&rwl->lock);
+}
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+
+/*
+ * When some architecture-dependent atomic operations are available,
+ * rwlock can be more efficient than the generic algorithm defined below.
+ * The basic algorithm is described in the following URL:
+ * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
+ *
+ * The key is to use the following integer variables modified atomically:
+ * write_requests, write_completions, and cnt_and_flag.
+ *
+ * write_requests and write_completions act as a waiting queue for writers
+ * in order to ensure the FIFO order. Both variables begin with the initial
+ * value of 0. When a new writer tries to get a write lock, it increments
+ * write_requests and gets the previous value of the variable as a "ticket".
+ * When write_completions reaches the ticket number, the new writer can start
+ * writing. When the writer completes its work, it increments
+ * write_completions so that another new writer can start working. If the
+ * write_requests is not equal to write_completions, it means a writer is now
+ * working or waiting. In this case, a new readers cannot start reading, or
+ * in other words, this algorithm basically prefers writers.
+ *
+ * cnt_and_flag is a "lock" shared by all readers and writers. This integer
+ * variable is a kind of structure with two members: writer_flag (1 bit) and
+ * reader_count (31 bits). The writer_flag shows whether a writer is working,
+ * and the reader_count shows the number of readers currently working or almost
+ * ready for working. A writer who has the current "ticket" tries to get the
+ * lock by exclusively setting the writer_flag to 1, provided that the whole
+ * 32-bit is 0 (meaning no readers or writers working). On the other hand,
+ * a new reader tries to increment the "reader_count" field provided that
+ * the writer_flag is 0 (meaning there is no writer working).
+ *
+ * If some of the above operations fail, the reader or the writer sleeps
+ * until the related condition changes. When a working reader or writer
+ * completes its work, some readers or writers are sleeping, and the condition
+ * that suspended the reader or writer has changed, it wakes up the sleeping
+ * readers or writers.
+ *
+ * As already noted, this algorithm basically prefers writers. In order to
+ * prevent readers from starving, however, the algorithm also introduces the
+ * "writer quota" (Q). When Q consecutive writers have completed their work,
+ * suspending readers, the last writer will wake up the readers, even if a new
+ * writer is waiting.
+ *
+ * Implementation specific note: due to the combination of atomic operations
+ * and a mutex lock, ordering between the atomic operation and locks can be
+ * very sensitive in some cases. In particular, it is generally very important
+ * to check the atomic variable that requires a reader or writer to sleep after
+ * locking the mutex and before actually sleeping; otherwise, it could be very
+ * likely to cause a deadlock. For example, assume "var" is a variable
+ * atomically modified, then the corresponding code would be:
+ * if (var == need_sleep) {
+ * LOCK(lock);
+ * if (var == need_sleep)
+ * WAIT(cond, lock);
+ * UNLOCK(lock);
+ * }
+ * The second check is important, since "var" is protected by the atomic
+ * operation, not by the mutex, and can be changed just before sleeping.
+ * (The first "if" could be omitted, but this is also important in order to
+ * make the code efficient by avoiding the use of the mutex unless it is
+ * really necessary.)
+ */
+
+#define WRITER_ACTIVE 0x1
+#define READER_INCR 0x2
+
+isc_result_t
+isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+ isc_int32_t cntflag;
+
+ REQUIRE(VALID_RWLOCK(rwl));
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_PRELOCK, "prelock"), rwl, type);
+#endif
+
+ if (type == isc_rwlocktype_read) {
+ if (rwl->write_requests != rwl->write_completions) {
+ /* there is a waiting or active writer */
+ LOCK(&rwl->lock);
+ if (rwl->write_requests != rwl->write_completions) {
+ rwl->readers_waiting++;
+ WAIT(&rwl->readable, &rwl->lock);
+ rwl->readers_waiting--;
+ }
+ UNLOCK(&rwl->lock);
+ }
+
+ cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
+ while (1) {
+ if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
+ break;
+
+ /* A writer is still working */
+ LOCK(&rwl->lock);
+ rwl->readers_waiting++;
+ if ((rwl->cnt_and_flag & WRITER_ACTIVE) != 0)
+ WAIT(&rwl->readable, &rwl->lock);
+ rwl->readers_waiting--;
+ UNLOCK(&rwl->lock);
+
+ /*
+ * Typically, the reader should be able to get a lock
+ * at this stage:
+ * (1) there should have been no pending writer when
+ * the reader was trying to increment the
+ * counter; otherwise, the writer should be in
+ * the waiting queue, preventing the reader from
+ * proceeding to this point.
+ * (2) once the reader increments the counter, no
+ * more writer can get a lock.
+ * Still, it is possible another writer can work at
+ * this point, e.g. in the following scenario:
+ * A previous writer unlocks the writer lock.
+ * This reader proceeds to point (1).
+ * A new writer appears, and gets a new lock before
+ * the reader increments the counter.
+ * The reader then increments the counter.
+ * The previous writer notices there is a waiting
+ * reader who is almost ready, and wakes it up.
+ * So, the reader needs to confirm whether it can now
+ * read explicitly (thus we loop). Note that this is
+ * not an infinite process, since the reader has
+ * incremented the counter at this point.
+ */
+ }
+
+ /*
+ * If we are temporarily preferred to writers due to the writer
+ * quota, reset the condition (race among readers doesn't
+ * matter).
+ */
+ rwl->write_granted = 0;
+ } else {
+ isc_int32_t prev_writer;
+
+ /* enter the waiting queue, and wait for our turn */
+ prev_writer = isc_atomic_xadd(&rwl->write_requests, 1);
+ while (rwl->write_completions != prev_writer) {
+ LOCK(&rwl->lock);
+ if (rwl->write_completions != prev_writer) {
+ WAIT(&rwl->writeable, &rwl->lock);
+ UNLOCK(&rwl->lock);
+ continue;
+ }
+ UNLOCK(&rwl->lock);
+ break;
+ }
+
+ while (1) {
+ cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
+ WRITER_ACTIVE);
+ if (cntflag == 0)
+ break;
+
+ /* Another active reader or writer is working. */
+ LOCK(&rwl->lock);
+ if (rwl->cnt_and_flag != 0)
+ WAIT(&rwl->writeable, &rwl->lock);
+ UNLOCK(&rwl->lock);
+ }
+
+ INSIST((rwl->cnt_and_flag & WRITER_ACTIVE) != 0);
+ rwl->write_granted++;
+ }
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_POSTLOCK, "postlock"), rwl, type);
+#endif
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+ isc_int32_t cntflag;
+
+ REQUIRE(VALID_RWLOCK(rwl));
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_PRELOCK, "prelock"), rwl, type);
+#endif
+
+ if (type == isc_rwlocktype_read) {
+ /* If a writer is waiting or working, we fail. */
+ if (rwl->write_requests != rwl->write_completions)
+ return (ISC_R_LOCKBUSY);
+
+ /* Otherwise, be ready for reading. */
+ cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
+ if ((cntflag & WRITER_ACTIVE) != 0) {
+ /*
+ * A writer is working. We lose, and cancel the read
+ * request.
+ */
+ cntflag = isc_atomic_xadd(&rwl->cnt_and_flag,
+ -READER_INCR);
+ /*
+ * If no other readers are waiting and we've suspended
+ * new writers in this short period, wake them up.
+ */
+ if (cntflag == READER_INCR &&
+ rwl->write_completions != rwl->write_requests) {
+ LOCK(&rwl->lock);
+ BROADCAST(&rwl->writeable);
+ UNLOCK(&rwl->lock);
+ }
+
+ return (ISC_R_LOCKBUSY);
+ }
+ } else {
+ /* Try locking without entering the waiting queue. */
+ cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
+ WRITER_ACTIVE);
+ if (cntflag != 0)
+ return (ISC_R_LOCKBUSY);
+
+ /*
+ * XXXJT: jump into the queue, possibly breaking the writer
+ * order.
+ */
+ (void)isc_atomic_xadd(&rwl->write_completions, -1);
+
+ rwl->write_granted++;
+ }
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_POSTLOCK, "postlock"), rwl, type);
+#endif
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
+ isc_int32_t prevcnt;
+
+ REQUIRE(VALID_RWLOCK(rwl));
+
+ /* Try to acquire write access. */
+ prevcnt = isc_atomic_cmpxchg(&rwl->cnt_and_flag,
+ READER_INCR, WRITER_ACTIVE);
+ /*
+ * There must have been no writer, and there must have been at least
+ * one reader.
+ */
+ INSIST((prevcnt & WRITER_ACTIVE) == 0 &&
+ (prevcnt & ~WRITER_ACTIVE) != 0);
+
+ if (prevcnt == READER_INCR) {
+ /*
+ * We are the only reader and have been upgraded.
+ * Now jump into the head of the writer waiting queue.
+ */
+ (void)isc_atomic_xadd(&rwl->write_completions, -1);
+ } else
+ return (ISC_R_LOCKBUSY);
+
+ return (ISC_R_SUCCESS);
+
+}
+
+void
+isc_rwlock_downgrade(isc_rwlock_t *rwl) {
+ isc_int32_t prev_readers;
+
+ REQUIRE(VALID_RWLOCK(rwl));
+
+ /* Become an active reader. */
+ prev_readers = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
+ /* We must have been a writer. */
+ INSIST((prev_readers & WRITER_ACTIVE) != 0);
+
+ /* Complete write */
+ (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
+ (void)isc_atomic_xadd(&rwl->write_completions, 1);
+
+ /* Resume other readers */
+ LOCK(&rwl->lock);
+ if (rwl->readers_waiting > 0)
+ BROADCAST(&rwl->readable);
+ UNLOCK(&rwl->lock);
+}
+
+isc_result_t
+isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+ isc_int32_t prev_cnt;
+
+ REQUIRE(VALID_RWLOCK(rwl));
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);
+#endif
+
+ if (type == isc_rwlocktype_read) {
+ prev_cnt = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR);
+
+ /*
+ * If we're the last reader and any writers are waiting, wake
+ * them up. We need to wake up all of them to ensure the
+ * FIFO order.
+ */
+ if (prev_cnt == READER_INCR &&
+ rwl->write_completions != rwl->write_requests) {
+ LOCK(&rwl->lock);
+ BROADCAST(&rwl->writeable);
+ UNLOCK(&rwl->lock);
+ }
+ } else {
+ isc_boolean_t wakeup_writers = ISC_TRUE;
+
+ /*
+ * Reset the flag, and (implicitly) tell other writers
+ * we are done.
+ */
+ (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
+ (void)isc_atomic_xadd(&rwl->write_completions, 1);
+
+ if (rwl->write_granted >= rwl->write_quota ||
+ rwl->write_requests == rwl->write_completions ||
+ (rwl->cnt_and_flag & ~WRITER_ACTIVE) != 0) {
+ /*
+ * We have passed the write quota, no writer is
+ * waiting, or some readers are almost ready, pending
+ * possible writers. Note that the last case can
+ * happen even if write_requests != write_completions
+ * (which means a new writer in the queue), so we need
+ * to catch the case explicitly.
+ */
+ LOCK(&rwl->lock);
+ if (rwl->readers_waiting > 0) {
+ wakeup_writers = ISC_FALSE;
+ BROADCAST(&rwl->readable);
+ }
+ UNLOCK(&rwl->lock);
+ }
+
+ if (rwl->write_requests != rwl->write_completions &&
+ wakeup_writers) {
+ LOCK(&rwl->lock);
+ BROADCAST(&rwl->writeable);
+ UNLOCK(&rwl->lock);
+ }
+ }
+
+#ifdef ISC_RWLOCK_TRACE
+ print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+ ISC_MSG_POSTUNLOCK, "postunlock"),
+ rwl, type);
+#endif
+
+ return (ISC_R_SUCCESS);
+}
+
+#else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+
static isc_result_t
doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {
isc_boolean_t skip = ISC_FALSE;
@@ -321,22 +717,7 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
return (ISC_R_SUCCESS);
}
-void
-isc_rwlock_destroy(isc_rwlock_t *rwl) {
- REQUIRE(VALID_RWLOCK(rwl));
-
- LOCK(&rwl->lock);
- REQUIRE(rwl->active == 0 &&
- rwl->readers_waiting == 0 &&
- rwl->writers_waiting == 0);
- UNLOCK(&rwl->lock);
-
- rwl->magic = 0;
- (void)isc_condition_destroy(&rwl->readable);
- (void)isc_condition_destroy(&rwl->writeable);
- DESTROYLOCK(&rwl->lock);
-}
-
+#endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
#else /* ISC_PLATFORM_USETHREADS */
isc_result_t
diff --git a/usr.sbin/bind/lib/isc/sha1.c b/usr.sbin/bind/lib/isc/sha1.c
index e94a9b845f5..30d5cc33ddf 100644
--- a/usr.sbin/bind/lib/isc/sha1.c
+++ b/usr.sbin/bind/lib/isc/sha1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,16 +15,14 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: sha1.c,v 1.10.2.2.2.3 2004/03/06 08:14:35 marka Exp $ */
+/* $ISC: sha1.c,v 1.14.18.2 2005/04/29 00:16:49 marka Exp $ */
+/* $OpenBSD: sha1.c,v 1.4 2007/12/09 13:39:44 jakob Exp $ */
-/* $NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp $ */
-/* $OpenBSD: sha1.c,v 1.3 2004/09/28 17:14:07 jakob Exp $ */
-
-/*
+/*! \file
* SHA-1 in C
- * By Steve Reid <steve@edmweb.com>
+ * \author By Steve Reid <steve@edmweb.com>
* 100% Public Domain
- *
+ * \verbatim
* Test Vectors (from FIPS PUB 180-1)
* "abc"
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
@@ -32,6 +30,7 @@
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
* A million repetitions of "a"
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ * \endverbatim
*/
#include "config.h"
@@ -44,7 +43,8 @@
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-/*
+/*@{*/
+/*!
* blk0() and blk() perform the initial expand.
* I got the idea of expanding during the round function from SSLeay
*/
@@ -61,7 +61,9 @@
^ block->l[(i + 2) & 15] \
^ block->l[i & 15], 1))
-/*
+/*@}*/
+/*@{*/
+/*!
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
*/
#define R0(v,w,x,y,z,i) \
@@ -80,6 +82,8 @@
z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
w = rol(w, 30);
+/*@}*/
+
typedef union {
unsigned char c[64];
unsigned int l[16];
@@ -154,7 +158,7 @@ do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
}
#endif
-/*
+/*!
* Hash a single 512-bit block. This is the core of the algorithm.
*/
static void
@@ -217,7 +221,7 @@ transform(isc_uint32_t state[5], const unsigned char buffer[64]) {
}
-/*
+/*!
* isc_sha1_init - Initialize new context
*/
void
@@ -240,7 +244,7 @@ isc_sha1_invalidate(isc_sha1_t *context) {
memset(context, 0, sizeof(isc_sha1_t));
}
-/*
+/*!
* Run your data through this.
*/
void
@@ -270,7 +274,7 @@ isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
}
-/*
+/*!
* Add padding and return the message digest.
*/
diff --git a/usr.sbin/bind/lib/isc/sockaddr.c b/usr.sbin/bind/lib/isc/sockaddr.c
index 1819cfda06e..730376f3f84 100644
--- a/usr.sbin/bind/lib/isc/sockaddr.c
+++ b/usr.sbin/bind/lib/isc/sockaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: sockaddr.c,v 1.48.2.1.2.12 2006/03/02 00:37:20 marka Exp $ */
+/* $ISC: sockaddr.c,v 1.59.18.9 2006/06/21 01:25:40 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -33,6 +35,21 @@
isc_boolean_t
isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPPORT|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int flags)
+{
REQUIRE(a != NULL && b != NULL);
if (a->length != b->length)
@@ -47,21 +64,33 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
return (ISC_FALSE);
switch (a->type.sa.sa_family) {
case AF_INET:
- if (memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr,
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr,
sizeof(a->type.sin.sin_addr)) != 0)
return (ISC_FALSE);
- if (a->type.sin.sin_port != b->type.sin.sin_port)
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin.sin_port != b->type.sin.sin_port)
return (ISC_FALSE);
break;
case AF_INET6:
- if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
sizeof(a->type.sin6.sin6_addr)) != 0)
return (ISC_FALSE);
#ifdef ISC_PLATFORM_HAVESCOPEID
- if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+ /*
+ * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return
+ * ISC_FALSE if one of the scopes in zero.
+ */
+ if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 &&
+ a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id &&
+ ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 ||
+ (a->type.sin6.sin6_scope_id != 0 &&
+ b->type.sin6.sin6_scope_id != 0)))
return (ISC_FALSE);
#endif
- if (a->type.sin6.sin6_port != b->type.sin6.sin6_port)
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin6.sin6_port != b->type.sin6.sin6_port)
return (ISC_FALSE);
break;
default:
@@ -72,37 +101,6 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
}
isc_boolean_t
-isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
- REQUIRE(a != NULL && b != NULL);
-
- if (a->length != b->length)
- return (ISC_FALSE);
-
- if (a->type.sa.sa_family != b->type.sa.sa_family)
- return (ISC_FALSE);
- switch (a->type.sa.sa_family) {
- case AF_INET:
- if (memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr,
- sizeof(a->type.sin.sin_addr)) != 0)
- return (ISC_FALSE);
- break;
- case AF_INET6:
- if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
- sizeof(a->type.sin6.sin6_addr)) != 0)
- return (ISC_FALSE);
-#ifdef ISC_PLATFORM_HAVESCOPEID
- if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
- return (ISC_FALSE);
-#endif
- break;
- default:
- if (memcmp(&a->type, &b->type, a->length) != 0)
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-isc_boolean_t
isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
unsigned int prefixlen)
{
@@ -134,6 +132,23 @@ isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) {
case AF_INET6:
snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin6.sin6_port));
break;
+#ifdef ISC_PLAFORM_HAVESYSUNH
+ case AF_UNIX:
+ plen = strlen(sockaddr->type.sunix.sun_path);
+ if (plen >= isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, sockaddr->type.sunix.sun_path, plen);
+
+ /*
+ * Null terminate after used region.
+ */
+ isc_buffer_availableregion(target, &avail);
+ INSIST(avail.length >= 1);
+ avail.base[0] = '\0';
+
+ return (ISC_R_SUCCESS);
+#endif
default:
return (ISC_R_FAILURE);
}
@@ -425,8 +440,12 @@ isc_boolean_t
isc_sockaddr_ismulticast(const isc_sockaddr_t *sockaddr) {
isc_netaddr_t netaddr;
- isc_netaddr_fromsockaddr(&netaddr, sockaddr);
- return (isc_netaddr_ismulticast(&netaddr));
+ if (sockaddr->type.sa.sa_family == AF_INET ||
+ sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_ismulticast(&netaddr));
+ }
+ return (ISC_FALSE);
}
isc_boolean_t
@@ -461,3 +480,24 @@ isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) {
}
return (ISC_FALSE);
}
+
+isc_result_t
+isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path))
+ return (ISC_R_NOSPACE);
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->length = sizeof(sockaddr->type.sunix);
+ sockaddr->type.sunix.sun_family = AF_UNIX;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sunix.sun_len =
+ (unsigned char)sizeof(sockaddr->type.sunix);
+#endif
+ strcpy(sockaddr->type.sunix.sun_path, path);
+ return (ISC_R_SUCCESS);
+#else
+ UNUSED(sockaddr);
+ UNUSED(path);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
diff --git a/usr.sbin/bind/lib/isc/string.c b/usr.sbin/bind/lib/isc/string.c
index d01af8ac755..e556f5b9ed1 100644
--- a/usr.sbin/bind/lib/isc/string.c
+++ b/usr.sbin/bind/lib/isc/string.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,13 +15,19 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: string.c,v 1.6.164.5 2004/09/16 01:00:58 marka Exp $ */
+/* $ISC: string.c,v 1.10.18.7 2006/10/03 23:50:51 marka Exp $ */
+
+/*! \file */
#include <config.h>
#include <ctype.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/region.h>
#include <isc/string.h>
+#include <isc/util.h>
static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
@@ -89,6 +95,105 @@ isc_string_touint64(char *source, char **end, int base) {
return (tmp);
}
+isc_result_t
+isc_string_copy(char *target, size_t size, const char *source) {
+ REQUIRE(size > 0U);
+
+ if (strlcpy(target, source, size) >= size) {
+ memset(target, ISC_STRING_MAGIC, size);
+ return (ISC_R_NOSPACE);
+ }
+
+ ENSURE(strlen(target) < size);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_string_copy_truncate(char *target, size_t size, const char *source) {
+ REQUIRE(size > 0U);
+
+ strlcpy(target, source, size);
+
+ ENSURE(strlen(target) < size);
+}
+
+isc_result_t
+isc_string_append(char *target, size_t size, const char *source) {
+ REQUIRE(size > 0U);
+ REQUIRE(strlen(target) < size);
+
+ if (strlcat(target, source, size) >= size) {
+ memset(target, ISC_STRING_MAGIC, size);
+ return (ISC_R_NOSPACE);
+ }
+
+ ENSURE(strlen(target) < size);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_string_append_truncate(char *target, size_t size, const char *source) {
+ REQUIRE(size > 0U);
+ REQUIRE(strlen(target) < size);
+
+ strlcat(target, source, size);
+
+ ENSURE(strlen(target) < size);
+}
+
+isc_result_t
+isc_string_printf(char *target, size_t size, const char *format, ...) {
+ va_list args;
+ size_t n;
+
+ REQUIRE(size > 0U);
+
+ va_start(args, format);
+ n = vsnprintf(target, size, format, args);
+ va_end(args);
+
+ if (n >= size) {
+ memset(target, ISC_STRING_MAGIC, size);
+ return (ISC_R_NOSPACE);
+ }
+
+ ENSURE(strlen(target) < size);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_string_printf_truncate(char *target, size_t size, const char *format, ...) {
+ va_list args;
+ size_t n;
+
+ REQUIRE(size > 0U);
+
+ va_start(args, format);
+ n = vsnprintf(target, size, format, args);
+ va_end(args);
+
+ ENSURE(strlen(target) < size);
+}
+
+char *
+isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
+ char *target;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(source != NULL);
+
+ target = (char *) isc_mem_allocate(mctx, source->length + 1);
+ if (target != NULL) {
+ memcpy(source->base, target, source->length);
+ target[source->length] = '\0';
+ }
+
+ return (target);
+}
+
char *
isc_string_separate(char **stringp, const char *delim) {
char *string = *stringp;
diff --git a/usr.sbin/bind/lib/isc/task.c b/usr.sbin/bind/lib/isc/task.c
index ce0327067b6..efffd536323 100644
--- a/usr.sbin/bind/lib/isc/task.c
+++ b/usr.sbin/bind/lib/isc/task.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,10 +15,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: task.c,v 1.85.2.3.8.5 2004/10/15 00:45:45 marka Exp $ */
+/* $ISC: task.c,v 1.91.18.6 2006/01/04 23:50:23 marka Exp $ */
-/*
- * Principal Author: Bob Halley
+/*! \file
+ * \author Principal Author: Bob Halley
*/
/*
@@ -174,6 +174,7 @@ isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
{
isc_task_t *task;
isc_boolean_t exiting;
+ isc_result_t result;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(taskp != NULL && *taskp == NULL);
@@ -183,13 +184,10 @@ isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
return (ISC_R_NOMEMORY);
XTRACE("isc_task_create");
task->manager = manager;
- if (isc_mutex_init(&task->lock) != ISC_R_SUCCESS) {
+ result = isc_mutex_init(&task->lock);
+ if (result != ISC_R_SUCCESS) {
isc_mem_put(manager->mctx, task, sizeof(*task));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- return (ISC_R_UNEXPECTED);
+ return (result);
}
task->state = task_state_idle;
task->references = 1;
@@ -1066,14 +1064,10 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (ISC_R_NOMEMORY);
manager->magic = TASK_MANAGER_MAGIC;
manager->mctx = NULL;
- if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- result = ISC_R_UNEXPECTED;
+ result = isc_mutex_init(&manager->lock);
+ if (result != ISC_R_SUCCESS)
goto cleanup_mgr;
- }
+
#ifdef ISC_PLATFORM_USETHREADS
manager->workers = 0;
manager->threads = isc_mem_allocate(mctx,
@@ -1235,6 +1229,8 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
UNLOCK(&manager->lock);
while (isc__taskmgr_ready())
(void)isc__taskmgr_dispatch();
+ if (!ISC_LIST_EMPTY(manager->tasks))
+ isc_mem_printallactive(stderr);
INSIST(ISC_LIST_EMPTY(manager->tasks));
#endif /* ISC_PLATFORM_USETHREADS */
diff --git a/usr.sbin/bind/lib/isc/unix/Makefile.in b/usr.sbin/bind/lib/isc/unix/Makefile.in
index 38c331edf85..9aa87a11aa4 100644
--- a/usr.sbin/bind/lib/isc/unix/Makefile.in
+++ b/usr.sbin/bind/lib/isc/unix/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $ISC: Makefile.in,v 1.35.2.1.10.2 2004/06/22 02:48:36 marka Exp $
+# $ISC: Makefile.in,v 1.38.18.1 2004/06/22 02:54:06 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/usr.sbin/bind/lib/isc/unix/dir.c b/usr.sbin/bind/lib/isc/unix/dir.c
index 5167cc7f5df..78b3014f928 100644
--- a/usr.sbin/bind/lib/isc/unix/dir.c
+++ b/usr.sbin/bind/lib/isc/unix/dir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * 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
@@ -15,9 +15,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: dir.c,v 1.18.2.1.2.3 2004/03/08 09:04:55 marka Exp $ */
+/* $ISC: dir.c,v 1.20.18.3 2005/09/05 00:18:30 marka Exp $ */
-/* Principal Authors: DCL */
+/*! \file
+ * \author Principal Authors: DCL */
#include <config.h>
@@ -50,18 +51,37 @@ isc_dir_init(isc_dir_t *dir) {
dir->magic = ISC_DIR_MAGIC;
}
-/*
- * Allocate workspace and open directory stream. If either one fails,
+/*!
+ * \brief 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) {
+ char *p;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_DIR(dir));
REQUIRE(dirname != NULL);
/*
+ * Copy directory name. Need to have enough space for the name,
+ * a possible path separator, the wildcard, and the final NUL.
+ */
+ if (strlen(dirname) + 3 > sizeof(dir->dirname))
+ /* XXXDCL ? */
+ return (ISC_R_NOSPACE);
+ strcpy(dir->dirname, dirname);
+
+ /*
+ * Append path separator, if needed, and "*".
+ */
+ p = dir->dirname + strlen(dir->dirname);
+ if (dir->dirname < p && *(p - 1) != '/')
+ *p++ = '/';
+ *p++ = '*';
+ *p++ = '\0';
+
+ /*
* Open stream.
*/
dir->handle = opendir(dirname);
@@ -72,8 +92,10 @@ isc_dir_open(isc_dir_t *dir, const char *dirname) {
return (result);
}
-/*
- * Return previously retrieved file or get next one. Unix's dirent has
+/*!
+ * \brief Return previously retrieved file or get next one.
+
+ * Unix's dirent has
* separate open and read functions, but the Win32 and DOS interfaces open
* the dir stream and reads the first file in one operation.
*/
@@ -107,8 +129,8 @@ isc_dir_read(isc_dir_t *dir) {
return (ISC_R_SUCCESS);
}
-/*
- * Close directory stream.
+/*!
+ * \brief Close directory stream.
*/
void
isc_dir_close(isc_dir_t *dir) {
@@ -118,8 +140,8 @@ isc_dir_close(isc_dir_t *dir) {
dir->handle = NULL;
}
-/*
- * Reposition directory stream at start.
+/*!
+ * \brief Reposition directory stream at start.
*/
isc_result_t
isc_dir_reset(isc_dir_t *dir) {
@@ -132,8 +154,8 @@ isc_dir_reset(isc_dir_t *dir) {
isc_result_t
isc_dir_chdir(const char *dirname) {
- /*
- * Change the current directory to 'dirname'.
+ /*!
+ * \brief Change the current directory to 'dirname'.
*/
REQUIRE(dirname != NULL);
@@ -165,8 +187,8 @@ isc_dir_createunique(char *templet) {
REQUIRE(templet != NULL);
- /*
- * mkdtemp is not portable, so this emulates it.
+ /*!
+ * \brief mkdtemp is not portable, so this emulates it.
*/
pid = getpid();
diff --git a/usr.sbin/bind/lib/isc/unix/entropy.c b/usr.sbin/bind/lib/isc/unix/entropy.c
index b39bba0a4aa..57609868a57 100644
--- a/usr.sbin/bind/lib/isc/unix/entropy.c
+++ b/usr.sbin/bind/lib/isc/unix/entropy.c
@@ -15,10 +15,11 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: entropy.c,v 1.60.2.3.8.14 2006/03/02 23:29:17 marka Exp $ */
+/* $ISC: entropy.c,v 1.71.18.7 2006/12/07 04:53:03 marka Exp $ */
-/*
- * This is the system depenedent part of the ISC entropy API.
+/* \file unix/entropy.c
+ * \brief
+ * This is the system dependent part of the ISC entropy API.
*/
#include <config.h>
@@ -41,7 +42,7 @@
#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
@@ -486,8 +487,6 @@ isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {
LOCK(&ent->lock);
- source = NULL;
-
if (stat(fname, &_stat) < 0) {
ret = isc__errno2result(errno);
goto errout;
@@ -588,9 +587,6 @@ isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {
(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/usr.sbin/bind/lib/isc/unix/file.c b/usr.sbin/bind/lib/isc/unix/file.c
index c5610ef52f5..4fc69cd49f6 100644
--- a/usr.sbin/bind/lib/isc/unix/file.c
+++ b/usr.sbin/bind/lib/isc/unix/file.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -48,7 +48,9 @@
* SUCH DAMAGE.
*/
-/* $ISC: file.c,v 1.38.12.8 2004/03/16 05:50:25 marka Exp $ */
+/* $ISC: file.c,v 1.47.18.2 2005/04/29 00:17:07 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -154,7 +156,7 @@ isc_file_settime(const char *file, isc_time_t *time) {
}
#undef TEMPLATE
-#define TEMPLATE "tmp-XXXXXXXXXX" /* 14 characters. */
+#define TEMPLATE "tmp-XXXXXXXXXX" /*%< 14 characters. */
isc_result_t
isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
diff --git a/usr.sbin/bind/lib/isc/unix/fsaccess.c b/usr.sbin/bind/lib/isc/unix/fsaccess.c
index 8b6250c8144..6b565ef22bd 100644
--- a/usr.sbin/bind/lib/isc/unix/fsaccess.c
+++ b/usr.sbin/bind/lib/isc/unix/fsaccess.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: fsaccess.c,v 1.6.206.3 2006/08/25 05:25:50 marka Exp $ */
+/* $ISC: fsaccess.c,v 1.7.18.4 2006/08/25 05:25:51 marka Exp $ */
#include <config.h>
@@ -26,7 +26,8 @@
#include "errno2result.h"
-/*
+/*! \file
+ * \brief
* The OS-independent part of the API is in lib/isc.
*/
#include "../fsaccess.c"
diff --git a/usr.sbin/bind/lib/isc/unix/ifiter_ioctl.c b/usr.sbin/bind/lib/isc/unix/ifiter_ioctl.c
index 0053d015828..51a05218d54 100644
--- a/usr.sbin/bind/lib/isc/unix/ifiter_ioctl.c
+++ b/usr.sbin/bind/lib/isc/unix/ifiter_ioctl.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,9 +15,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: ifiter_ioctl.c,v 1.19.2.5.2.19 2006/02/03 23:51:37 marka Exp $ */
+/* $ISC: ifiter_ioctl.c,v 1.44.18.13 2007/08/31 23:46:25 tbox Exp $ */
-/*
+/*! \file
+ * \brief
* Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
* See netintro(4).
*/
@@ -93,7 +94,7 @@ struct isc_interfaceiter {
#endif
-/*
+/*%
* Size of buffer for SIOCGLIFCONF, in bytes. We assume no sane system
* will have more than a megabyte of interface configuration data.
*/
@@ -904,7 +905,8 @@ internal_next4(isc_interfaceiter_t *iter) {
struct ifreq *ifrp;
#endif
- REQUIRE (iter->pos < (unsigned int) iter->ifc.ifc_len);
+ REQUIRE(iter->ifc.ifc_len == 0 ||
+ iter->pos < (unsigned int) iter->ifc.ifc_len);
#ifdef __linux
if (linux_if_inet6_next(iter) == ISC_R_SUCCESS)
@@ -912,6 +914,10 @@ internal_next4(isc_interfaceiter_t *iter) {
if (!iter->first)
return (ISC_R_SUCCESS);
#endif
+
+ if (iter->ifc.ifc_len == 0)
+ return (ISC_R_NOMORE);
+
#ifdef ISC_PLATFORM_HAVESALEN
ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
diff --git a/usr.sbin/bind/lib/isc/unix/include/isc/stat.h b/usr.sbin/bind/lib/isc/unix/include/isc/stat.h
index aecbb6b0dd9..8efbce0e418 100644
--- a/usr.sbin/bind/lib/isc/unix/include/isc/stat.h
+++ b/usr.sbin/bind/lib/isc/unix/include/isc/stat.h
@@ -1,6 +1,5 @@
/*
* 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
@@ -15,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: stat.h,v 1.1.2.1.4.1 2004/03/06 08:15:05 marka Exp $ */
+/* $ISC: stat.h,v 1.2.18.1 2004/08/19 04:42:54 marka Exp $ */
#ifndef ISC_STAT_H
#define ISC_STAT_H 1
diff --git a/usr.sbin/bind/lib/isc/unix/socket.c b/usr.sbin/bind/lib/isc/unix/socket.c
index 128f39467ea..97822cef4e2 100644
--- a/usr.sbin/bind/lib/isc/unix/socket.c
+++ b/usr.sbin/bind/lib/isc/unix/socket.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,13 +15,19 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket.c,v 1.207.2.19.2.26 2006/05/19 02:53:36 marka Exp $ */
+/* $ISC: socket.c,v 1.237.18.29 2007/08/28 07:20:06 tbox Exp $ */
+
+/*! \file */
#include <config.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/un.h>
+#endif
#include <sys/time.h>
#include <sys/uio.h>
@@ -42,6 +48,7 @@
#include <isc/msgs.h>
#include <isc/mutex.h>
#include <isc/net.h>
+#include <isc/once.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/privsep.h>
@@ -58,7 +65,7 @@
#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.
*/
@@ -66,7 +73,12 @@
#define ISC_SOCKADDR_LEN_T unsigned int
#endif
-/*
+
+#if defined(SO_BSDCOMPAT) && defined(__linux__)
+#include <sys/utsname.h>
+#endif
+
+/*%
* Define what the possible "soft" errors can be. These are non-fatal returns
* of various network related functions, like recv() and so on.
*
@@ -81,7 +93,7 @@
#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
@@ -105,7 +117,7 @@ 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.
@@ -116,7 +128,7 @@ typedef isc_event_t intev_t;
#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?
@@ -127,7 +139,12 @@ typedef isc_event_t intev_t;
#endif
#endif
-/*
+/*%
+ * The size to raise the recieve buffer to (from BIND 8).
+ */
+#define RCVBUFSIZE (32*1024)
+
+/*%
* The number of times a send operation is repeated if the result is EINTR.
*/
#define NRETRIES 10
@@ -241,9 +258,9 @@ static void build_msghdr_recv(isc_socket_t *, isc_socketevent_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_ACCEPT (-3) /*%< Same as _READ */
#define SELECT_POKE_WRITE (-4)
-#define SELECT_POKE_CONNECT (-4) /* Same as _WRITE */
+#define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */
#define SELECT_POKE_CLOSE (-5)
#define SOCK_DEAD(s) ((s)->references == 0)
@@ -873,6 +890,15 @@ set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
}
}
+static void
+destroy_socketevent(isc_event_t *event) {
+ isc_socketevent_t *ev = (isc_socketevent_t *)event;
+
+ INSIST(ISC_LIST_EMPTY(ev->bufferlist));
+
+ (ev->destroy)(event);
+}
+
static isc_socketevent_t *
allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
@@ -894,6 +920,8 @@ allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
ev->n = 0;
ev->offset = 0;
ev->attributes = 0;
+ ev->destroy = ev->ev_destroy;
+ ev->ev_destroy = destroy_socketevent;
return (ev);
}
@@ -1228,7 +1256,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
isc_socket_t **socketp)
{
isc_socket_t *sock;
- isc_result_t ret;
+ isc_result_t result;
ISC_SOCKADDR_LEN_T cmsgbuflen;
sock = isc_mem_get(manager->mctx, sizeof(*sock));
@@ -1236,7 +1264,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
if (sock == NULL)
return (ISC_R_NOMEMORY);
- ret = ISC_R_UNEXPECTED;
+ result = ISC_R_UNEXPECTED;
sock->magic = 0;
sock->references = 0;
@@ -1296,13 +1324,9 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
/*
* initialize the lock
*/
- if (isc_mutex_init(&sock->lock) != ISC_R_SUCCESS) {
+ result = isc_mutex_init(&sock->lock);
+ if (result != 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;
}
@@ -1330,7 +1354,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
sock->sendcmsgbuflen);
isc_mem_put(manager->mctx, sock, sizeof(*sock));
- return (ret);
+ return (result);
}
/*
@@ -1371,7 +1395,45 @@ free_socket(isc_socket_t **socketp) {
*socketp = NULL;
}
+#ifdef SO_BSDCOMPAT
/*
+ * This really should not be necessary to do. Having to workout
+ * which kernel version we are on at run time so that we don't cause
+ * the kernel to issue a warning about us using a deprecated socket option.
+ * Such warnings should *never* be on by default in production kernels.
+ *
+ * We can't do this a build time because executables are moved between
+ * machines and hence kernels.
+ *
+ * We can't just not set SO_BSDCOMAT because some kernels require it.
+ */
+
+static isc_once_t bsdcompat_once = ISC_ONCE_INIT;
+isc_boolean_t bsdcompat = ISC_TRUE;
+
+static void
+clear_bsdcompat(void) {
+#ifdef __linux__
+ struct utsname buf;
+ char *endp;
+ long int major;
+ long int minor;
+
+ uname(&buf); /* Can only fail if buf is bad in Linux. */
+
+ /* Paranoia in parsing can be increased, but we trust uname(). */
+ major = strtol(buf.release, &endp, 10);
+ if (*endp == '.') {
+ minor = strtol(endp+1, &endp, 10);
+ if ((major > 2) || ((major == 2) && (minor >= 4))) {
+ bsdcompat = ISC_FALSE;
+ }
+ }
+#endif /* __linux __ */
+}
+#endif
+
+/*%
* 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
@@ -1382,21 +1444,27 @@ 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;
+ isc_result_t result;
#if defined(USE_CMSG) || defined(SO_BSDCOMPAT)
int on = 1;
#endif
+#if defined(SO_RCVBUF)
+ ISC_SOCKADDR_LEN_T optlen;
+ int size;
+#endif
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
+ int try = 0;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
- ret = allocate_socket(manager, type, &sock);
- if (ret != ISC_R_SUCCESS)
- return (ret);
+ result = allocate_socket(manager, type, &sock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
sock->pf = pf;
+ again:
switch (type) {
case isc_sockettype_udp:
sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
@@ -1404,7 +1472,12 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
case isc_sockettype_tcp:
sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
break;
+ case isc_sockettype_unix:
+ sock->fd = socket(pf, SOCK_STREAM, 0);
+ break;
}
+ if (sock->fd == -1 && errno == EINTR && try++ < 42)
+ goto again;
#ifdef F_DUPFD
/*
@@ -1471,7 +1544,10 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#ifdef SO_BSDCOMPAT
- if (setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
+ RUNTIME_CHECK(isc_once_do(&bsdcompat_once,
+ clear_bsdcompat) == ISC_R_SUCCESS);
+ if (type != isc_sockettype_unix && bsdcompat &&
+ setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
(void *)&on, sizeof(on)) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -1484,9 +1560,10 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif
-#if defined(USE_CMSG)
+#if defined(USE_CMSG) || defined(SO_RCVBUF)
if (type == isc_sockettype_udp) {
+#if defined(USE_CMSG)
#if defined(SO_TIMESTAMP)
if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP,
(void *)&on, sizeof(on)) < 0
@@ -1516,7 +1593,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
#ifdef IPV6_RECVPKTINFO
- /* 2292bis */
+ /* RFC 3542 */
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
(void *)&on, sizeof(on)) < 0)) {
@@ -1531,7 +1608,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
strbuf);
}
#else
- /* 2292 */
+ /* RFC 2292 */
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
(void *)&on, sizeof(on)) < 0)) {
@@ -1547,7 +1624,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif /* IPV6_RECVPKTINFO */
#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */
-#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/
+#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/
/* use minimum MTU */
if (pf == AF_INET6) {
(void)setsockopt(sock->fd, IPPROTO_IPV6,
@@ -1556,9 +1633,30 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif
#endif /* ISC_PLATFORM_HAVEIPV6 */
-
+#endif /* defined(USE_CMSG) */
+
+#if defined(SO_RCVBUF)
+ optlen = sizeof(size);
+ if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
+ (void *)&size, &optlen) >= 0 &&
+ size < RCVBUFSIZE) {
+ size = RCVBUFSIZE;
+ if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
+ (void *)&size, sizeof(size)) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "setsockopt(%d, SO_RCVBUF, %d) %s: %s",
+ sock->fd, size,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ }
+ }
+#endif
}
-#endif /* USE_CMSG */
+#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
sock->references = 1;
*socketp = sock;
@@ -2319,6 +2417,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
#ifdef ISC_PLATFORM_USETHREADS
char strbuf[ISC_STRERRORSIZE];
#endif
+ isc_result_t result;
REQUIRE(managerp != NULL && *managerp == NULL);
@@ -2338,13 +2437,10 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
manager->mctx = NULL;
memset(manager->fds, 0, sizeof(manager->fds));
ISC_LIST_INIT(manager->socklist);
- if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) {
+ result = isc_mutex_init(&manager->lock);
+ if (result != 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);
+ return (result);
}
#ifdef ISC_PLATFORM_USETHREADS
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
@@ -2887,6 +2983,190 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, event, task, address, pktinfo, flags));
}
+void
+isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ int s;
+ struct stat sb;
+ char strbuf[ISC_STRERRORSIZE];
+
+ if (sockaddr->type.sa.sa_family != AF_UNIX)
+ return;
+
+#ifndef S_ISSOCK
+#if defined(S_IFMT) && defined(S_IFSOCK)
+#define S_ISSOCK(mode) ((mode & S_IFMT)==S_IFSOCK)
+#elif defined(_S_IFMT) && defined(S_IFSOCK)
+#define S_ISSOCK(mode) ((mode & _S_IFMT)==S_IFSOCK)
+#endif
+#endif
+
+#ifndef S_ISFIFO
+#if defined(S_IFMT) && defined(S_IFIFO)
+#define S_ISFIFO(mode) ((mode & S_IFMT)==S_IFIFO)
+#elif defined(_S_IFMT) && defined(S_IFIFO)
+#define S_ISFIFO(mode) ((mode & _S_IFMT)==S_IFIFO)
+#endif
+#endif
+
+#if !defined(S_ISFIFO) && !defined(S_ISSOCK)
+#error You need to define S_ISFIFO and S_ISSOCK as appropriate for your platform. See <sys/stat.h>.
+#endif
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(mode) 0
+#endif
+
+#ifndef S_ISSOCK
+#define S_ISSOCK(mode) 0
+#endif
+
+ if (active) {
+ if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: stat(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ return;
+ }
+ if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: %s: not a socket",
+ sockaddr->type.sunix.sun_path);
+ return;
+ }
+ if (unlink(sockaddr->type.sunix.sun_path) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: unlink(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ }
+ return;
+ }
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: socket(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ return;
+ }
+
+ if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) {
+ switch (errno) {
+ case ENOENT: /* We exited cleanly last time */
+ break;
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: stat(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ break;
+ }
+ goto cleanup;
+ }
+
+ if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: %s: not a socket",
+ sockaddr->type.sunix.sun_path);
+ goto cleanup;
+ }
+
+ if (connect(s, (struct sockaddr *)&sockaddr->type.sunix,
+ sizeof(sockaddr->type.sunix)) < 0) {
+ switch (errno) {
+ case ECONNREFUSED:
+ case ECONNRESET:
+ if (unlink(sockaddr->type.sunix.sun_path) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_WARNING,
+ "isc_socket_cleanunix: "
+ "unlink(%s): %s",
+ sockaddr->type.sunix.sun_path,
+ strbuf);
+ }
+ break;
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: connect(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ break;
+ }
+ }
+ cleanup:
+ close(s);
+#else
+ UNUSED(sockaddr);
+ UNUSED(active);
+#endif
+}
+
+isc_result_t
+isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group)
+{
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ isc_result_t result = ISC_R_SUCCESS;
+ char strbuf[ISC_STRERRORSIZE];
+ char path[sizeof(sockaddr->type.sunix.sun_path)];
+#ifdef NEED_SECURE_DIRECTORY
+ char *slash;
+#endif
+
+ REQUIRE(sockaddr->type.sa.sa_family == AF_UNIX);
+ INSIST(strlen(sockaddr->type.sunix.sun_path) < sizeof(path));
+ strcpy(path, sockaddr->type.sunix.sun_path);
+
+#ifdef NEED_SECURE_DIRECTORY
+ slash = strrchr(path, '/');
+ if (slash != NULL) {
+ if (slash != path)
+ *slash = '\0';
+ else
+ strcpy(path, "/");
+ } else
+ strcpy(path, ".");
+#endif
+
+ if (chmod(path, perm) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_permunix: chmod(%s, %d): %s",
+ path, perm, strbuf);
+ result = ISC_R_FAILURE;
+ }
+ if (chown(path, owner, group) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_permunix: chown(%s, %d, %d): %s",
+ path, owner, group,
+ strbuf);
+ result = ISC_R_FAILURE;
+ }
+ return (result);
+#else
+ UNUSED(sockaddr);
+ UNUSED(perm);
+ UNUSED(owner);
+ UNUSED(group);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
isc_result_t
isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
char strbuf[ISC_STRERRORSIZE];
@@ -2903,6 +3183,10 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
/*
* Only set SO_REUSEADDR when we want a specific port.
*/
+#ifdef AF_UNIX
+ if (sock->pf == AF_UNIX)
+ goto bind_socket;
+#endif
if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on)) < 0) {
@@ -2915,6 +3199,9 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
if ((privsep ?
isc_priv_bind(sock->fd, &sockaddr->type.sa, sockaddr->length) :
bind(sock->fd, &sockaddr->type.sa, sockaddr->length)) < 0) {
+#ifdef AF_UNIX
+ bind_socket:
+#endif
UNLOCK(&sock->lock);
switch (errno) {
case EACCES:
@@ -2996,7 +3283,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
REQUIRE(!sock->listener);
REQUIRE(sock->bound);
- REQUIRE(sock->type == isc_sockettype_tcp);
+ REQUIRE(sock->type == isc_sockettype_tcp ||
+ sock->type == isc_sockettype_unix);
if (backlog == 0)
backlog = SOMAXCONN;
@@ -3027,7 +3315,7 @@ isc_socket_accept(isc_socket_t *sock,
isc_socketmgr_t *manager;
isc_task_t *ntask = NULL;
isc_socket_t *nsock;
- isc_result_t ret;
+ isc_result_t result;
isc_boolean_t do_poke = ISC_FALSE;
REQUIRE(VALID_SOCKET(sock));
@@ -3052,11 +3340,11 @@ isc_socket_accept(isc_socket_t *sock,
}
ISC_LINK_INIT(dev, ev_link);
- ret = allocate_socket(manager, sock->type, &nsock);
- if (ret != ISC_R_SUCCESS) {
+ result = allocate_socket(manager, sock->type, &nsock);
+ if (result != ISC_R_SUCCESS) {
isc_event_free(ISC_EVENT_PTR(&dev));
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
/*
@@ -3320,7 +3608,7 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
isc_result_t
isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
- isc_result_t ret;
+ isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addressp != NULL);
@@ -3329,20 +3617,20 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
if (sock->connected) {
*addressp = sock->address;
- ret = ISC_R_SUCCESS;
+ result = ISC_R_SUCCESS;
} else {
- ret = ISC_R_NOTCONNECTED;
+ result = ISC_R_NOTCONNECTED;
}
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
isc_result_t
isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
ISC_SOCKADDR_LEN_T len;
- isc_result_t ret;
+ isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(VALID_SOCKET(sock));
@@ -3351,18 +3639,18 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
LOCK(&sock->lock);
if (!sock->bound) {
- ret = ISC_R_NOTBOUND;
+ result = ISC_R_NOTBOUND;
goto out;
}
- ret = ISC_R_SUCCESS;
+ result = 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;
+ result = ISC_R_UNEXPECTED;
goto out;
}
addressp->length = (unsigned int)len;
@@ -3370,7 +3658,7 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
out:
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
/*
diff --git a/usr.sbin/bind/lib/isc/unix/time.c b/usr.sbin/bind/lib/isc/unix/time.c
index 34cfde620d2..09d9686c251 100644
--- a/usr.sbin/bind/lib/isc/unix/time.c
+++ b/usr.sbin/bind/lib/isc/unix/time.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: time.c,v 1.34.2.6.2.4 2004/03/06 08:15:03 marka Exp $ */
+/* $ISC: time.c,v 1.47.18.2 2005/04/29 00:17:09 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -33,9 +35,9 @@
#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. */
+#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
@@ -48,7 +50,7 @@
#define ISC_FIX_TV_USEC 1
#endif
-/***
+/*%
*** Intervals
***/