diff options
Diffstat (limited to 'lib/isc')
35 files changed, 845 insertions, 321 deletions
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index ff500ffd3fb2f..2fa5633585155 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -60,7 +60,8 @@ OBJS = @ISC_EXTRA_OBJS@ \ md5.@O@ mem.@O@ mutexblock.@O@ \ netaddr.@O@ netscope.@O@ ondestroy.@O@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ - ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \ + ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ + rwlock.@O@ \ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \ timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS} @@ -76,7 +77,7 @@ SRCS = @ISC_EXTRA_SRCS@ \ md5.c mem.c mutexblock.c \ netaddr.c netscope.c ondestroy.c \ parseint.c portset.c quota.c radix.c random.c \ - ratelimiter.c refcount.c region.c result.c rwlock.c \ + ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \ symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c diff --git a/lib/isc/api b/lib/isc/api index 18de29ceb9d26..c7d281344cf13 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 -LIBINTERFACE = 85 -LIBREVISION = 0 -LIBAGE = 1 +# 9.9-sub: 130-139 +LIBINTERFACE = 87 +LIBREVISION = 1 +LIBAGE = 3 diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c index 1b59e650acdec..e37af15968a9b 100644 --- a/lib/isc/buffer.c +++ b/lib/isc/buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -28,7 +28,7 @@ #include <isc/util.h> void -isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) { +isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) { /* * Make 'b' refer to the 'length'-byte region starting at 'base'. * XXXDCL see the comment in buffer.h about base being const. diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index b8acdb5dbe0f2..8afcfa73cb802 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2009, 2012, 2013 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 @@ -36,7 +36,7 @@ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.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 region.h resource.h \ + refcount.h regex.h region.h resource.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 \ diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h index ae7e4c3dfc346..72b856056a8aa 100644 --- a/lib/isc/include/isc/buffer.h +++ b/lib/isc/include/isc/buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -222,7 +222,7 @@ isc_buffer_free(isc_buffer_t **dynbuffer); */ void -isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length); +isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length); /*!< * \brief Make 'b' refer to the 'length'-byte region starting at base. * @@ -681,12 +681,7 @@ ISC_LANG_ENDDECLS */ #define ISC__BUFFER_INIT(_b, _base, _length) \ do { \ - union { \ - const void * konst; \ - void * var; \ - } _u; \ - _u.konst = (_base); \ - (_b)->base = _u.var; \ + (_b)->base = _base; \ (_b)->length = (_length); \ (_b)->used = 0; \ (_b)->current = 0; \ @@ -896,6 +891,13 @@ ISC_LANG_ENDDECLS #define isc_buffer_putuint32 isc__buffer_putuint32 #endif +#define isc_buffer_constinit(_b, _d, _l) \ + do { \ + union { void *_var; const void *_const; } _deconst; \ + _deconst._const = (_d); \ + isc_buffer_init((_b), _deconst._var, (_l)); \ + } while (0) + /* * No inline method for this one (yet). */ diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h index 38f78b7403e83..92ea96eceb7e1 100644 --- a/lib/isc/include/isc/file.h +++ b/lib/isc/include/isc/file.h @@ -115,8 +115,8 @@ isc_result_t isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); /*!< * \brief Create and open a file with a unique name based on 'templet'. - * isc_file_bopen*() open the file in binary mode in Windows. - * isc_file_open*() open the file in text mode in Windows. + * isc_file_bopen*() open the file in binary mode in Windows. + * isc_file_open*() open the file in text mode in Windows. * * Notes: *\li 'template' is a reserved work in C++. If you want to complain @@ -217,6 +217,22 @@ isc_file_isplainfile(const char *name); * These occur when stat returns -1 and an errno. */ +isc_result_t +isc_file_isdirectory(const char *name); +/*!< + * \brief Check that 'name' exists and is a directory. + * + * Returns: + *\li #ISC_R_SUCCESS + * Success, file is a directory. + *\li #ISC_R_INVALIDFILE + * File is not a directory. + *\li #ISC_R_FILENOTFOUND + * File does not exist. + *\li #other ISC_R_* errors translated from errno + * These occur when stat returns -1 and an errno. + */ + isc_boolean_t isc_file_iscurrentdir(const char *filename); /*!< diff --git a/lib/isc/include/isc/list.h b/lib/isc/include/isc/list.h index 4056be257f3cf..2b174eca575c9 100644 --- a/lib/isc/include/isc/list.h +++ b/lib/isc/include/isc/list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -102,6 +102,8 @@ } \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ + ISC_INSIST((list).head != (elt)); \ + ISC_INSIST((list).tail != (elt)); \ } while (0) #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \ diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index c47ae55ad1beb..317417f63663b 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -40,15 +40,6 @@ typedef void * (*isc_memalloc_t)(void *, size_t); typedef void (*isc_memfree_t)(void *, void *); /*% - * Define ISC_MEM_DEBUG=1 to make all functions that free memory - * set the pointer being freed to NULL after being freed. - * This is the default; set ISC_MEM_DEBUG=0 to disable it. - */ -#ifndef ISC_MEM_DEBUG -#define ISC_MEM_DEBUG 1 -#endif - -/*% * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory * allocation and freeing by file and line number. */ @@ -274,7 +265,6 @@ struct isc_mempool { #define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \ (mp)->magic == ISCAPI_MPOOL_MAGIC) -#if ISC_MEM_DEBUG #define isc_mem_put(c, p, s) \ do { \ ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \ @@ -295,13 +285,6 @@ struct isc_mempool { ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) -#else -#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_putanddetach(c, p, s) \ - ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE) -#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE) -#endif /*@{*/ isc_result_t @@ -548,7 +531,7 @@ isc_mem_gettag(isc_mem_t *ctx); */ #ifdef HAVE_LIBXML2 -void +int isc_mem_renderxml(xmlTextWriterPtr writer); /*%< * Render all contexts' statistics and status in XML for writer. diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h index ae1801d5f4617..45b769c5eeb5b 100644 --- a/lib/isc/include/isc/namespace.h +++ b/lib/isc/include/isc/namespace.h @@ -70,6 +70,7 @@ #define isc_mem_isovermem isc__mem_isovermem #define isc_mem_setname isc__mem_setname #define isc_mem_setwater isc__mem_setwater +#define isc_mem_printactive isc__mem_printactive #define isc_mem_printallactive isc__mem_printallactive #define isc_mem_waterack isc__mem_waterack #define isc_mempool_create isc__mempool_create diff --git a/lib/isc/include/isc/regex.h b/lib/isc/include/isc/regex.h new file mode 100644 index 0000000000000..3cf6aa4c686aa --- /dev/null +++ b/lib/isc/include/isc/regex.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 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_REGEX_H +#define ISC_REGEX_H 1 + +/*! \file isc/regex.h */ + +#include <isc/types.h> +#include <isc/lang.h> + +ISC_LANG_BEGINDECLS + +int +isc_regex_validate(const char *expression); +/*%< + * Check a regular expression for syntactic correctness. + * + * Returns: + *\li -1 on error. + *\li the number of groups in the expression. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_REGEX_H */ diff --git a/lib/isc/include/isc/region.h b/lib/isc/include/isc/region.h index 43d8f8f2d3e97..ccca272ae5228 100644 --- a/lib/isc/include/isc/region.h +++ b/lib/isc/include/isc/region.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -23,6 +23,7 @@ /*! \file isc/region.h */ #include <isc/types.h> +#include <isc/lang.h> struct isc_region { unsigned char * base; @@ -81,12 +82,14 @@ struct isc_consttextregion { } while (0) /*@}*/ +ISC_LANG_BEGINDECLS + int isc_region_compare(isc_region_t *r1, isc_region_t *r2); /*%< - * Compares the contents of two regions + * Compares the contents of two regions * - * Requires: + * Requires: *\li 'r1' is a valid region *\li 'r2' is a valid region * @@ -96,4 +99,6 @@ isc_region_compare(isc_region_t *r1, isc_region_t *r2); *\li > 0 if r1 is lexicographically greater than r2 */ +ISC_LANG_ENDDECLS + #endif /* ISC_REGION_H */ diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 1e6914222c1ba..4d811dd64971d 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -34,6 +34,7 @@ struct isc_sockaddr { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; + struct sockaddr_storage ss; #ifdef ISC_PLATFORM_HAVESYSUNH struct sockaddr_un sunix; #endif diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 0df7d27f14ada..4111ec2c6bed6 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -1116,7 +1116,7 @@ isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp); #ifdef HAVE_LIBXML2 -void +int isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer); /*%< * Render internal statistics and other state into the XML document. diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index 19d47835786be..ced70590b167f 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -726,7 +726,7 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp); #ifdef HAVE_LIBXML2 -void +int isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer); #endif diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index fa9abb16aa9d5..0598f79b58e07 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -108,8 +108,8 @@ typedef struct { void (*destroy)(isc_timermgr_t **managerp); isc_result_t (*timercreate)(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, @@ -120,7 +120,8 @@ typedef struct { void (*attach)(isc_timer_t *timer, isc_timer_t **timerp); void (*detach)(isc_timer_t **timerp); isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_boolean_t purge); isc_result_t (*touch)(isc_timer_t *timer); } isc_timermethods_t; @@ -168,8 +169,8 @@ struct isc_timer { isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, @@ -232,8 +233,8 @@ isc_timer_create(isc_timermgr_t *manager, isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_boolean_t purge); /*%< * Change the timer's type, expires, and interval values to the given diff --git a/lib/isc/inet_aton.c b/lib/isc/inet_aton.c index 14b4887f4f16b..66a108dc4274f 100644 --- a/lib/isc/inet_aton.c +++ b/lib/isc/inet_aton.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -91,7 +91,7 @@ static char rcsid[] = "$Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp $"; */ int isc_net_aton(const char *cp, struct in_addr *addr) { - unsigned long val; + isc_uint32_t val; int base, n; unsigned char c; isc_uint8_t parts[4]; diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 1964b7a07996e..20fec46c7cbfc 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -202,6 +202,7 @@ struct isc__mempool { #if ! ISC_MEM_TRACKLINES #define ADD_TRACE(a, b, c, d, e) #define DELETE_TRACE(a, b, c, d, e) +#define ISC_MEMFUNC_SCOPE #else #define ADD_TRACE(a, b, c, d, e) \ do { \ @@ -321,6 +322,7 @@ isc__mem_checkdestroyed(FILE *file); ISC_MEMFUNC_SCOPE unsigned int isc__mem_references(isc_mem_t *ctx0); #endif +#endif /* ISC_MEM_TRACKLINES */ static struct isc__memmethods { isc_memmethods_t methods; @@ -389,6 +391,7 @@ static struct isc__mempoolmethods { #endif }; +#if ISC_MEM_TRACKLINES /*! * mctx must be locked. */ @@ -1478,7 +1481,12 @@ isc__mem_stats(isc_mem_t *ctx0, FILE *out) { } while (pool != NULL) { fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n", - pool->name, (unsigned long) pool->size, pool->maxalloc, +#if ISC_MEMPOOL_NAMES + pool->name, +#else + "(not tracked)", +#endif + (unsigned long) pool->size, pool->maxalloc, pool->allocated, pool->freecount, pool->freemax, pool->fillcount, pool->gets, (pool->lock == NULL ? "N" : "Y")); @@ -2260,16 +2268,16 @@ isc__mem_register() { #ifdef BIND9 ISC_MEMFUNC_SCOPE void isc__mem_printactive(isc_mem_t *ctx0, FILE *file) { +#if ISC_MEM_TRACKLINES isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(file != NULL); -#if !ISC_MEM_TRACKLINES - UNUSED(ctx); - UNUSED(file); -#else print_active(ctx, file); +#else + UNUSED(ctx0); + UNUSED(file); #endif } @@ -2295,6 +2303,9 @@ isc__mem_printallactive(FILE *file) { ISC_MEMFUNC_SCOPE void isc__mem_checkdestroyed(FILE *file) { +#if !ISC_MEM_TRACKLINES + UNUSED(file); +#endif RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2339,25 +2350,27 @@ typedef struct summarystat { isc_uint64_t contextsize; } summarystat_t; -static void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +static int renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) { + int xmlrc; + REQUIRE(VALID_CONTEXT(ctx)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "context"); + MCTXLOCK(ctx, &ctx->lock); + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "context")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", ctx); - xmlTextWriterEndElement(writer); /* id */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", ctx)); + TRY0(xmlTextWriterEndElement(writer)); /* id */ if (ctx->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", ctx->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", ctx->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); - summary->contextsize += sizeof(*ctx) + (ctx->max_size + 1) * sizeof(struct stats) + ctx->max_size * sizeof(element *) + @@ -2369,70 +2382,79 @@ renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) { ctx->debuglistcnt * sizeof(debuglink_t); } #endif - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", ctx->references); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", ctx->references)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ summary->total += ctx->total; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "total"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->total); - xmlTextWriterEndElement(writer); /* total */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "total")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->total)); + TRY0(xmlTextWriterEndElement(writer)); /* total */ summary->inuse += ctx->inuse; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->inuse); - xmlTextWriterEndElement(writer); /* inuse */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->inuse)); + TRY0(xmlTextWriterEndElement(writer)); /* inuse */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->maxinuse); - xmlTextWriterEndElement(writer); /* maxinuse */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->maxinuse)); + TRY0(xmlTextWriterEndElement(writer)); /* maxinuse */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize")); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { summary->blocksize += ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target; - xmlTextWriterWriteFormatString(writer, + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t) ctx->basic_table_count * NUM_BASIC_BLOCKS * - ctx->mem_target); + ctx->mem_target)); } else - xmlTextWriterWriteFormatString(writer, "%s", "-"); - xmlTextWriterEndElement(writer); /* blocksize */ + TRY0(xmlTextWriterWriteFormatString(writer, "%s", "-")); + TRY0(xmlTextWriterEndElement(writer)); /* blocksize */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools"); - xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt); - xmlTextWriterEndElement(writer); /* pools */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools")); + TRY0(xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt)); + TRY0(xmlTextWriterEndElement(writer)); /* pools */ summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->hi_water); - xmlTextWriterEndElement(writer); /* hiwater */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->hi_water)); + TRY0(xmlTextWriterEndElement(writer)); /* hiwater */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->lo_water); - xmlTextWriterEndElement(writer); /* lowater */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->lo_water)); + TRY0(xmlTextWriterEndElement(writer)); /* lowater */ + TRY0(xmlTextWriterEndElement(writer)); /* context */ + + error: MCTXUNLOCK(ctx, &ctx->lock); - xmlTextWriterEndElement(writer); /* context */ + return (xmlrc); } -void +int isc_mem_renderxml(xmlTextWriterPtr writer) { isc__mem_t *ctx; summarystat_t summary; isc_uint64_t lost; + int xmlrc; memset(&summary, 0, sizeof(summary)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts")); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2441,40 +2463,51 @@ isc_mem_renderxml(xmlTextWriterPtr writer) { for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { - renderctx(ctx, &summary, writer); + xmlrc = renderctx(ctx, &summary, writer); + if (xmlrc < 0) { + UNLOCK(&lock); + goto error; + } } UNLOCK(&lock); - xmlTextWriterEndElement(writer); /* contexts */ + TRY0(xmlTextWriterEndElement(writer)); /* contexts */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.total); - xmlTextWriterEndElement(writer); /* TotalUse */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.total)); + TRY0(xmlTextWriterEndElement(writer)); /* TotalUse */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.inuse); - xmlTextWriterEndElement(writer); /* InUse */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.inuse)); + TRY0(xmlTextWriterEndElement(writer)); /* InUse */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.blocksize); - xmlTextWriterEndElement(writer); /* BlockSize */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.blocksize)); + TRY0(xmlTextWriterEndElement(writer)); /* BlockSize */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.contextsize); - xmlTextWriterEndElement(writer); /* ContextSize */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.contextsize)); + TRY0(xmlTextWriterEndElement(writer)); /* ContextSize */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - lost); - xmlTextWriterEndElement(writer); /* Lost */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + lost)); + TRY0(xmlTextWriterEndElement(writer)); /* Lost */ - xmlTextWriterEndElement(writer); /* summary */ + TRY0(xmlTextWriterEndElement(writer)); /* summary */ + error: + return (xmlrc); } #endif /* HAVE_LIBXML2 */ diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in index 540b2434240cd..b8b5f98b6f516 100644 --- a/lib/isc/nothreads/Makefile.in +++ b/lib/isc/nothreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -16,8 +16,8 @@ # $Id: Makefile.in,v 1.12 2010/06/09 23:50:58 tbox Exp $ top_srcdir = @top_srcdir@ -srcdir = @top_srcdir@/lib/isc/nothreads -VPATH = @top_srcdir@/lib/isc/nothreads +srcdir = @srcdir@ +VPATH = @srcdir@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ diff --git a/lib/isc/parseint.c b/lib/isc/parseint.c index 266d44cec5c5f..f8ec3892c2c54 100644 --- a/lib/isc/parseint.c +++ b/lib/isc/parseint.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +32,7 @@ isc_result_t isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) { unsigned long n; + isc_uint32_t r; char *e; if (! isalnum((unsigned char)(string[0]))) return (ISC_R_BADNUMBER); @@ -39,9 +40,15 @@ isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) { n = strtoul(string, &e, base); if (*e != '\0') return (ISC_R_BADNUMBER); - if (n == ULONG_MAX && errno == ERANGE) + /* + * Where long is 64 bits we need to convert to 32 bits then test for + * equality. This is a no-op on 32 bit machines and a good compiler + * will optimise it away. + */ + r = (isc_uint32_t)n; + if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) return (ISC_R_RANGE); - *uip = n; + *uip = r; return (ISC_R_SUCCESS); } diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c index 4b5b4919b2b01..1b250fac2801f 100644 --- a/lib/isc/pthreads/thread.c +++ b/lib/isc/pthreads/thread.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -25,7 +25,7 @@ #include <isc/util.h> #ifndef THREAD_MINSTACKSIZE -#define THREAD_MINSTACKSIZE (64U * 1024) +#define THREAD_MINSTACKSIZE (1024U * 1024) #endif isc_result_t diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index 07bcc7c7af1c2..fc66e9f61efb4 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -114,7 +114,7 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) { /* * If the timer is currently running, change its rate. */ - if (rl->state == isc_ratelimiter_ratelimited) { + if (rl->state == isc_ratelimiter_ratelimited) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); } @@ -142,13 +142,13 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, REQUIRE(ev->ev_sender == NULL); LOCK(&rl->lock); - if (rl->state == isc_ratelimiter_ratelimited || + if (rl->state == isc_ratelimiter_ratelimited || rl->state == isc_ratelimiter_stalled) { isc_event_t *ev = *eventp; ev->ev_sender = task; - ISC_LIST_APPEND(rl->pending, ev, ev_link); + ISC_LIST_APPEND(rl->pending, ev, ev_link); *eventp = NULL; - } else if (rl->state == isc_ratelimiter_idle) { + } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) { @@ -177,7 +177,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); pertic = rl->pertic; - while (pertic != 0) { + while (pertic != 0) { pertic--; LOCK(&rl->lock); p = ISC_LIST_HEAD(rl->pending); @@ -289,8 +289,9 @@ isc_ratelimiter_stall(isc_ratelimiter_t *rl) { break; case isc_ratelimiter_ratelimited: result = isc_timer_reset(rl->timer, isc_timertype_inactive, - NULL, NULL, ISC_FALSE); + NULL, NULL, ISC_FALSE); RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* FALLTHROUGH */ case isc_ratelimiter_idle: case isc_ratelimiter_stalled: rl->state = isc_ratelimiter_stalled; @@ -316,7 +317,7 @@ isc_ratelimiter_release(isc_ratelimiter_t *rl) { &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) rl->state = isc_ratelimiter_ratelimited; - } else + } else rl->state = isc_ratelimiter_idle; break; case isc_ratelimiter_ratelimited: diff --git a/lib/isc/regex.c b/lib/isc/regex.c new file mode 100644 index 0000000000000..279bcdc437fbd --- /dev/null +++ b/lib/isc/regex.c @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2013 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. + */ + +#include <config.h> + +#include <isc/file.h> +#include <isc/regex.h> +#include <isc/string.h> + +#if VALREGEX_REPORT_REASON +#define FAIL(x) do { reason = (x); goto error; } while(0) +#else +#define FAIL(x) goto error +#endif + +/* + * Validate the regular expression 'C' locale. + */ +int +isc_regex_validate(const char *c) { + enum { + none, parse_bracket, parse_bound, + parse_ce, parse_ec, parse_cc + } state = none; + /* Well known character classes. */ + const char *cc[] = { + ":alnum:", ":digit:", ":punct:", ":alpha:", ":graph:", + ":space:", ":blank:", ":lower:", ":upper:", ":cntrl:", + ":print:", ":xdigit:" + }; + isc_boolean_t seen_comma = ISC_FALSE; + isc_boolean_t seen_high = ISC_FALSE; + isc_boolean_t seen_char = ISC_FALSE; + isc_boolean_t seen_ec = ISC_FALSE; + isc_boolean_t seen_ce = ISC_FALSE; + isc_boolean_t have_atom = ISC_FALSE; + int group = 0; + int range = 0; + int sub = 0; + isc_boolean_t empty_ok = ISC_FALSE; + isc_boolean_t neg = ISC_FALSE; + isc_boolean_t was_multiple = ISC_FALSE; + unsigned int low = 0; + unsigned int high = 0; + const char *ccname = NULL; + int range_start = 0; +#if VALREGEX_REPORT_REASON + const char *reason = ""; +#endif + + if (c == NULL || *c == 0) + FAIL("empty string"); + + while (c != NULL && *c != 0) { + switch (state) { + case none: + switch (*c) { + case '\\': /* make literal */ + ++c; + switch (*c) { + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + if ((*c - '0') > sub) + FAIL("bad back reference"); + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + break; + case 0: + FAIL("escaped end-of-string"); + default: + goto literal; + } + ++c; + break; + case '[': /* bracket start */ + ++c; + neg = ISC_FALSE; + was_multiple = ISC_FALSE; + seen_char = ISC_FALSE; + state = parse_bracket; + break; + case '{': /* bound start */ + switch (c[1]) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + if (!have_atom) + FAIL("no atom"); + if (was_multiple) + FAIL("was multiple"); + seen_comma = ISC_FALSE; + seen_high = ISC_FALSE; + low = high = 0; + state = parse_bound; + break; + default: + goto literal; + } + ++c; + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + break; + case '}': + goto literal; + case '(': /* group start */ + have_atom = ISC_FALSE; + was_multiple = ISC_FALSE; + empty_ok = ISC_TRUE; + ++group; + ++sub; + ++c; + break; + case ')': /* group end */ + if (group && !have_atom && !empty_ok) + FAIL("empty alternative"); + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + if (group != 0) + --group; + ++c; + break; + case '|': /* alternative seperator */ + if (!have_atom) + FAIL("no atom"); + have_atom = ISC_FALSE; + empty_ok = ISC_FALSE; + was_multiple = ISC_FALSE; + ++c; + break; + case '^': + case '$': + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + ++c; + break; + case '+': + case '*': + case '?': + if (was_multiple) + FAIL("was multiple"); + if (!have_atom) + FAIL("no atom"); + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + ++c; + break; + case '.': + default: + literal: + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + ++c; + break; + } + break; + case parse_bound: + switch (*c) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (!seen_comma) { + low = low * 10 + *c - '0'; + if (low > 255) + FAIL("lower bound too big"); + } else { + seen_high = ISC_TRUE; + high = high * 10 + *c - '0'; + if (high > 255) + FAIL("upper bound too big"); + } + ++c; + break; + case ',': + if (seen_comma) + FAIL("multiple commas"); + seen_comma = ISC_TRUE; + ++c; + break; + default: + case '{': + FAIL("non digit/comma"); + case '}': + if (seen_high && low > high) + FAIL("bad parse bound"); + seen_comma = ISC_FALSE; + state = none; + ++c; + break; + } + break; + case parse_bracket: + switch (*c) { + case '^': + if (seen_char || neg) goto inside; + neg = ISC_TRUE; + ++c; + break; + case '-': + if (range == 2) goto inside; + if (!seen_char) goto inside; + if (range == 1) + FAIL("bad range"); + range = 2; + ++c; + break; + case '[': + ++c; + switch (*c) { + case '.': /* collating element */ + if (range) --range; + ++c; + state = parse_ce; + seen_ce = ISC_FALSE; + break; + case '=': /* equivalence class */ + if (range == 2) + FAIL("equivalence class in range"); + ++c; + state = parse_ec; + seen_ec = ISC_FALSE; + break; + case ':': /* character class */ + if (range == 2) + FAIL("character class in range"); + ccname = c; + ++c; + state = parse_cc; + break; + } + seen_char = ISC_TRUE; + break; + case ']': + if (!c[1] && !seen_char) + FAIL("unfinished brace"); + if (!seen_char) + goto inside; + ++c; + range = 0; + have_atom = ISC_TRUE; + state = none; + break; + default: + inside: + seen_char = ISC_TRUE; + if (range == 2 && *c < range_start) + FAIL("out of order range"); + if (range != 0) + --range; + range_start = *c; + ++c; + break; + }; + break; + case parse_ce: + switch (*c) { + case '.': + ++c; + switch (*c) { + case ']': + if (!seen_ce) + FAIL("empty ce"); + ++c; + state = parse_bracket; + break; + default: + if (seen_ce) + range_start = 256; + else + range_start = '.'; + seen_ce = ISC_TRUE; + break; + } + break; + default: + if (seen_ce) + range_start = 256; + else + range_start = *c; + seen_ce = ISC_TRUE; + ++c; + break; + } + break; + case parse_ec: + switch (*c) { + case '=': + ++c; + switch (*c) { + case ']': + if (!seen_ec) + FAIL("no ec"); + ++c; + state = parse_bracket; + break; + default: + seen_ec = ISC_TRUE; + break; + } + break; + default: + seen_ec = ISC_TRUE; + ++c; + break; + } + break; + case parse_cc: + switch (*c) { + case ':': + ++c; + switch (*c) { + case ']': { + unsigned int i; + isc_boolean_t found = ISC_FALSE; + for (i = 0; + i < sizeof(cc)/sizeof(*cc); + i++) + { + unsigned int len; + len = strlen(cc[i]); + if (len != + (unsigned int)(c - ccname)) + continue; + if (strncmp(cc[i], ccname, len)) + continue; + found = ISC_TRUE; + } + if (!found) + FAIL("unknown cc"); + ++c; + state = parse_bracket; + break; + } + default: + break; + } + break; + default: + ++c; + break; + } + break; + } + } + if (group != 0) + FAIL("group open"); + if (state != none) + FAIL("incomplete"); + if (!have_atom) + FAIL("no atom"); + return (sub); + + error: +#if VALREGEX_REPORT_REASON + fprintf(stderr, "%s\n", reason); +#endif + return (-1); +} diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index 7b43b8f31bb86..91a949b642539 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -219,13 +219,12 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) { break; case AF_INET6: in6 = &sockaddr->type.sin6.sin6_addr; + s = (const unsigned char *)in6; if (IN6_IS_ADDR_V4MAPPED(in6)) { - s = (const unsigned char *)&in6[12]; + s += 12; length = sizeof(sockaddr->type.sin.sin_addr.s_addr); - } else { - s = (const unsigned char *)in6; + } else length = sizeof(sockaddr->type.sin6.sin6_addr); - } p = ntohs(sockaddr->type.sin6.sin6_port); break; default: diff --git a/lib/isc/sparc64/include/isc/atomic.h b/lib/isc/sparc64/include/isc/atomic.h index b920095615935..4b366619a56a8 100644 --- a/lib/isc/sparc64/include/isc/atomic.h +++ b/lib/isc/sparc64/include/isc/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005, 2007, 2013 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 @@ -72,9 +72,9 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(swapped) - : "r"(p), "n"(ASI_P), "r"(prev)); + "casa [%2] %3, %4, %0" + : "+r"(swapped), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } @@ -92,10 +92,9 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) { for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(swapped) - : "r"(p), "n"(ASI_P), "r"(prev) - : "memory"); + "casa [%2] %3, %4, %0" + : "+r"(swapped), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } @@ -111,9 +110,9 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t temp = val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(temp) - : "r"(p), "n"(ASI_P), "r"(cmpval)); + "casa [%2] %3, %4, %0" + : "+r"(temp), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(cmpval), "m"(*p)); return (temp); } diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index d4c1dccf0ad90..1f294fb9c02e9 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -71,15 +71,17 @@ isc_symtab_create(isc_mem_t *mctx, unsigned int size, symtab = (isc_symtab_t *)isc_mem_get(mctx, sizeof(*symtab)); if (symtab == NULL) return (ISC_R_NOMEMORY); + + symtab->mctx = NULL; + isc_mem_attach(mctx, &symtab->mctx); symtab->table = (eltlist_t *)isc_mem_get(mctx, size * sizeof(eltlist_t)); if (symtab->table == NULL) { - isc_mem_put(mctx, symtab, sizeof(*symtab)); + isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); return (ISC_R_NOMEMORY); } for (i = 0; i < size; i++) INIT_LIST(symtab->table[i]); - symtab->mctx = mctx; symtab->size = size; symtab->count = 0; symtab->maxload = size * 3 / 4; @@ -117,7 +119,7 @@ isc_symtab_destroy(isc_symtab_t **symtabp) { isc_mem_put(symtab->mctx, symtab->table, symtab->size * sizeof(eltlist_t)); symtab->magic = 0; - isc_mem_put(symtab->mctx, symtab, sizeof(*symtab)); + isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); *symtabp = NULL; } diff --git a/lib/isc/task.c b/lib/isc/task.c index a5f6ef98f6c9e..94f1c6d6dabdb 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -1539,10 +1539,12 @@ isc_task_exiting(isc_task_t *t) { #if defined(HAVE_LIBXML2) && defined(BIND9) -void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +int isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; - isc__task_t *task; + isc__task_t *task = NULL; + int xmlrc; LOCK(&mgr->lock); @@ -1550,72 +1552,82 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { * Write out the thread-model, and some details about each depending * on which type is enabled. */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model")); #ifdef ISC_PLATFORM_USETHREADS - xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded"); - xmlTextWriterEndElement(writer); /* type */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded")); + TRY0(xmlTextWriterEndElement(writer)); /* type */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->workers); - xmlTextWriterEndElement(writer); /* worker-threads */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers)); + TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */ #else /* ISC_PLATFORM_USETHREADS */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"); - xmlTextWriterEndElement(writer); /* type */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded")); + TRY0(xmlTextWriterEndElement(writer)); /* type */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ #endif /* ISC_PLATFORM_USETHREADS */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum); - xmlTextWriterEndElement(writer); /* default-quantum */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + mgr->default_quantum)); + TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running); - xmlTextWriterEndElement(writer); /* tasks-running */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running)); + TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */ - xmlTextWriterEndElement(writer); /* thread-model */ + TRY0(xmlTextWriterEndElement(writer)); /* thread-model */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks")); task = ISC_LIST_HEAD(mgr->tasks); while (task != NULL) { LOCK(&task->lock); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "task"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "task")); if (task->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", - task->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + task->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", task->references); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + task->references)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", task); - xmlTextWriterEndElement(writer); /* id */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", task)); + TRY0(xmlTextWriterEndElement(writer)); /* id */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "state"); - xmlTextWriterWriteFormatString(writer, "%s", - statenames[task->state]); - xmlTextWriterEndElement(writer); /* state */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + statenames[task->state])); + TRY0(xmlTextWriterEndElement(writer)); /* state */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum"); - xmlTextWriterWriteFormatString(writer, "%d", task->quantum); - xmlTextWriterEndElement(writer); /* quantum */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + task->quantum)); + TRY0(xmlTextWriterEndElement(writer)); /* quantum */ - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterEndElement(writer)); UNLOCK(&task->lock); task = ISC_LIST_NEXT(task, link); } - xmlTextWriterEndElement(writer); /* tasks */ + TRY0(xmlTextWriterEndElement(writer)); /* tasks */ + error: + if (task != NULL) + UNLOCK(&task->lock); UNLOCK(&mgr->lock); + + return (xmlrc); } #endif /* HAVE_LIBXML2 && BIND9 */ diff --git a/lib/isc/taskpool.c b/lib/isc/taskpool.c index 936732c0e955b..7324cfa379d00 100644 --- a/lib/isc/taskpool.c +++ b/lib/isc/taskpool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -52,13 +52,15 @@ alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, pool = isc_mem_get(mctx, sizeof(*pool)); if (pool == NULL) return (ISC_R_NOMEMORY); - pool->mctx = mctx; + + pool->mctx = NULL; + isc_mem_attach(mctx, &pool->mctx); pool->ntasks = ntasks; pool->quantum = quantum; pool->tmgr = tmgr; pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); if (pool->tasks == NULL) { - isc_mem_put(mctx, pool, sizeof(*pool)); + isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); return (ISC_R_NOMEMORY); } for (i = 0; i < ntasks; i++) @@ -169,7 +171,7 @@ isc_taskpool_destroy(isc_taskpool_t **poolp) { } isc_mem_put(pool->mctx, pool->tasks, pool->ntasks * sizeof(isc_task_t *)); - isc_mem_put(pool->mctx, pool, sizeof(*pool)); + isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); *poolp = NULL; } diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 0da251f4c31b3..23fcbbef64986 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -130,12 +130,12 @@ struct isc__timermgr { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp); ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge); ISC_TIMERFUNC_SCOPE isc_timertype_t isc__timer_gettype(isc_timer_t *timer); @@ -392,7 +392,7 @@ destroy(isc__timer_t *timer) { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp) { @@ -514,7 +514,7 @@ isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { isc__timer_t *timer = (isc__timer_t *)timer0; @@ -692,7 +692,7 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { while (manager->nscheduled > 0 && !done) { timer = isc_heap_element(manager->heap, 1); - INSIST(timer->type != isc_timertype_inactive); + INSIST(timer != NULL && timer->type != isc_timertype_inactive); if (isc_time_compare(now, &timer->due) >= 0) { if (timer->type == isc_timertype_ticker) { type = ISC_TIMEREVENT_TICK; diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c index 97e62b3f0ec41..39b33e3c7444d 100644 --- a/lib/isc/timer_api.c +++ b/lib/isc/timer_api.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2012 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 @@ -96,7 +96,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp) { @@ -128,7 +128,7 @@ isc_timer_detach(isc_timer_t **timerp) { isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { REQUIRE(ISCAPI_TIMER_VALID(timer)); diff --git a/lib/isc/unix/entropy.c b/lib/isc/unix/entropy.c index ab53faf6754ed..9c422b55a38b4 100644 --- a/lib/isc/unix/entropy.c +++ b/lib/isc/unix/entropy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -536,8 +536,7 @@ isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { memset(&sname, 0, sizeof(sname)); sname.sun_family = AF_UNIX; - strncpy(sname.sun_path, fname, sizeof(sname.sun_path)); - sname.sun_path[sizeof(sname.sun_path)-1] = '0'; + strlcpy(sname.sun_path, fname, sizeof(sname.sun_path)); #ifdef ISC_PLATFORM_HAVESALEN #if !defined(SUN_LEN) #define SUN_LEN(su) \ diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c index 99c02ec7b6283..7bb25d725f079 100644 --- a/lib/isc/unix/file.c +++ b/lib/isc/unix/file.c @@ -396,6 +396,24 @@ isc_file_isplainfile(const char *filename) { return(ISC_R_SUCCESS); } +isc_result_t +isc_file_isdirectory(const char *filename) { + /* + * This function returns success if filename exists and is a + * directory. + */ + struct stat filestat; + memset(&filestat,0,sizeof(struct stat)); + + if ((stat(filename, &filestat)) == -1) + return(isc__errno2result(errno)); + + if(! S_ISDIR(filestat.st_mode)) + return(ISC_R_INVALIDFILE); + + return(ISC_R_SUCCESS); +} + isc_boolean_t isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); @@ -542,6 +560,9 @@ isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) { char *dir, *file, *slash; + if (path == NULL) + return (ISC_R_INVALIDFILE); + slash = strrchr(path, '/'); if (slash == path) { diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h index dc1cef9ad3f23..d81d854a24e29 100644 --- a/lib/isc/unix/include/isc/time.h +++ b/lib/isc/unix/include/isc/time.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012 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,7 @@ struct isc_interval { unsigned int nanoseconds; }; -extern isc_interval_t *isc_interval_zero; +extern const isc_interval_t * const isc_interval_zero; ISC_LANG_BEGINDECLS @@ -85,7 +85,7 @@ struct isc_time { unsigned int nanoseconds; }; -extern isc_time_t *isc_time_epoch; +extern const isc_time_t * const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c index ea4a504ebdec8..1fedbc438deda 100644 --- a/lib/isc/unix/net.c +++ b/lib/isc/unix/net.c @@ -301,8 +301,6 @@ try_ipv6only(void) { goto close; } - close(s); - ipv6only_result = ISC_R_SUCCESS; close: @@ -358,7 +356,6 @@ try_ipv6pktinfo(void) { goto close; } - close(s); ipv6pktinfo_result = ISC_R_SUCCESS; close: diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 9d64a77ab37bd..d007598e19d09 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -613,7 +613,7 @@ enum { STATID_SENDFAIL = 8, STATID_RECVFAIL = 9 }; -static const isc_statscounter_t upd4statsindex[] = { +static const isc_statscounter_t udp4statsindex[] = { isc_sockstatscounter_udp4open, isc_sockstatscounter_udp4openfail, isc_sockstatscounter_udp4close, @@ -625,7 +625,7 @@ static const isc_statscounter_t upd4statsindex[] = { isc_sockstatscounter_udp4sendfail, isc_sockstatscounter_udp4recvfail }; -static const isc_statscounter_t upd6statsindex[] = { +static const isc_statscounter_t udp6statsindex[] = { isc_sockstatscounter_udp6open, isc_sockstatscounter_udp6openfail, isc_sockstatscounter_udp6close, @@ -1192,7 +1192,7 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { struct in6_pktinfo *pktinfop; #endif #ifdef SO_TIMESTAMP - struct timeval *timevalp; + void *timevalp; #endif #endif @@ -1259,9 +1259,11 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { #ifdef SO_TIMESTAMP if (cmsgp->cmsg_level == SOL_SOCKET && cmsgp->cmsg_type == SCM_TIMESTAMP) { - timevalp = (struct timeval *)CMSG_DATA(cmsgp); - dev->timestamp.seconds = timevalp->tv_sec; - dev->timestamp.nanoseconds = timevalp->tv_usec * 1000; + struct timeval tv; + timevalp = CMSG_DATA(cmsgp); + memcpy(&tv, timevalp, sizeof(tv)); + dev->timestamp.seconds = tv.tv_sec; + dev->timestamp.nanoseconds = tv.tv_usec * 1000; dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP; goto next; } @@ -2052,7 +2054,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->sendcmsgbuf = NULL; /* - * set up cmsg buffers + * Set up cmsg buffers. */ cmsgbuflen = 0; #if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) @@ -2094,7 +2096,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->tag = NULL; /* - * set up list of readers and writers to be initially empty + * Set up list of readers and writers to be initially empty. */ ISC_LIST_INIT(sock->recv_list); ISC_LIST_INIT(sock->send_list); @@ -2109,7 +2111,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->bound = 0; /* - * initialize the lock + * Initialize the lock. */ result = isc_mutex_init(&sock->lock); if (result != ISC_R_SUCCESS) { @@ -2119,7 +2121,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, } /* - * Initialize readable and writable events + * Initialize readable and writable events. */ ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t), ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR, @@ -2223,13 +2225,38 @@ clear_bsdcompat(void) { } #endif +static void +use_min_mtu(isc__socket_t *sock) { +#if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) + UNUSED(sock); +#endif +#ifdef IPV6_USE_MIN_MTU + /* use minimum MTU */ + if (sock->pf == AF_INET6) { + int on = 1; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&on, sizeof(on)); + } +#endif +#if defined(IPV6_MTU) + /* + * Use minimum MTU on IPv6 sockets. + */ + if (sock->pf == AF_INET6) { + int mtu = 1280; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, + &mtu, sizeof(mtu)); + } +#endif +} + static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; -#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) +#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE) int on = 1; #endif #if defined(SO_RCVBUF) @@ -2367,6 +2394,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } #endif + /* + * Use minimum mtu if possible. + */ + use_min_mtu(sock); + #if defined(USE_CMSG) || defined(SO_RCVBUF) if (sock->type == isc_sockettype_udp) { @@ -2431,32 +2463,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/ - /* use minimum MTU */ - if (sock->pf == AF_INET6 && - setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_USE_MIN_MTU) " - "%s: %s", sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#endif -#if defined(IPV6_MTU) - /* - * Use minimum MTU on IPv6 sockets. - */ - if (sock->pf == AF_INET6) { - int mtu = 1280; - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, - &mtu, sizeof(mtu)); - } -#endif #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv6/UDP sockets. @@ -2546,7 +2552,7 @@ isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, switch (sock->type) { case isc_sockettype_udp: sock->statsindex = - (pf == AF_INET) ? upd4statsindex : upd6statsindex; + (pf == AF_INET) ? udp4statsindex : udp6statsindex; break; case isc_sockettype_tcp: sock->statsindex = @@ -3209,23 +3215,27 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { if (fd != -1) { int lockid = FDLOCK_ID(fd); - LOCK(&manager->fdlock[lockid]); - manager->fds[fd] = NEWCONNSOCK(dev); - manager->fdstate[fd] = MANAGED; - UNLOCK(&manager->fdlock[lockid]); - - LOCK(&manager->lock); - ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); - NEWCONNSOCK(dev)->fd = fd; NEWCONNSOCK(dev)->bound = 1; NEWCONNSOCK(dev)->connected = 1; /* + * Use minimum mtu if possible. + */ + use_min_mtu(NEWCONNSOCK(dev)); + + /* * Save away the remote address */ dev->address = NEWCONNSOCK(dev)->peer_address; + LOCK(&manager->fdlock[lockid]); + manager->fds[fd] = NEWCONNSOCK(dev); + manager->fdstate[fd] = MANAGED; + UNLOCK(&manager->fdlock[lockid]); + + LOCK(&manager->lock); + #ifdef USE_SELECT if (manager->maxfd < fd) manager->maxfd = fd; @@ -3236,6 +3246,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { "accepted connection, new socket %p", dev->newsocket); + ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); + UNLOCK(&manager->lock); inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]); @@ -5851,94 +5863,112 @@ _socktype(isc_sockettype_t type) return ("not-initialized"); } -ISC_SOCKETFUNC_SCOPE void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +ISC_SOCKETFUNC_SCOPE int isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; - isc__socket_t *sock; + isc__socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; + int xmlrc; LOCK(&mgr->lock); #ifdef USE_SHARED_MANAGER - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); + TRY0(xmlTextWriterEndElement(writer)); #endif /* USE_SHARED_MANAGER */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets")); sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { LOCK(&sock->lock); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", sock); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", sock)); + TRY0(xmlTextWriterEndElement(writer)); if (sock->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", - sock->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + sock->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", sock->references); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + sock->references)); + TRY0(xmlTextWriterEndElement(writer)); - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR _socktype(sock->type)); + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); - xmlTextWriterWriteElement(writer, + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "peer-address", - ISC_XMLCHAR peerbuf); + ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); - xmlTextWriterWriteElement(writer, + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "local-address", - ISC_XMLCHAR peerbuf); + ISC_XMLCHAR peerbuf)); } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "states"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); if (sock->pending_recv) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-receive"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-receive")); if (sock->pending_send) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-send"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-send")); if (sock->pending_accept) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending_accept"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending_accept")); if (sock->listener) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "listener"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "listener")); if (sock->connected) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "connected"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "connected")); if (sock->connecting) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "connecting"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "connecting")); if (sock->bound) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "bound"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "bound")); - xmlTextWriterEndElement(writer); /* states */ + TRY0(xmlTextWriterEndElement(writer)); /* states */ - xmlTextWriterEndElement(writer); /* socket */ + TRY0(xmlTextWriterEndElement(writer)); /* socket */ UNLOCK(&sock->lock); sock = ISC_LIST_NEXT(sock, link); } - xmlTextWriterEndElement(writer); /* sockets */ + TRY0(xmlTextWriterEndElement(writer)); /* sockets */ + + error: + if (sock != NULL) + UNLOCK(&sock->lock); UNLOCK(&mgr->lock); + + return (xmlrc); } #endif /* HAVE_LIBXML2 */ diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index ac23ae092804e..e820afb1eaa07 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -54,8 +54,8 @@ *** Intervals ***/ -static isc_interval_t zero_interval = { 0, 0 }; -isc_interval_t *isc_interval_zero = &zero_interval; +static const isc_interval_t zero_interval = { 0, 0 }; +const isc_interval_t * const isc_interval_zero = &zero_interval; #if ISC_FIX_TV_USEC static inline void @@ -110,8 +110,8 @@ isc_interval_iszero(const isc_interval_t *i) { *** Absolute Times ***/ -static isc_time_t epoch = { 0, 0 }; -isc_time_t *isc_time_epoch = &epoch; +static const isc_time_t epoch = { 0, 0 }; +const isc_time_t * const isc_time_epoch = &epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { |
