diff options
Diffstat (limited to 'lib/isc')
40 files changed, 587 insertions, 188 deletions
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index f513eb97ff9e..3176a267988d 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -13,8 +13,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id$ - srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @@ -53,7 +51,7 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \ OBJS = @ISC_EXTRA_OBJS@ \ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \ - error.@O@ event.@O@ \ + counter.@O@ error.@O@ event.@O@ \ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ @@ -71,8 +69,8 @@ SYMTBLOBJS = backtrace-emptytbl.@O@ # Alphabetically SRCS = @ISC_EXTRA_SRCS@ \ assertions.c backtrace.c base32.c base64.c bitstring.c \ - buffer.c bufferlist.c commandline.c error.c event.c \ - heap.c hex.c hmacmd5.c hmacsha.c \ + buffer.c bufferlist.c commandline.c counter.c \ + error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \ httpd.c inet_aton.c iterated_hash.c \ lex.c lfsr.c lib.c log.c \ md5.c mem.c mutexblock.c \ @@ -134,7 +132,7 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ ${DESTDIR}${libdir} + ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libisc.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libisc.@A@ libisc-nosymtbl.@A@ libisc.la \ diff --git a/lib/isc/api b/lib/isc/api index a1fe77ff05b6..d8990f0ffbea 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 100 +LIBINTERFACE = 103 LIBREVISION = 0 -LIBAGE = 5 +LIBAGE = 8 diff --git a/lib/isc/backtrace.c b/lib/isc/backtrace.c index a5b1a0fdba7e..2a510421474f 100644 --- a/lib/isc/backtrace.c +++ b/lib/isc/backtrace.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -140,7 +140,7 @@ isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { #elif defined(BACKTRACE_X86STACK) #ifdef __x86_64__ static unsigned long -getrbp() { +getrbp(void) { __asm("movq %rbp, %rax\n"); } #endif diff --git a/lib/isc/base32.c b/lib/isc/base32.c index ad0b0da569e1..2ee99b182426 100644 --- a/lib/isc/base32.c +++ b/lib/isc/base32.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base32.c,v 1.6 2009/10/21 01:22:29 each Exp $ */ +/* $Id: base32.c,v 1.6.698.1 2012/02/15 05:00:16 marka Exp $ */ /*! \file */ @@ -54,7 +54,7 @@ static const char base32hex[] = static isc_result_t base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, - isc_buffer_t *target, const char base[]) + isc_buffer_t *target, const char base[], char pad) { char buf[9]; unsigned int loops = 0; @@ -67,8 +67,8 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[0] = base[((source->base[0]>>3)&0x1f)]; /* 5 + */ if (source->length == 1) { buf[1] = base[(source->base[0]<<2)&0x1c]; - buf[2] = buf[3] = buf[4] = '='; - buf[5] = buf[6] = buf[7] = '='; + buf[2] = buf[3] = buf[4] = pad; + buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -77,7 +77,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[2] = base[((source->base[1]>>1)&0x1f)]; /* 5 + */ if (source->length == 2) { buf[3] = base[(source->base[1]<<4)&0x10]; - buf[4] = buf[5] = buf[6] = buf[7] = '='; + buf[4] = buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -85,7 +85,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, ((source->base[2]>>4)&0x0f)]; /* 4 + */ if (source->length == 3) { buf[4] = base[(source->base[2]<<1)&0x1e]; - buf[5] = buf[6] = buf[7] = '='; + buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -94,7 +94,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[5] = base[((source->base[3]>>2)&0x1f)]; /* 5 + */ if (source->length == 4) { buf[6] = base[(source->base[3]<<3)&0x18]; - buf[7] = '='; + buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -121,7 +121,8 @@ isc_result_t isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { - return (base32_totext(source, wordlength, wordbreak, target, base32)); + return (base32_totext(source, wordlength, wordbreak, target, + base32, '=')); } isc_result_t @@ -129,7 +130,15 @@ isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { return (base32_totext(source, wordlength, wordbreak, target, - base32hex)); + base32hex, '=')); +} + +isc_result_t +isc_base32hexnp_totext(isc_region_t *source, int wordlength, + const char *wordbreak, isc_buffer_t *target) +{ + return (base32_totext(source, wordlength, wordbreak, target, + base32hex, 0)); } /*% @@ -143,11 +152,12 @@ typedef struct { int val[8]; const char *base; /*%< Which encoding we are using */ int seen_32; /*%< Number of significant bytes if non zero */ + isc_boolean_t pad; /*%< Expect padding */ } base32_decode_ctx_t; static inline void -base32_decode_init(base32_decode_ctx_t *ctx, int length, - const char base[], isc_buffer_t *target) +base32_decode_init(base32_decode_ctx_t *ctx, int length, const char base[], + isc_boolean_t pad, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = ISC_FALSE; @@ -155,6 +165,7 @@ base32_decode_init(base32_decode_ctx_t *ctx, int length, ctx->length = length; ctx->target = target; ctx->base = base; + ctx->pad = pad; } static inline isc_result_t @@ -167,16 +178,25 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { if ((s = strchr(ctx->base, c)) == NULL) return (ISC_R_BADBASE32); last = (unsigned int)(s - ctx->base); + /* * Handle lower case. */ if (last > 32) last -= 33; + /* * Check that padding is contiguous. */ if (last != 32 && ctx->seen_32 != 0) return (ISC_R_BADBASE32); + + /* + * If padding is not permitted flag padding as a error. + */ + if (last == 32 && !ctx->pad) + return (ISC_R_BADBASE32); + /* * Check that padding starts at the right place and that * bits that should be zero are. @@ -212,6 +232,7 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { ctx->seen_32 = 4; break; } + /* * Zero fill pad values. */ @@ -244,23 +265,33 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { static inline isc_result_t base32_decode_finish(base32_decode_ctx_t *ctx) { + if (ctx->length > 0) return (ISC_R_UNEXPECTEDEND); + /* + * Add missing padding if required. + */ + if (!ctx->pad && ctx->digits != 0) { + ctx->pad = ISC_TRUE; + do { + RETERR(base32_decode_char(ctx, '=')); + } while (ctx->digits != 0); + } if (ctx->digits != 0) return (ISC_R_BADBASE32); return (ISC_R_SUCCESS); } static isc_result_t -base32_tobuffer(isc_lex_t *lexer, const char base[], isc_buffer_t *target, - int length) +base32_tobuffer(isc_lex_t *lexer, const char base[], isc_boolean_t pad, + isc_buffer_t *target, int length) { base32_decode_ctx_t ctx; isc_textregion_t *tr; isc_token_t token; isc_boolean_t eol; - base32_decode_init(&ctx, length, base, target); + base32_decode_init(&ctx, length, base, pad, target); while (!ctx.seen_end && (ctx.length != 0)) { unsigned int i; @@ -285,19 +316,26 @@ base32_tobuffer(isc_lex_t *lexer, const char base[], isc_buffer_t *target, isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { - return (base32_tobuffer(lexer, base32, target, length)); + return (base32_tobuffer(lexer, base32, ISC_TRUE, target, length)); } isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { - return (base32_tobuffer(lexer, base32hex, target, length)); + return (base32_tobuffer(lexer, base32hex, ISC_TRUE, target, length)); +} + +isc_result_t +isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { + return (base32_tobuffer(lexer, base32hex, ISC_FALSE, target, length)); } static isc_result_t -base32_decodestring(const char *cstr, const char base[], isc_buffer_t *target) { +base32_decodestring(const char *cstr, const char base[], isc_boolean_t pad, + isc_buffer_t *target) +{ base32_decode_ctx_t ctx; - base32_decode_init(&ctx, -1, base, target); + base32_decode_init(&ctx, -1, base, pad, target); for (;;) { int c = *cstr++; if (c == '\0') @@ -312,19 +350,26 @@ base32_decodestring(const char *cstr, const char base[], isc_buffer_t *target) { isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target) { - return (base32_decodestring(cstr, base32, target)); + return (base32_decodestring(cstr, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target) { - return (base32_decodestring(cstr, base32hex, target)); + return (base32_decodestring(cstr, base32hex, ISC_TRUE, target)); +} + +isc_result_t +isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target) { + return (base32_decodestring(cstr, base32hex, ISC_FALSE, target)); } static isc_result_t -base32_decoderegion(isc_region_t *source, const char base[], isc_buffer_t *target) { +base32_decoderegion(isc_region_t *source, const char base[], + isc_boolean_t pad, isc_buffer_t *target) +{ base32_decode_ctx_t ctx; - base32_decode_init(&ctx, -1, base, target); + base32_decode_init(&ctx, -1, base, pad, target); while (source->length != 0) { int c = *source->base; RETERR(base32_decode_char(&ctx, c)); @@ -336,12 +381,17 @@ base32_decoderegion(isc_region_t *source, const char base[], isc_buffer_t *targe isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target) { - return (base32_decoderegion(source, base32, target)); + return (base32_decoderegion(source, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target) { - return (base32_decoderegion(source, base32hex, target)); + return (base32_decoderegion(source, base32hex, ISC_TRUE, target)); +} + +isc_result_t +isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target) { + return (base32_decoderegion(source, base32hex, ISC_FALSE, target)); } static isc_result_t diff --git a/lib/isc/counter.c b/lib/isc/counter.c new file mode 100644 index 000000000000..d7d187bbeee4 --- /dev/null +++ b/lib/isc/counter.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <config.h> + +#include <stddef.h> + +#include <isc/counter.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/util.h> + +#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r') +#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC) + +struct isc_counter { + unsigned int magic; + isc_mem_t *mctx; + isc_mutex_t lock; + unsigned int references; + unsigned int limit; + unsigned int used; +}; + +isc_result_t +isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) { + isc_result_t result; + isc_counter_t *counter; + + REQUIRE(counterp != NULL && *counterp == NULL); + + counter = isc_mem_get(mctx, sizeof(*counter)); + if (counter == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&counter->lock); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, counter, sizeof(*counter)); + return (result); + } + + counter->mctx = NULL; + isc_mem_attach(mctx, &counter->mctx); + + counter->references = 1; + counter->limit = limit; + counter->used = 0; + + counter->magic = COUNTER_MAGIC; + *counterp = counter; + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_counter_increment(isc_counter_t *counter) { + isc_result_t result = ISC_R_SUCCESS; + + LOCK(&counter->lock); + counter->used++; + if (counter->limit != 0 && counter->used >= counter->limit) + result = ISC_R_QUOTA; + UNLOCK(&counter->lock); + + return (result); +} + +unsigned int +isc_counter_used(isc_counter_t *counter) { + REQUIRE(VALID_COUNTER(counter)); + + return (counter->used); +} + +void +isc_counter_setlimit(isc_counter_t *counter, int limit) { + REQUIRE(VALID_COUNTER(counter)); + + LOCK(&counter->lock); + counter->limit = limit; + UNLOCK(&counter->lock); +} + +void +isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) { + REQUIRE(VALID_COUNTER(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + + LOCK(&source->lock); + source->references++; + INSIST(source->references > 0); + UNLOCK(&source->lock); + + *targetp = source; +} + +static void +destroy(isc_counter_t *counter) { + counter->magic = 0; + isc_mutex_destroy(&counter->lock); + isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter)); +} + +void +isc_counter_detach(isc_counter_t **counterp) { + isc_counter_t *counter; + isc_boolean_t want_destroy = ISC_FALSE; + + REQUIRE(counterp != NULL && *counterp != NULL); + counter = *counterp; + REQUIRE(VALID_COUNTER(counter)); + + *counterp = NULL; + + LOCK(&counter->lock); + INSIST(counter->references > 0); + counter->references--; + if (counter->references == 0) + want_destroy = ISC_TRUE; + UNLOCK(&counter->lock); + + if (want_destroy) + destroy(counter); +} diff --git a/lib/isc/event.c b/lib/isc/event.c index 8ab75240dca9..895e3d82fe8d 100644 --- a/lib/isc/event.c +++ b/lib/isc/event.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -41,7 +41,26 @@ destroy(isc_event_t *event) { isc_event_t * isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, - isc_taskaction_t action, const void *arg, size_t size) + isc_taskaction_t action, void *arg, size_t size) +{ + isc_event_t *event; + + REQUIRE(size >= sizeof(struct isc_event)); + REQUIRE(action != NULL); + + event = isc_mem_get(mctx, size); + if (event == NULL) + return (NULL); + + ISC_EVENT_INIT(event, size, 0, NULL, type, action, arg, + sender, destroy, mctx); + + return (event); +} + +isc_event_t * +isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, + isc_taskaction_t action, const void *arg, size_t size) { isc_event_t *event; void *deconst_arg; diff --git a/lib/isc/hash.c b/lib/isc/hash.c index f70e7943312d..e12c47183f21 100644 --- a/lib/isc/hash.c +++ b/lib/isc/hash.c @@ -283,7 +283,7 @@ isc_hash_ctxinit(isc_hash_t *hctx) { } void -isc_hash_init() { +isc_hash_init(void) { INSIST(hash != NULL && VALID_HASH(hash)); isc_hash_ctxinit(hash); @@ -348,7 +348,7 @@ isc_hash_ctxdetach(isc_hash_t **hctxp) { } void -isc_hash_destroy() { +isc_hash_destroy(void) { unsigned int refs; INSIST(hash != NULL && VALID_HASH(hash)); diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index 54524beddc2a..572bb3e1046b 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -13,8 +13,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id$ - srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @@ -26,18 +24,20 @@ top_srcdir = @top_srcdir@ # machine generated. The latter are handled specially in the # install target below. # -HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \ - buffer.h bufferlist.h commandline.h entropy.h error.h event.h \ +HEADERS = app.h assertions.h backtrace.h base32.h base64.h \ + bind9.h bitstring.h boolean.h buffer.h bufferlist.h \ + commandline.h counter.h entropy.h error.h event.h \ eventclass.h file.h formatcheck.h fsaccess.h \ hash.h heap.h hex.h hmacmd5.h hmacsha.h httpd.h \ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h \ lang.h lex.h lfsr.h lib.h list.h log.h \ magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \ - namespace.h netaddr.h ondestroy.h os.h parseint.h \ - print.h quota.h radix.h random.h ratelimiter.h \ - refcount.h regex.h region.h resource.h \ - result.h resultclass.h rwlock.h safe.h serial.h sha1.h sha2.h \ - sockaddr.h socket.h stdio.h stdlib.h string.h symtab.h \ + namespace.h netaddr.h netscope.h ondestroy.h os.h parseint.h \ + pool.h portset.h print.h queue.h quota.h \ + radix.h random.h ratelimiter.h refcount.h regex.h \ + region.h resource.h result.h resultclass.h rwlock.h \ + safe.h serial.h sha1.h sha2.h sockaddr.h socket.h \ + stats.h stdio.h stdlib.h string.h symtab.h \ task.h taskpool.h timer.h tm.h types.h util.h version.h \ xml.h diff --git a/lib/isc/include/isc/base32.h b/lib/isc/include/isc/base32.h index 978a8db463ae..347b8ed40a09 100644 --- a/lib/isc/include/isc/base32.h +++ b/lib/isc/include/isc/base32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,8 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base32.h,v 1.3 2008/09/25 04:02:39 tbox Exp $ */ - #ifndef ISC_BASE32_H #define ISC_BASE32_H 1 @@ -27,6 +25,8 @@ * * Base 32 hex preserves the sort order of data when it is encoded / * decoded. + * + * Base 32 hex "np" is base 32 hex but no padding is produced or accepted. */ #include <isc/lang.h> @@ -44,6 +44,9 @@ isc_base32_totext(isc_region_t *source, int wordlength, isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_totext(isc_region_t *source, int wordlength, + const char *wordbreak, isc_buffer_t *target); /*!< * \brief Convert data into base32 encoded text. * @@ -69,8 +72,11 @@ isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target); isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target); /*!< - * \brief Decode a null-terminated base32 string. + * \brief Decode a null-terminated string in base32, base32hex, or + * base32hex non-padded. * * Requires: *\li 'cstr' is non-null. @@ -91,8 +97,11 @@ isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); +isc_result_t +isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); /*!< - * \brief Convert base32 encoded text from a lexer context into data. + * \brief Convert text encoded in base32, base32hex, or base32hex + * non-padded from a lexer context into data. * * Requires: *\li 'lex' is a valid lexer context @@ -110,8 +119,11 @@ isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target); isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target); /*!< - * \brief Decode a packed (no white space permitted) base32 region. + * \brief Decode a packed (no white space permitted) region in + * base32, base32hex or base32hex non-padded. * * Requires: *\li 'source' is a valid region. diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h index 5aff01c24790..f9c0775790e7 100644 --- a/lib/isc/include/isc/buffer.h +++ b/lib/isc/include/isc/buffer.h @@ -664,12 +664,12 @@ ISC_LANG_ENDDECLS /*! \note * XXXDCL Something more could be done with initializing buffers that - * point to const data. For example, a new function, isc_buffer_initconst, - * could be used, and a new boolean flag in the buffer structure could - * indicate whether the buffer was initialized with that function. - * (isc_bufer_init itself would be reprototyped to *not* have its "base" - * parameter be const.) Then if the boolean were true, the isc_buffer_put* - * functions could assert a contractual requirement for a non-const buffer. + * point to const data. For example, isc_buffer_constinit() could + * set a new boolean flag in the buffer structure indicating whether + * the buffer was initialized with that function. * Then if the + * boolean were true, the isc_buffer_put* functions could assert a + * contractual requirement for a non-const buffer. + * * One drawback is that the isc_buffer_* functions (macros) that return * pointers would still need to return non-const pointers to avoid compiler * warnings, so it would be up to code that uses them to have to deal diff --git a/lib/isc/include/isc/counter.h b/lib/isc/include/isc/counter.h new file mode 100644 index 000000000000..e7ebd2533254 --- /dev/null +++ b/lib/isc/include/isc/counter.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef ISC_COUNTER_H +#define ISC_COUNTER_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file isc/counter.h + * + * \brief The isc_counter_t object is a simplified version of the + * isc_quota_t object; it tracks the consumption of limited + * resources, returning an error condition when the quota is + * exceeded. However, unlike isc_quota_t, attaching and detaching + * from a counter object does not increment or decrement the counter. + */ + +/*** + *** Imports. + ***/ + +#include <isc/lang.h> +#include <isc/mutex.h> +#include <isc/types.h> + +/***** + ***** Types. + *****/ + +ISC_LANG_BEGINDECLS + +isc_result_t +isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp); +/*%< + * Allocate and initialize a counter object. + */ + +isc_result_t +isc_counter_increment(isc_counter_t *counter); +/*%< + * Increment the counter. + * + * If the counter limit is nonzero and has been reached, then + * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is + * incremented regardless of return value.) + */ + +unsigned int +isc_counter_used(isc_counter_t *counter); +/*%< + * Return the current counter value. + */ + +void +isc_counter_setlimit(isc_counter_t *counter, int limit); +/*%< + * Set the counter limit. + */ + +void +isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp); +/*%< + * Attach to a counter object, increasing its reference counter. + */ + +void +isc_counter_detach(isc_counter_t **counterp); +/*%< + * Detach (and destroy if reference counter has dropped to zero) + * a counter object. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_COUNTER_H */ diff --git a/lib/isc/include/isc/event.h b/lib/isc/include/isc/event.h index 68fabb2fcc3c..38206f53b9c9 100644 --- a/lib/isc/include/isc/event.h +++ b/lib/isc/include/isc/event.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -90,9 +90,12 @@ ISC_LANG_BEGINDECLS isc_event_t * isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, - isc_taskaction_t action, const void *arg, size_t size); + isc_taskaction_t action, void *arg, size_t size); +isc_event_t * +isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, + isc_taskaction_t action, const void *arg, size_t size); /*%< - * Allocate an event structure. + * Allocate an event structure. * * Allocate and initialize in a structure with initial elements * defined by: @@ -103,7 +106,7 @@ isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, * ... * }; * \endcode - * + * * Requires: *\li 'size' >= sizeof(struct isc_event) *\li 'action' to be non NULL diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h index a974bbd7219b..7137410b613d 100644 --- a/lib/isc/include/isc/file.h +++ b/lib/isc/include/isc/file.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -62,7 +62,7 @@ isc_file_getmodtime(const char *file, isc_time_t *time); *\li #ISC_R_NOPERM * The file's metainformation could not be retrieved because * permission was denied to some part of the file's path. - *\li #ISC_R_EIO + *\li #ISC_R_IOERROR * Hardware error interacting with the filesystem. *\li #ISC_R_UNEXPECTED * Something totally unexpected happened. @@ -213,7 +213,7 @@ isc_file_isplainfile(const char *name); * permitted in addition to ISC_R_SUCCESS. This is done since * the next call in logconf.c is to isc_stdio_open(), which * will create the file if it can. - *\li #other ISC_R_* errors translated from errno + *\li other ISC_R_* errors translated from errno * These occur when stat returns -1 and an errno. */ @@ -229,7 +229,7 @@ isc_file_isdirectory(const char *name); * File is not a directory. *\li #ISC_R_FILENOTFOUND * File does not exist. - *\li #other ISC_R_* errors translated from errno + *\li other ISC_R_* errors translated from errno * These occur when stat returns -1 and an errno. */ diff --git a/lib/isc/include/isc/iterated_hash.h b/lib/isc/include/isc/iterated_hash.h index a8173f0ab22f..5c0512c328c1 100644 --- a/lib/isc/include/isc/iterated_hash.h +++ b/lib/isc/include/isc/iterated_hash.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,7 +23,7 @@ #include <isc/sha1.h> /* - * The maximal hash length that can be encoded it a name + * The maximal hash length that can be encoded in a name * using base32hex. floor(255/8)*5 */ #define NSEC3_MAX_HASH_LENGTH 155 diff --git a/lib/isc/include/isc/print.h b/lib/isc/include/isc/print.h index cd1e38eaf6fb..2b9169001fec 100644 --- a/lib/isc/include/isc/print.h +++ b/lib/isc/include/isc/print.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -38,10 +38,13 @@ */ #if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDVSNPRINTF +#undef snprintf +#undef vsnprintf #endif #if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDSPRINTF +#undef sprintf #endif /*** diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h index dcd457b3d1b0..ed1bc63e7364 100644 --- a/lib/isc/include/isc/result.h +++ b/lib/isc/include/isc/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -88,9 +88,10 @@ #define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */ #define ISC_R_BADBASE32 60 /*%< bad base32 encoding */ #define ISC_R_UNSET 61 /*%< unset */ +#define ISC_R_MULTIPLE 62 /*%< multiple */ /*% Not a result code: the number of results. */ -#define ISC_R_NRESULTS 62 +#define ISC_R_NRESULTS 63 ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 2ccd41a2d5c3..97e2f7605b9c 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -281,7 +281,7 @@ typedef struct isc_socketmethods { unsigned int options); isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, - const void *arg, isc_sockaddr_t *address, + void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t (*sendto2)(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, @@ -290,10 +290,10 @@ typedef struct isc_socketmethods { unsigned int flags); isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, - const void *arg); + void *arg); isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg); + isc_taskaction_t action, void *arg); isc_result_t (*recv2)(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags); @@ -675,7 +675,7 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog); isc_result_t isc_socket_accept(isc_socket_t *sock, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Queue accept event. When a new connection is received, the task will * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen @@ -699,7 +699,7 @@ isc_socket_accept(isc_socket_t *sock, 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); + void *arg); /*%< * Connect 'socket' to peer with address *saddr. When the connection * succeeds, or when an error occurs, a CONNECT event with action 'action' @@ -766,11 +766,11 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp); isc_result_t isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, @@ -853,21 +853,21 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, /*@{*/ isc_result_t isc_socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags); isc_result_t diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index 7abf2ef2be60..a42a7e6b2a51 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -128,7 +128,7 @@ typedef struct isc_taskmethods { unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events); isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action, - const void *arg); + void *arg); void (*shutdown)(isc_task_t *task); void (*setname)(isc_task_t *task, const char *name, void *tag); unsigned int (*purgeevents)(isc_task_t *task, void *sender, @@ -441,7 +441,7 @@ isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, isc_result_t isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, - const void *arg); + void *arg); /*%< * Send a shutdown event with action 'action' and argument 'arg' when * 'task' is shutdown. diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index 0598f79b58e0..d72a86a379f9 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -112,7 +112,7 @@ typedef struct { const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, - const void *arg, + void *arg, isc_timer_t **timerp); } isc_timermgrmethods_t; @@ -173,7 +173,7 @@ isc_timer_create(isc_timermgr_t *manager, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, - const void *arg, + void *arg, isc_timer_t **timerp); /*%< * Create a new 'type' timer managed by 'manager'. The timers parameters diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h index a1edadd10db7..6f6e64ea1e67 100644 --- a/lib/isc/include/isc/types.h +++ b/lib/isc/include/isc/types.h @@ -50,6 +50,7 @@ typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ typedef struct isc_constregion isc_constregion_t; /*%< Const region */ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */ +typedef struct isc_counter isc_counter_t; /*%< Counter */ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */ typedef struct isc_event isc_event_t; /*%< Event */ diff --git a/lib/isc/lib.c b/lib/isc/lib.c index a50542551df3..0ab72420c2b9 100644 --- a/lib/isc/lib.c +++ b/lib/isc/lib.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -96,7 +96,7 @@ do_register(void) { } void -isc_lib_register() { +isc_lib_register(void) { RUNTIME_CHECK(isc_once_do(®ister_once, do_register) == ISC_R_SUCCESS); } diff --git a/lib/isc/log.c b/lib/isc/log.c index 2cf584b44a6d..986ed61352e6 100644 --- a/lib/isc/log.c +++ b/lib/isc/log.c @@ -1633,6 +1633,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, TIME_NOW(&new->time); + ISC_LINK_INIT(new, link); ISC_LIST_APPEND(lctx->messages, new, link); } diff --git a/lib/isc/mem.c b/lib/isc/mem.c index f45a077e1e94..043a579077fa 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -1778,7 +1778,6 @@ isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg, ctx->water_arg = water_arg; ctx->hi_water = hiwater; ctx->lo_water = lowater; - ctx->hi_called = ISC_FALSE; } MCTXUNLOCK(ctx, &ctx->lock); @@ -2258,7 +2257,7 @@ isc__mempool_getfillcount(isc_mempool_t *mpctx0) { #ifdef USE_MEMIMPREGISTER isc_result_t -isc__mem_register() { +isc__mem_register(void) { return (isc_mem_register(isc__mem_create2)); } #endif diff --git a/lib/isc/netaddr.c b/lib/isc/netaddr.c index 0940df1713e5..dcbfba42eae8 100644 --- a/lib/isc/netaddr.c +++ b/lib/isc/netaddr.c @@ -235,11 +235,12 @@ isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) { nbytes = prefixlen / 8; nbits = prefixlen % 8; if (nbits != 0) { + INSIST(nbytes < ipbytes); if ((p[nbytes] & (0xff>>nbits)) != 0U) return (ISC_R_FAILURE); nbytes++; } - if (memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0) + if (nbytes < ipbytes && memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); } diff --git a/lib/isc/print.c b/lib/isc/print.c index a5e5ba6699d6..06719e83a547 100644 --- a/lib/isc/print.c +++ b/lib/isc/print.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -117,7 +117,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { dot = neg = space = plus = left = zero = alt = h = l = q = 0; width = precision = 0; head = ""; - length = pad = zeropad = 0; + pad = zeropad = 0; do { if (*format == '#') { @@ -260,7 +260,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (hi != 0) sprintf(buf, "%lu", hi); else - buf[0] = '\n'; + buf[0] = '\0'; sprintf(buf + strlen(buf), "%lu", mid); sprintf(buf + strlen(buf), "%lu", lo); } @@ -317,7 +317,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (hi != 0) sprintf(buf, "%lu", hi); else - buf[0] = '\n'; + buf[0] = '\0'; sprintf(buf + strlen(buf), "%lu", mid); sprintf(buf + strlen(buf), "%lu", lo); } diff --git a/lib/isc/radix.c b/lib/isc/radix.c index 82090d1fde91..df26615fa9bf 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -634,12 +634,12 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { if (node->r == NULL && node->l == NULL) { parent = node->parent; _deref_prefix(node->prefix); - isc_mem_put(radix->mctx, node, sizeof(*node)); - radix->num_active_node--; if (parent == NULL) { INSIST(radix->head == node); radix->head = NULL; + isc_mem_put(radix->mctx, node, sizeof(*node)); + radix->num_active_node--; return; } @@ -652,11 +652,13 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { child = parent->r; } + isc_mem_put(radix->mctx, node, sizeof(*node)); + radix->num_active_node--; + if (parent->prefix) return; /* We need to remove parent too. */ - if (parent->parent == NULL) { INSIST(radix->head == parent); radix->head = child; @@ -666,6 +668,7 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { INSIST(parent->parent->l == parent); parent->parent->l = child; } + child->parent = parent->parent; isc_mem_put(radix->mctx, parent, sizeof(*parent)); radix->num_active_node--; @@ -678,19 +681,23 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { INSIST(node->l != NULL); child = node->l; } + parent = node->parent; child->parent = parent; _deref_prefix(node->prefix); - isc_mem_put(radix->mctx, node, sizeof(*node)); - radix->num_active_node--; if (parent == NULL) { INSIST(radix->head == node); radix->head = child; + isc_mem_put(radix->mctx, node, sizeof(*node)); + radix->num_active_node--; return; } + isc_mem_put(radix->mctx, node, sizeof(*node)); + radix->num_active_node--; + if (parent->r == node) { parent->r = child; } else { diff --git a/lib/isc/random.c b/lib/isc/random.c index 4c48e60fd77d..d18204d6e337 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -67,8 +67,16 @@ isc_random_seed(isc_uint32_t seed) #ifndef HAVE_ARC4RANDOM srand(seed); -#else +#elif defined(HAVE_ARC4RANDOM_ADDRANDOM) arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); +#else + /* + * If arcrandom() is available and no corresponding seeding + * function arc4random_addrandom() is available, no seeding is + * done on such platforms (e.g., OpenBSD 5.5). This is because + * the OS itself is supposed to seed the RNG and it is assumed + * that no explicit seeding is required. + */ #endif } diff --git a/lib/isc/regex.c b/lib/isc/regex.c index 279bcdc437fb..2ee13653bdde 100644 --- a/lib/isc/regex.c +++ b/lib/isc/regex.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -220,7 +220,7 @@ isc_regex_validate(const char *c) { ++c; switch (*c) { case '.': /* collating element */ - if (range) --range; + if (range != 0) --range; ++c; state = parse_ce; seen_ce = ISC_FALSE; @@ -255,11 +255,11 @@ isc_regex_validate(const char *c) { default: inside: seen_char = ISC_TRUE; - if (range == 2 && *c < range_start) + if (range == 2 && (*c & 0xff) < range_start) FAIL("out of order range"); if (range != 0) --range; - range_start = *c; + range_start = *c & 0xff; ++c; break; }; diff --git a/lib/isc/result.c b/lib/isc/result.c index a9405fddf055..2bd2fb4218ed 100644 --- a/lib/isc/result.c +++ b/lib/isc/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -103,6 +103,7 @@ static const char *text[ISC_R_NRESULTS] = { "invalid address format", /*%< 59 */ "bad base32 encoding", /*%< 60 */ "unset", /*%< 61 */ + "multiple", /*%< 62 */ }; #define ISC_RESULT_RESULTSET 2 diff --git a/lib/isc/socket_api.c b/lib/isc/socket_api.c index 1fba3e0ac19a..dca6c34fc37a 100644 --- a/lib/isc/socket_api.c +++ b/lib/isc/socket_api.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -131,7 +131,7 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, isc_result_t isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, - isc_taskaction_t action, const void *arg, + isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); @@ -154,7 +154,7 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_result_t isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, - isc_taskaction_t action, const void *arg) + isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); @@ -163,7 +163,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_result_t isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, - isc_task_t *task, isc_taskaction_t action, const void *arg) + isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); diff --git a/lib/isc/task.c b/lib/isc/task.c index b743271339f9..02d6e2abaf60 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -208,7 +208,7 @@ isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events); ISC_TASKFUNC_SCOPE isc_result_t isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action, - const void *arg); + void *arg); ISC_TASKFUNC_SCOPE void isc__task_shutdown(isc_task_t *task0); ISC_TASKFUNC_SCOPE void @@ -796,7 +796,7 @@ isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, ISC_TASKFUNC_SCOPE isc_result_t isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action, - const void *arg) + void *arg) { isc__task_t *task = (isc__task_t *)task0; isc_boolean_t disallowed = ISC_FALSE; @@ -1751,7 +1751,7 @@ isc__task_privilege(isc_task_t *task0) { #ifdef USE_SOCKETIMPREGISTER isc_result_t -isc__task_register() { +isc__task_register(void) { return (isc_task_register(isc__taskmgr_create)); } #endif diff --git a/lib/isc/task_api.c b/lib/isc/task_api.c index f49ab321b2d3..44aaa1761151 100644 --- a/lib/isc/task_api.c +++ b/lib/isc/task_api.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -172,7 +172,7 @@ isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, } isc_result_t -isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg) +isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_TASK_VALID(task)); @@ -204,7 +204,7 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) void isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); - return (mgr->methods->setexcltask(mgr, task)); + mgr->methods->setexcltask(mgr, task); } isc_result_t diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 23fcbbef6498..f48259dddbcc 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -131,7 +131,7 @@ struct isc__timermgr { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp); ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer, isc_timertype_t type, @@ -393,7 +393,7 @@ destroy(isc__timer_t *timer) { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp) { isc__timermgr_t *manager = (isc__timermgr_t *)manager0; @@ -1066,7 +1066,7 @@ isc__timermgr_dispatch(isc_timermgr_t *manager0) { #ifdef USE_TIMERIMPREGISTER isc_result_t -isc__timer_register() { +isc__timer_register(void) { return (isc_timer_register(isc__timermgr_create)); } #endif diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c index 39b33e3c7444..f6091b47c41d 100644 --- a/lib/isc/timer_api.c +++ b/lib/isc/timer_api.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -97,7 +97,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp) { REQUIRE(ISCAPI_TIMERMGR_VALID(manager)); diff --git a/lib/isc/tm.c b/lib/isc/tm.c index 08af2bcc95dd..842a2f7fb4ab 100644 --- a/lib/isc/tm.c +++ b/lib/isc/tm.c @@ -147,6 +147,12 @@ isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm) { size_t len = 0; int alt_format, i, split_year = 0; + REQUIRE(buf != NULL); + REQUIRE(fmt != NULL); + REQUIRE(tm != NULL); + + memset(tm, 0, sizeof(struct tm)); + bp = buf; while ((c = *fmt) != '\0') { diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c index d97d7c6bbcc9..6c53559fb032 100644 --- a/lib/isc/unix/app.c +++ b/lib/isc/unix/app.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -379,7 +379,7 @@ isc__app_start(void) { } presult = sigprocmask(SIG_UNBLOCK, &sset, NULL); if (presult != 0) { - isc__strerror(presult, strbuf, sizeof(strbuf)); + isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() sigprocmask: %s", strbuf); return (ISC_R_UNEXPECTED); @@ -718,7 +718,7 @@ isc__app_ctxrun(isc_appctx_t *ctx0) { } ISC_APPFUNC_SCOPE isc_result_t -isc__app_run() { +isc__app_run(void) { return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx)); } @@ -773,7 +773,7 @@ isc__app_ctxshutdown(isc_appctx_t *ctx0) { } ISC_APPFUNC_SCOPE isc_result_t -isc__app_shutdown() { +isc__app_shutdown(void) { return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); } @@ -955,7 +955,7 @@ isc__appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) { #ifdef USE_APPIMPREGISTER isc_result_t -isc__app_register() { +isc__app_register(void) { return (isc_app_register(isc__appctx_create)); } #endif diff --git a/lib/isc/unix/include/isc/Makefile.in b/lib/isc/unix/include/isc/Makefile.in index 6acad0067a77..9cd96d71b750 100644 --- a/lib/isc/unix/include/isc/Makefile.in +++ b/lib/isc/unix/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -21,8 +21,8 @@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ -HEADERS = dir.h int.h net.h netdb.h offset.h stat.h stdtime.h \ - syslog.h time.h +HEADERS = dir.h int.h keyboard.h net.h netdb.h offset.h stat.h \ + stdtime.h strerror.h syslog.h time.h SUBDIRS = TARGETS = diff --git a/lib/isc/unix/include/isc/net.h b/lib/isc/unix/include/isc/net.h index efa67c223bef..c9ceaf774e89 100644 --- a/lib/isc/unix/include/isc/net.h +++ b/lib/isc/unix/include/isc/net.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/isc/unix/include/isc/stat.h b/lib/isc/unix/include/isc/stat.h index b7a798649225..4d59f922c15c 100644 --- a/lib/isc/unix/include/isc/stat.h +++ b/lib/isc/unix/include/isc/stat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,7 +24,7 @@ *****/ /* - * Portable netdb.h support. + * Portable <sys/stat.h> support. * * This module is responsible for defining S_IS??? macros. * diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index d1ac96f53514..2a004234d429 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -34,6 +34,9 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> /* uintptr_t */ +#endif #include <isc/buffer.h> #include <isc/bufferlist.h> @@ -49,6 +52,7 @@ #include <isc/platform.h> #include <isc/print.h> #include <isc/region.h> +#include <isc/resource.h> #include <isc/socket.h> #include <isc/stats.h> #include <isc/strerror.h> @@ -374,6 +378,8 @@ struct isc__socketmgr { #endif /* USE_EPOLL */ #ifdef USE_DEVPOLL int devpoll_fd; + isc_resourcevalue_t open_max; + unsigned int calls; int nevents; struct pollfd *events; #endif /* USE_DEVPOLL */ @@ -481,32 +487,32 @@ isc__socketmgr_destroy(isc_socketmgr_t **managerp); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg); + isc_taskaction_t action, void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg); + isc_taskaction_t action, void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendto(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags); ISC_SOCKETFUNC_SCOPE isc_result_t @@ -528,11 +534,11 @@ ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_listen(isc_socket_t *sock, unsigned int backlog); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_accept(isc_socket_t *sock, - isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_task_t *task, isc_taskaction_t action, void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, - const void *arg); + void *arg); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp); ISC_SOCKETFUNC_SCOPE isc_result_t @@ -1091,8 +1097,6 @@ select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) { "read() failed " "during watcher poke: %s"), strbuf); - - return; } INSIST(cc == sizeof(buf)); @@ -1593,7 +1597,7 @@ destroy_socketevent(isc_event_t *event) { static isc_socketevent_t * allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype, - isc_taskaction_t action, const void *arg) + isc_taskaction_t action, void *arg) { isc_socketevent_t *ev; @@ -1951,7 +1955,7 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { * references exist. */ static void -closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) { +socketclose(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) { isc_sockettype_t type = sock->type; int lockid = FDLOCK_ID(fd); @@ -2031,7 +2035,7 @@ destroy(isc__socket_t **sockp) { if (sock->fd >= 0) { fd = sock->fd; sock->fd = -1; - closesocket(manager, sock, fd); + socketclose(manager, sock, fd); } LOCK(&manager->lock); @@ -2903,7 +2907,7 @@ isc__socket_close(isc_socket_t *sock0) { UNLOCK(&sock->lock); - closesocket(manager, sock, fd); + socketclose(manager, sock, fd); return (ISC_R_SUCCESS); } @@ -3822,8 +3826,10 @@ watcher(void *uap) { #elif defined (USE_EPOLL) const char *fnname = "epoll_wait()"; #elif defined(USE_DEVPOLL) + isc_result_t result; const char *fnname = "ioctl(DP_POLL)"; struct dvpoll dvp; + int pass; #elif defined (USE_SELECT) const char *fnname = "select()"; int maxfd; @@ -3850,17 +3856,45 @@ watcher(void *uap) { cc = epoll_wait(manager->epoll_fd, manager->events, manager->nevents, -1); #elif defined(USE_DEVPOLL) - dvp.dp_fds = manager->events; - dvp.dp_nfds = manager->nevents; + /* + * Re-probe every thousand calls. + */ + if (manager->calls++ > 1000U) { + result = isc_resource_getcurlimit( + isc_resource_openfiles, + &manager->open_max); + if (result != ISC_R_SUCCESS) + manager->open_max = 64; + manager->calls = 0; + } + for (pass = 0; pass < 2; pass++) { + dvp.dp_fds = manager->events; + dvp.dp_nfds = manager->nevents; + if (dvp.dp_nfds >= manager->open_max) + dvp.dp_nfds = manager->open_max - 1; #ifndef ISC_SOCKET_USE_POLLWATCH - dvp.dp_timeout = -1; -#else - if (pollstate == poll_idle) dvp.dp_timeout = -1; - else - dvp.dp_timeout = ISC_SOCKET_POLLWATCH_TIMEOUT; +#else + if (pollstate == poll_idle) + dvp.dp_timeout = -1; + else + dvp.dp_timeout = + ISC_SOCKET_POLLWATCH_TIMEOUT; #endif /* ISC_SOCKET_USE_POLLWATCH */ - cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp); + cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp); + if (cc == -1 && errno == EINVAL) { + /* + * {OPEN_MAX} may have dropped. Look + * up the current value and try again. + */ + result = isc_resource_getcurlimit( + isc_resource_openfiles, + &manager->open_max); + if (result != ISC_R_SUCCESS) + manager->open_max = 64; + } else + break; + } #elif defined(USE_SELECT) LOCK(&manager->lock); memmove(manager->read_fds_copy, manager->read_fds, @@ -4022,11 +4056,12 @@ setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) { } #endif /* USE_WATCHER_THREAD */ #elif defined(USE_DEVPOLL) - /* - * XXXJT: /dev/poll seems to reject large numbers of events, - * so we should be careful about redefining ISC_SOCKET_MAXEVENTS. - */ manager->nevents = ISC_SOCKET_MAXEVENTS; + result = isc_resource_getcurlimit(isc_resource_openfiles, + &manager->open_max); + if (result != ISC_R_SUCCESS) + manager->open_max = 64; + manager->calls = 0; manager->events = isc_mem_get(mctx, sizeof(struct pollfd) * manager->nevents); if (manager->events == NULL) @@ -4557,7 +4592,7 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg) + isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; @@ -4611,7 +4646,7 @@ isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_recv(isc_socket_t *sock0, isc_region_t *region, unsigned int minimum, isc_task_t *task, - isc_taskaction_t action, const void *arg) + isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; @@ -4756,7 +4791,7 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_send(isc_socket_t *sock, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg) + isc_task_t *task, isc_taskaction_t action, void *arg) { /* * REQUIRE() checking is performed in isc_socket_sendto(). @@ -4767,7 +4802,7 @@ isc__socket_send(isc_socket_t *sock, isc_region_t *region, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { isc__socket_t *sock = (isc__socket_t *)sock0; @@ -4795,7 +4830,7 @@ isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg) + isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_sendtov2(sock, buflist, task, action, arg, NULL, NULL, 0)); @@ -4803,7 +4838,7 @@ isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { return (isc__socket_sendtov2(sock, buflist, task, action, arg, address, @@ -4812,7 +4847,7 @@ isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_sendtov2(isc_socket_t *sock0, isc_bufferlist_t *buflist, - isc_task_t *task, isc_taskaction_t action, const void *arg, + isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { @@ -5211,7 +5246,7 @@ isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) { */ ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_accept(isc_socket_t *sock0, - isc_task_t *task, isc_taskaction_t action, const void *arg) + isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_newconnev_t *dev; @@ -5286,7 +5321,7 @@ isc__socket_accept(isc_socket_t *sock0, ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr, - isc_task_t *task, isc_taskaction_t action, const void *arg) + isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_connev_t *dev; @@ -5796,8 +5831,6 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp, isc_socketwait_t **swaitp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; - - int n; #ifdef USE_KQUEUE struct timespec ts, *tsp; @@ -5806,6 +5839,8 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp, int timeout; #endif #ifdef USE_DEVPOLL + isc_result_t result; + int pass; struct dvpoll dvp; #endif @@ -5839,15 +5874,41 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp, manager->nevents, timeout); n = swait_private.nevents; #elif defined(USE_DEVPOLL) - dvp.dp_fds = manager->events; - dvp.dp_nfds = manager->nevents; - if (tvp != NULL) { - dvp.dp_timeout = tvp->tv_sec * 1000 + - (tvp->tv_usec + 999) / 1000; - } else - dvp.dp_timeout = -1; - swait_private.nevents = ioctl(manager->devpoll_fd, DP_POLL, &dvp); - n = swait_private.nevents; + /* + * Re-probe every thousand calls. + */ + if (manager->calls++ > 1000U) { + result = isc_resource_getcurlimit(isc_resource_openfiles, + &manager->open_max); + if (result != ISC_R_SUCCESS) + manager->open_max = 64; + manager->calls = 0; + } + for (pass = 0; pass < 2; pass++) { + dvp.dp_fds = manager->events; + dvp.dp_nfds = manager->nevents; + if (dvp.dp_nfds >= manager->open_max) + dvp.dp_nfds = manager->open_max - 1; + if (tvp != NULL) { + dvp.dp_timeout = tvp->tv_sec * 1000 + + (tvp->tv_usec + 999) / 1000; + } else + dvp.dp_timeout = -1; + n = ioctl(manager->devpoll_fd, DP_POLL, &dvp); + if (n == -1 && errno == EINVAL) { + /* + * {OPEN_MAX} may have dropped. Look + * up the current value and try again. + */ + result = isc_resource_getcurlimit( + isc_resource_openfiles, + &manager->open_max); + if (result != ISC_R_SUCCESS) + manager->open_max = 64; + } else + break; + } + swait_private.nevents = n; #elif defined(USE_SELECT) memmove(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize); memmove(manager->write_fds_copy, manager->write_fds, @@ -5923,7 +5984,7 @@ isc__socket_gettag(isc_socket_t *socket0) { #ifdef USE_SOCKETIMPREGISTER isc_result_t -isc__socket_register() { +isc__socket_register(void) { return (isc_socket_register(isc__socketmgr_create)); } #endif |
