summaryrefslogtreecommitdiff
path: root/lib/isc
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2016-09-28 03:45:43 +0000
committerXin LI <delphij@FreeBSD.org>2016-09-28 03:45:43 +0000
commitc2a8859aa5c96190c179c911d3841c4de17b9c34 (patch)
treed692d2581f8989d075abe40c9f3f55f2fa650949 /lib/isc
parent5ef882476736cbe802bb4e6437c520162c4f44ce (diff)
Diffstat (limited to 'lib/isc')
-rw-r--r--lib/isc/Makefile.in4
-rw-r--r--lib/isc/alpha/include/isc/Makefile.in4
-rw-r--r--lib/isc/api6
-rw-r--r--lib/isc/base32.c4
-rw-r--r--lib/isc/base64.c4
-rw-r--r--lib/isc/buffer.c4
-rw-r--r--lib/isc/commandline.c2
-rw-r--r--lib/isc/hash.c151
-rw-r--r--lib/isc/hex.c4
-rw-r--r--lib/isc/httpd.c98
-rw-r--r--lib/isc/ia64/include/isc/Makefile.in4
-rw-r--r--lib/isc/include/isc/Makefile.in4
-rw-r--r--lib/isc/include/isc/assertions.h10
-rw-r--r--lib/isc/include/isc/error.h4
-rw-r--r--lib/isc/include/isc/file.h6
-rw-r--r--lib/isc/include/isc/hash.h41
-rw-r--r--lib/isc/include/isc/magic.h8
-rw-r--r--lib/isc/include/isc/netaddr.h8
-rw-r--r--lib/isc/include/isc/platform.h.in10
-rw-r--r--lib/isc/include/isc/result.h5
-rw-r--r--lib/isc/include/isc/sockaddr.h8
-rw-r--r--lib/isc/include/isc/socket.h6
-rw-r--r--lib/isc/include/isc/util.h13
-rw-r--r--lib/isc/md5.c4
-rw-r--r--lib/isc/mem.c58
-rw-r--r--lib/isc/mips/include/isc/Makefile.in4
-rw-r--r--lib/isc/netaddr.c18
-rw-r--r--lib/isc/noatomic/include/isc/Makefile.in4
-rw-r--r--lib/isc/nothreads/include/isc/Makefile.in4
-rw-r--r--lib/isc/powerpc/include/isc/Makefile.in4
-rw-r--r--lib/isc/pthreads/include/isc/Makefile.in4
-rw-r--r--lib/isc/result.c1
-rw-r--r--lib/isc/sockaddr.c25
-rw-r--r--lib/isc/sparc64/include/isc/Makefile.in4
-rw-r--r--lib/isc/stats.c78
-rw-r--r--lib/isc/string.c6
-rw-r--r--lib/isc/task.c4
-rw-r--r--lib/isc/unix/file.c15
-rw-r--r--lib/isc/unix/include/isc/Makefile.in4
-rw-r--r--lib/isc/unix/net.c4
-rw-r--r--lib/isc/unix/socket.c94
-rw-r--r--lib/isc/x86_32/include/isc/Makefile.in4
-rw-r--r--lib/isc/x86_32/include/isc/atomic.h26
-rw-r--r--lib/isc/x86_64/include/isc/Makefile.in4
-rw-r--r--lib/isc/x86_64/include/isc/atomic.h33
45 files changed, 635 insertions, 175 deletions
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
index 3176a267988d..8b2c0608aced 100644
--- a/lib/isc/Makefile.in
+++ b/lib/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -17,7 +17,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
@LIBISC_API@
diff --git a/lib/isc/alpha/include/isc/Makefile.in b/lib/isc/alpha/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/alpha/include/isc/Makefile.in
+++ b/lib/isc/alpha/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/api b/lib/isc/api
index 9a572b2d2e74..7de96ec52e86 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 = 106
-LIBREVISION = 0
-LIBAGE = 0
+LIBINTERFACE = 107
+LIBREVISION = 1
+LIBAGE = 1
diff --git a/lib/isc/base32.c b/lib/isc/base32.c
index 2ee99b182426..e472439eba5e 100644
--- a/lib/isc/base32.c
+++ b/lib/isc/base32.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2008, 2009, 2013-2015 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
@@ -170,7 +170,7 @@ base32_decode_init(base32_decode_ctx_t *ctx, int length, const char base[],
static inline isc_result_t
base32_decode_char(base32_decode_ctx_t *ctx, int c) {
- char *s;
+ const char *s;
unsigned int last;
if (ctx->seen_end)
diff --git a/lib/isc/base64.c b/lib/isc/base64.c
index 6b4cb1bf7c63..554097c47eb5 100644
--- a/lib/isc/base64.c
+++ b/lib/isc/base64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2013-2015 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
@@ -118,7 +118,7 @@ base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target)
static inline isc_result_t
base64_decode_char(base64_decode_ctx_t *ctx, int c) {
- char *s;
+ const char *s;
if (ctx->seen_end)
return (ISC_R_BADBASE64);
diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c
index 2d15e248575c..d0f08d767113 100644
--- a/lib/isc/buffer.c
+++ b/lib/isc/buffer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -462,6 +462,8 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
length);
dbuf->mctx = mctx;
+ ENSURE(ISC_BUFFER_VALID(dbuf));
+
*dynbuffer = dbuf;
return (ISC_R_SUCCESS);
diff --git a/lib/isc/commandline.c b/lib/isc/commandline.c
index 416fba1927a6..e58b1b8ceddc 100644
--- a/lib/isc/commandline.c
+++ b/lib/isc/commandline.c
@@ -95,7 +95,7 @@ static char endopt = '\0';
int
isc_commandline_parse(int argc, char * const *argv, const char *options) {
static char *place = ENDOPT;
- char *option; /* Index into *options of option. */
+ const char *option; /* Index into *options of option. */
REQUIRE(argc >= 0 && argv != NULL && options != NULL);
diff --git a/lib/isc/hash.c b/lib/isc/hash.c
index 6ee8dcf5a1f7..8fd58532838d 100644
--- a/lib/isc/hash.c
+++ b/lib/isc/hash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2013-2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -399,3 +399,152 @@ isc_hash_calc(const unsigned char *key, unsigned int keylen,
return (hash_calc(hash, key, keylen, case_sensitive));
}
+
+static isc_uint32_t fnv_offset_basis;
+static isc_once_t fnv_once = ISC_ONCE_INIT;
+
+static void
+fnv_initialize(void) {
+ /*
+ * This function should not leave fnv_offset_basis set to
+ * 0. Also, after this function has been called, if it is called
+ * again, it should not change fnv_offset_basis.
+ */
+ while (fnv_offset_basis == 0) {
+ isc_random_get(&fnv_offset_basis);
+ }
+}
+
+isc_uint32_t
+isc_hash_function(const void *data, size_t length,
+ isc_boolean_t case_sensitive,
+ const isc_uint32_t *previous_hashp)
+{
+ isc_uint32_t hval;
+ const unsigned char *bp;
+ const unsigned char *be;
+
+ INSIST(data == NULL || length > 0);
+ RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+ hval = ISC_UNLIKELY(previous_hashp != NULL) ?
+ *previous_hashp : fnv_offset_basis;
+
+ if (length == 0)
+ return (hval);
+
+ bp = (const unsigned char *) data;
+ be = bp + length;
+
+ /*
+ * Fowler-Noll-Vo FNV-1a hash function.
+ *
+ * NOTE: A random fnv_offset_basis is used by default to avoid
+ * collision attacks as the hash function is reversible. This
+ * makes the mapping non-deterministic, but the distribution in
+ * the domain is still uniform.
+ */
+
+ if (case_sensitive) {
+ while (bp < be - 4) {
+ hval ^= (isc_uint32_t) bp[0];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) bp[1];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) bp[2];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) bp[3];
+ hval *= 16777619;
+ bp += 4;
+ }
+ while (bp < be) {
+ hval ^= (isc_uint32_t) *bp++;
+ hval *= 16777619;
+ }
+ } else {
+ while (bp < be - 4) {
+ hval ^= (isc_uint32_t) maptolower[bp[0]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[bp[1]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[bp[2]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[bp[3]];
+ hval *= 16777619;
+ bp += 4;
+ }
+ while (bp < be) {
+ hval ^= (isc_uint32_t) maptolower[*bp++];
+ hval *= 16777619;
+ }
+ }
+
+ return (hval);
+}
+
+isc_uint32_t
+isc_hash_function_reverse(const void *data, size_t length,
+ isc_boolean_t case_sensitive,
+ const isc_uint32_t *previous_hashp)
+{
+ isc_uint32_t hval;
+ const unsigned char *bp;
+ const unsigned char *be;
+
+ INSIST(data == NULL || length > 0);
+ RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+ hval = ISC_UNLIKELY(previous_hashp != NULL) ?
+ *previous_hashp : fnv_offset_basis;
+
+ if (length == 0)
+ return (hval);
+
+ bp = (const unsigned char *) data;
+ be = bp + length;
+
+ /*
+ * Fowler-Noll-Vo FNV-1a hash function.
+ *
+ * NOTE: A random fnv_offset_basis is used by default to avoid
+ * collision attacks as the hash function is reversible. This
+ * makes the mapping non-deterministic, but the distribution in
+ * the domain is still uniform.
+ */
+
+ if (case_sensitive) {
+ while (be >= bp + 4) {
+ be -= 4;
+ hval ^= (isc_uint32_t) be[3];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) be[2];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) be[1];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) be[0];
+ hval *= 16777619;
+ }
+ while (--be >= bp) {
+ hval ^= (isc_uint32_t) *be;
+ hval *= 16777619;
+ }
+ } else {
+ while (be >= bp + 4) {
+ be -= 4;
+ hval ^= (isc_uint32_t) maptolower[be[3]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[be[2]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[be[1]];
+ hval *= 16777619;
+ hval ^= (isc_uint32_t) maptolower[be[0]];
+ hval *= 16777619;
+ }
+ while (--be >= bp) {
+ hval ^= (isc_uint32_t) maptolower[*be];
+ hval *= 16777619;
+ }
+ }
+
+ return (hval);
+}
diff --git a/lib/isc/hex.c b/lib/isc/hex.c
index 00903c7374cf..9e565c8a1c24 100644
--- a/lib/isc/hex.c
+++ b/lib/isc/hex.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2013-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -95,7 +95,7 @@ hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target)
static inline isc_result_t
hex_decode_char(hex_decode_ctx_t *ctx, int c) {
- char *s;
+ const char *s;
if ((s = strchr(hex, toupper(c))) == NULL)
return (ISC_R_BADHEX);
diff --git a/lib/isc/httpd.c b/lib/isc/httpd.c
index 241c1d53a8d5..b33f3577f994 100644
--- a/lib/isc/httpd.c
+++ b/lib/isc/httpd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008, 2010-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006-2008, 2010-2012, 2014-2016 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
@@ -360,6 +360,73 @@ httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) {
#define LENGTHOK(s) (httpd->recvbuf - (s) < (int)httpd->recvlen)
#define BUFLENOK(s) (httpd->recvbuf - (s) < HTTP_RECVLEN)
+/*
+ * Look for the given header in headers.
+ * If value is specified look for it terminated with a character in eov.
+ */
+static isc_boolean_t
+have_header(isc_httpd_t *httpd, const char *header, const char *value,
+ const char *eov)
+{
+ char *cr, *nl, *h;
+ size_t hlen, vlen = 0;
+
+ h = httpd->headers;
+ hlen = strlen(header);
+ if (value != NULL) {
+ INSIST(eov != NULL);
+ vlen = strlen(value);
+ }
+
+ for (;;) {
+ if (strncasecmp(h, header, hlen) != 0) {
+ /*
+ * Skip to next line;
+ */
+ cr = strchr(h, '\r');
+ if (cr != NULL && cr[1] == '\n')
+ cr++;
+ nl = strchr(h, '\n');
+
+ /* last header? */
+ h = cr;
+ if (h == NULL || (nl != NULL && nl < h))
+ h = nl;
+ if (h == NULL)
+ return (ISC_FALSE);
+ h++;
+ continue;
+ }
+
+ if (value == NULL)
+ return (ISC_TRUE);
+
+ /*
+ * Skip optional leading white space.
+ */
+ h += hlen;
+ while (*h == ' ' || *h == '\t')
+ h++;
+ /*
+ * Terminate token search on NULL or EOL.
+ */
+ while (*h != 0 && *h != '\r' && *h != '\n') {
+ if (strncasecmp(h, value, vlen) == 0)
+ if (strchr(eov, h[vlen]) != NULL)
+ return (ISC_TRUE);
+ /*
+ * Skip to next token.
+ */
+ h += strcspn(h, eov);
+ if (h[0] == '\r' && h[1] == '\n')
+ h++;
+ if (h[0] != 0)
+ h++;
+ }
+ return (ISC_FALSE);
+ }
+}
+
static isc_result_t
process_request(isc_httpd_t *httpd, int length) {
char *s;
@@ -378,15 +445,20 @@ process_request(isc_httpd_t *httpd, int length) {
* more data.
*/
s = strstr(httpd->recvbuf, "\r\n\r\n");
- delim = 1;
+ delim = 2;
if (s == NULL) {
s = strstr(httpd->recvbuf, "\n\n");
- delim = 2;
+ delim = 1;
}
if (s == NULL)
return (ISC_R_NOTFOUND);
/*
+ * NUL terminate request at the blank line.
+ */
+ s[delim] = 0;
+
+ /*
* Determine if this is a POST or GET method. Any other values will
* cause an error to be returned.
*/
@@ -444,7 +516,7 @@ process_request(isc_httpd_t *httpd, int length) {
}
httpd->url = p;
- p = s + delim;
+ p = s + 1;
s = p;
/*
@@ -459,7 +531,7 @@ process_request(isc_httpd_t *httpd, int length) {
/*
* Extract the HTTP/1.X protocol. We will bounce on anything but
- * HTTP/1.1 for now.
+ * HTTP/1.0 or HTTP/1.1 for now.
*/
while (LENGTHOK(s) && BUFLENOK(s) &&
(*s != '\n' && *s != '\r' && *s != '\0'))
@@ -468,24 +540,30 @@ process_request(isc_httpd_t *httpd, int length) {
return (ISC_R_NOTFOUND);
if (!BUFLENOK(s))
return (ISC_R_NOMEMORY);
+ /*
+ * Check that we have the expected eol delimiter.
+ */
+ if (strncmp(s, delim == 1 ? "\n" : "\r\n", delim) != 0)
+ return (ISC_R_RANGE);
*s = 0;
if ((strncmp(p, "HTTP/1.0", 8) != 0)
&& (strncmp(p, "HTTP/1.1", 8) != 0))
return (ISC_R_RANGE);
httpd->protocol = p;
- p = s + 1;
+ p = s + delim; /* skip past eol */
s = p;
httpd->headers = s;
- if (strstr(s, "Connection: close") != NULL)
+ if (have_header(httpd, "Connection:", "close", ", \t\r\n"))
httpd->flags |= HTTPD_CLOSE;
- if (strstr(s, "Host: ") != NULL)
+ if (have_header(httpd, "Host:", NULL, NULL))
httpd->flags |= HTTPD_FOUNDHOST;
if (strncmp(httpd->protocol, "HTTP/1.0", 8) == 0) {
- if (strcasestr(s, "Connection: Keep-Alive") != NULL)
+ if (have_header(httpd, "Connection:", "Keep-Alive",
+ ", \t\r\n"))
httpd->flags |= HTTPD_KEEPALIVE;
else
httpd->flags |= HTTPD_CLOSE;
@@ -838,7 +916,7 @@ isc_httpd_response(isc_httpd_t *httpd) {
return (result);
}
- sprintf(isc_buffer_used(&httpd->headerbuffer), "%s %03d %s\r\n",
+ sprintf(isc_buffer_used(&httpd->headerbuffer), "%s %03u %s\r\n",
httpd->protocol, httpd->retcode, httpd->retmsg);
isc_buffer_add(&httpd->headerbuffer, needlen);
diff --git a/lib/isc/ia64/include/isc/Makefile.in b/lib/isc/ia64/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/ia64/include/isc/Makefile.in
+++ b/lib/isc/ia64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
index 572bb3e1046b..15b55069b13b 100644
--- a/lib/isc/include/isc/Makefile.in
+++ b/lib/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2009, 2012-2015 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
@@ -17,7 +17,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
#
# Only list headers that are to be installed and are not
diff --git a/lib/isc/include/isc/assertions.h b/lib/isc/include/isc/assertions.h
index 2c81b1ae9880..ebe96922dcbe 100644
--- a/lib/isc/include/isc/assertions.h
+++ b/lib/isc/include/isc/assertions.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -83,7 +83,7 @@ isc_assertion_typetotext(isc_assertiontype_t type);
#if ISC_CHECK_REQUIRE != 0
#define ISC_REQUIRE(cond) \
- ((void) ((cond) || \
+ ((void) (ISC_LIKELY(cond) || \
((isc_assertion_failed)(__FILE__, __LINE__, \
isc_assertiontype_require, \
#cond), 0)))
@@ -93,7 +93,7 @@ isc_assertion_typetotext(isc_assertiontype_t type);
#if ISC_CHECK_ENSURE != 0
#define ISC_ENSURE(cond) \
- ((void) ((cond) || \
+ ((void) (ISC_LIKELY(cond) || \
((isc_assertion_failed)(__FILE__, __LINE__, \
isc_assertiontype_ensure, \
#cond), 0)))
@@ -103,7 +103,7 @@ isc_assertion_typetotext(isc_assertiontype_t type);
#if ISC_CHECK_INSIST != 0
#define ISC_INSIST(cond) \
- ((void) ((cond) || \
+ ((void) (ISC_LIKELY(cond) || \
((isc_assertion_failed)(__FILE__, __LINE__, \
isc_assertiontype_insist, \
#cond), 0)))
@@ -113,7 +113,7 @@ isc_assertion_typetotext(isc_assertiontype_t type);
#if ISC_CHECK_INVARIANT != 0
#define ISC_INVARIANT(cond) \
- ((void) ((cond) || \
+ ((void) (ISC_LIKELY(cond) || \
((isc_assertion_failed)(__FILE__, __LINE__, \
isc_assertiontype_invariant, \
#cond), 0)))
diff --git a/lib/isc/include/isc/error.h b/lib/isc/include/isc/error.h
index e0cdfa83e7cb..b6cac178e3d0 100644
--- a/lib/isc/include/isc/error.h
+++ b/lib/isc/include/isc/error.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -55,7 +55,7 @@ void
isc_error_runtimecheck(const char *, int, const char *);
#define ISC_ERROR_RUNTIMECHECK(cond) \
- ((void) ((cond) || \
+ ((void) (ISC_LIKELY(cond) || \
((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0)))
ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
index 7137410b613d..97e4fd323e02 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-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -312,8 +312,8 @@ isc_file_safecreate(const char *filename, FILE **fp);
*/
isc_result_t
-isc_file_splitpath(isc_mem_t *mctx, char *path,
- char **dirname, char **basename);
+isc_file_splitpath(isc_mem_t *mctx, const char *path,
+ char **dirname, char const **basename);
/*%<
* Split a path into dirname and basename. If 'path' contains no slash
* (or, on windows, backslash), then '*dirname' is set to ".".
diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h
index 0bfe936d7f95..46cdf78b4923 100644
--- a/lib/isc/include/isc/hash.h
+++ b/lib/isc/include/isc/hash.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2013, 2015, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -180,6 +180,45 @@ isc_hash_calc(const unsigned char *key, unsigned int keylen,
*/
/*@}*/
+isc_uint32_t
+isc_hash_function(const void *data, size_t length,
+ isc_boolean_t case_sensitive,
+ const isc_uint32_t *previous_hashp);
+isc_uint32_t
+isc_hash_function_reverse(const void *data, size_t length,
+ isc_boolean_t case_sensitive,
+ const isc_uint32_t *previous_hashp);
+/*!<
+ * \brief Calculate a hash over data.
+ *
+ * This hash function is useful for hashtables. The hash function is
+ * opaque and not important to the caller. The returned hash values are
+ * non-deterministic and will have different mapping every time a
+ * process using this library is run, but will have uniform
+ * distribution.
+ *
+ * isc_hash_function() calculates the hash from start to end over the
+ * input data. isc_hash_function_reverse() calculates the hash from the
+ * end to the start over the input data. The difference in order is
+ * useful in incremental hashing; for example, a previously hashed
+ * value for 'com' can be used as input when hashing 'example.com'.
+ *
+ * This is a new variant of isc_hash_calc() and will supercede
+ * isc_hash_calc() eventually.
+ *
+ * 'data' is the data to be hashed.
+ *
+ * 'length' is the size of the data to be hashed.
+ *
+ * 'case_sensitive' specifies whether the hash key should be treated as
+ * case_sensitive values. It should typically be ISC_FALSE if the hash key
+ * is a DNS name.
+ *
+ * 'previous_hashp' is a pointer to a previous hash value returned by
+ * this function. It can be used to perform incremental hashing. NULL
+ * must be passed during first calls.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_HASH_H */
diff --git a/lib/isc/include/isc/magic.h b/lib/isc/include/isc/magic.h
index 073de90dcc92..679d9d9233fb 100644
--- a/lib/isc/include/isc/magic.h
+++ b/lib/isc/include/isc/magic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -20,6 +20,8 @@
#ifndef ISC_MAGIC_H
#define ISC_MAGIC_H 1
+#include <isc/util.h>
+
/*! \file isc/magic.h */
typedef struct {
@@ -33,8 +35,8 @@ typedef struct {
* The intent of this is to allow magic numbers to be checked even though
* the object is otherwise opaque.
*/
-#define ISC_MAGIC_VALID(a,b) (((a) != NULL) && \
- (((const isc__magic_t *)(a))->magic == (b)))
+#define ISC_MAGIC_VALID(a,b) (ISC_LIKELY((a) != NULL) && \
+ ISC_LIKELY(((const isc__magic_t *)(a))->magic == (b)))
#define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
diff --git a/lib/isc/include/isc/netaddr.h b/lib/isc/include/isc/netaddr.h
index 954d77019b69..140d11826dd9 100644
--- a/lib/isc/include/isc/netaddr.h
+++ b/lib/isc/include/isc/netaddr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -155,6 +155,12 @@ isc_netaddr_issitelocal(isc_netaddr_t *na);
* Returns #ISC_TRUE if the address is a site local address.
*/
+isc_boolean_t
+isc_netaddr_isnetzero(isc_netaddr_t *na);
+/*%<
+ * Returns #ISC_TRUE if the address is in net zero.
+ */
+
void
isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s);
/*%<
diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in
index 667a1454a4cd..ae2af287c338 100644
--- a/lib/isc/include/isc/platform.h.in
+++ b/lib/isc/include/isc/platform.h.in
@@ -288,12 +288,18 @@
@ISC_PLATFORM_HAVEXADDQ@
/*
- * If the "atomic swap" operation is available on this architecture,
- * ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
+ * If the 32-bit "atomic swap" operation is available on this
+ * architecture, ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
*/
@ISC_PLATFORM_HAVEATOMICSTORE@
/*
+ * If the 64-bit "atomic swap" operation is available on this
+ * architecture, ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
+ */
+@ISC_PLATFORM_HAVEATOMICSTOREQ@
+
+/*
* If the "compare-and-exchange" operation is available on this architecture,
* ISC_PLATFORM_HAVECMPXCHG will be defined.
*/
diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h
index ed1bc63e7364..ce881e1a2388 100644
--- a/lib/isc/include/isc/result.h
+++ b/lib/isc/include/isc/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2012, 2014, 2015 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
@@ -89,9 +89,10 @@
#define ISC_R_BADBASE32 60 /*%< bad base32 encoding */
#define ISC_R_UNSET 61 /*%< unset */
#define ISC_R_MULTIPLE 62 /*%< multiple */
+#define ISC_R_WOULDBLOCK 63 /*%< would block */
/*% Not a result code: the number of results. */
-#define ISC_R_NRESULTS 63
+#define ISC_R_NRESULTS 64
ISC_LANG_BEGINDECLS
diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h
index 4d811dd64971..5dfc3d23f512 100644
--- a/lib/isc/include/isc/sockaddr.h
+++ b/lib/isc/include/isc/sockaddr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2012, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -220,6 +220,12 @@ isc_sockaddr_issitelocal(const isc_sockaddr_t *sa);
* Returns ISC_TRUE if the address is a sitelocal address.
*/
+isc_boolean_t
+isc_sockaddr_isnetzero(const isc_sockaddr_t *sa);
+/*%<
+ * Returns ISC_TRUE if the address is in net zero.
+ */
+
isc_result_t
isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path);
/*
diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
index 97e2f7605b9c..0ee305c894b4 100644
--- a/lib/isc/include/isc/socket.h
+++ b/lib/isc/include/isc/socket.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2014, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -370,7 +370,8 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
*
* Note:
*
- *\li 'fd' is the already-opened file descriptor.
+ *\li 'fd' is the already-opened file descriptor (must be less
+ * than maxsockets).
*\li This function is not available on Windows.
*\li The callback function is called "in-line" - this means the function
* needs to return as fast as possible, as all other I/O will be suspended
@@ -394,6 +395,7 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
*\li #ISC_R_NOMEMORY
*\li #ISC_R_NORESOURCES
*\li #ISC_R_UNEXPECTED
+ *\li #ISC_R_RANGE
*/
isc_result_t
diff --git a/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h
index 6baf786bdeab..fc2e1882641a 100644
--- a/lib/isc/include/isc/util.h
+++ b/lib/isc/include/isc/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010-2012, 2015 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010-2012, 2015, 2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -206,6 +206,17 @@
#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln)
#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link)
+/*%
+ * Performance
+ */
+#ifdef HAVE_BUILTIN_EXPECT
+#define ISC_LIKELY(x) __builtin_expect(!!(x), 1)
+#define ISC_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define ISC_LIKELY(x) (x)
+#define ISC_UNLIKELY(x) (x)
+#endif
+
/*
* Assertions
*/
diff --git a/lib/isc/md5.c b/lib/isc/md5.c
index 579d61c20b2a..55d56195f48e 100644
--- a/lib/isc/md5.c
+++ b/lib/isc/md5.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -57,6 +57,8 @@ isc_md5_invalidate(isc_md5_t *ctx) {
void
isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
+ if (len == 0U)
+ return;
RUNTIME_CHECK(EVP_DigestUpdate(ctx,
(const void *) buf,
(size_t) len) == 1);
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index 854425750bcd..dfa5e572770b 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2012-2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1987,53 +1987,43 @@ isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
/*
* Don't let the caller go over quota
*/
- if (mpctx->allocated >= mpctx->maxalloc) {
+ if (ISC_UNLIKELY(mpctx->allocated >= mpctx->maxalloc)) {
item = NULL;
goto out;
}
- /*
- * if we have a free list item, return the first here
- */
- item = mpctx->items;
- if (item != NULL) {
- mpctx->items = item->next;
- INSIST(mpctx->freecount > 0);
- mpctx->freecount--;
- mpctx->gets++;
- mpctx->allocated++;
- goto out;
- }
-
- /*
- * We need to dip into the well. Lock the memory context here and
- * fill up our free list.
- */
- MCTXLOCK(mctx, &mctx->lock);
- for (i = 0; i < mpctx->fillcount; i++) {
- if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
- item = mem_getunlocked(mctx, mpctx->size);
- } else {
- item = mem_get(mctx, mpctx->size);
- if (item != NULL)
- mem_getstats(mctx, mpctx->size);
+ if (ISC_UNLIKELY(mpctx->items == NULL)) {
+ /*
+ * We need to dip into the well. Lock the memory context
+ * here and fill up our free list.
+ */
+ MCTXLOCK(mctx, &mctx->lock);
+ for (i = 0; i < mpctx->fillcount; i++) {
+ if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
+ item = mem_getunlocked(mctx, mpctx->size);
+ } else {
+ item = mem_get(mctx, mpctx->size);
+ if (item != NULL)
+ mem_getstats(mctx, mpctx->size);
+ }
+ if (ISC_UNLIKELY(item == NULL))
+ break;
+ item->next = mpctx->items;
+ mpctx->items = item;
+ mpctx->freecount++;
}
- if (item == NULL)
- break;
- item->next = mpctx->items;
- mpctx->items = item;
- mpctx->freecount++;
+ MCTXUNLOCK(mctx, &mctx->lock);
}
- MCTXUNLOCK(mctx, &mctx->lock);
/*
* If we didn't get any items, return NULL.
*/
item = mpctx->items;
- if (item == NULL)
+ if (ISC_UNLIKELY(item == NULL))
goto out;
mpctx->items = item->next;
+ INSIST(mpctx->freecount > 0);
mpctx->freecount--;
mpctx->gets++;
mpctx->allocated++;
diff --git a/lib/isc/mips/include/isc/Makefile.in b/lib/isc/mips/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/mips/include/isc/Makefile.in
+++ b/lib/isc/mips/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/netaddr.c b/lib/isc/netaddr.c
index dcbfba42eae8..2178c7a2a7b5 100644
--- a/lib/isc/netaddr.c
+++ b/lib/isc/netaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2010-2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2010-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -419,6 +419,22 @@ isc_netaddr_issitelocal(isc_netaddr_t *na) {
}
}
+#ifndef IN_ZERONET
+#define IN_ZERONET(x) (((x) & htonl(0xff000000U)) == 0)
+#endif
+
+isc_boolean_t
+isc_netaddr_isnetzero(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_TF(IN_ZERONET(na->type.in.s_addr)));
+ case AF_INET6:
+ return (ISC_FALSE);
+ default:
+ return (ISC_FALSE);
+ }
+}
+
void
isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
isc_netaddr_t *src;
diff --git a/lib/isc/noatomic/include/isc/Makefile.in b/lib/isc/noatomic/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/noatomic/include/isc/Makefile.in
+++ b/lib/isc/noatomic/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/nothreads/include/isc/Makefile.in b/lib/isc/nothreads/include/isc/Makefile.in
index a2c347eaa253..f32180f3a783 100644
--- a/lib/isc/nothreads/include/isc/Makefile.in
+++ b/lib/isc/nothreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012, 2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -19,7 +19,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = condition.h mutex.h once.h thread.h
diff --git a/lib/isc/powerpc/include/isc/Makefile.in b/lib/isc/powerpc/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/powerpc/include/isc/Makefile.in
+++ b/lib/isc/powerpc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/pthreads/include/isc/Makefile.in b/lib/isc/pthreads/include/isc/Makefile.in
index 7cadcf4b6f3d..68e6c76b8d6b 100644
--- a/lib/isc/pthreads/include/isc/Makefile.in
+++ b/lib/isc/pthreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012, 2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -19,7 +19,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = condition.h mutex.h once.h thread.h
diff --git a/lib/isc/result.c b/lib/isc/result.c
index 6cbd8b4722a1..27927e8f25d2 100644
--- a/lib/isc/result.c
+++ b/lib/isc/result.c
@@ -104,6 +104,7 @@ static const char *description[ISC_R_NRESULTS] = {
"bad base32 encoding", /*%< 60 */
"unset", /*%< 61 */
"multiple", /*%< 62 */
+ "would block", /*%< 63 */
};
#define ISC_RESULT_RESULTSET 2
diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c
index cee6d700c02e..195f1c1c739d 100644
--- a/lib/isc/sockaddr.c
+++ b/lib/isc/sockaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010-2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -205,7 +205,6 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
unsigned int length = 0;
const unsigned char *s = NULL;
unsigned int h = 0;
- unsigned int g;
unsigned int p = 0;
const struct in6_addr *in6;
@@ -239,12 +238,9 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
p = 0;
}
- h = isc_hash_calc(s, length, ISC_TRUE);
- if (!address_only) {
- g = isc_hash_calc((const unsigned char *)&p, sizeof(p),
- ISC_TRUE);
- h = h ^ g; /* XXX: we should concatenate h and p first */
- }
+ h = isc_hash_function(s, length, ISC_TRUE, NULL);
+ if (!address_only)
+ h = isc_hash_function(&p, sizeof(p), ISC_TRUE, &h);
return (h);
}
@@ -368,7 +364,7 @@ isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) {
void
isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
- in_port_t port)
+ in_port_t port)
{
memset(sockaddr, 0, sizeof(*sockaddr));
sockaddr->type.sin.sin_family = na->family;
@@ -483,6 +479,17 @@ isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) {
return (ISC_FALSE);
}
+isc_boolean_t
+isc_sockaddr_isnetzero(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_isnetzero(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
isc_result_t
isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) {
#ifdef ISC_PLATFORM_HAVESYSUNH
diff --git a/lib/isc/sparc64/include/isc/Makefile.in b/lib/isc/sparc64/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/sparc64/include/isc/Makefile.in
+++ b/lib/isc/sparc64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/stats.c b/lib/isc/stats.c
index 03d2a8a7d103..368dadfc323e 100644
--- a/lib/isc/stats.c
+++ b/lib/isc/stats.c
@@ -35,13 +35,45 @@
#define ISC_STATS_MAGIC ISC_MAGIC('S', 't', 'a', 't')
#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC)
-#ifndef ISC_STATS_USEMULTIFIELDS
-#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEXADD) && !defined(ISC_PLATFORM_HAVEXADDQ)
+/*%
+ * Local macro confirming prescence of 64-bit
+ * increment and store operations, just to make
+ * the later macros simpler
+ */
+#if defined(ISC_PLATFORM_HAVEXADDQ) && defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
+#define ISC_STATS_HAVEATOMICQ 1
+#else
+#define ISC_STATS_HAVEATOMICQ 0
+#endif
+
+/*%
+ * Only lock the counters if 64-bit atomic operations are
+ * not available but cheap atomic lock operations are.
+ * On a modern 64-bit system this should never be the case.
+ *
+ * Normal locks are too expensive to be used whenever a counter
+ * is updated.
+ */
+#if !ISC_STATS_HAVEATOMICQ && defined(ISC_RWLOCK_HAVEATOMIC)
+#define ISC_STATS_LOCKCOUNTERS 1
+#else
+#define ISC_STATS_LOCKCOUNTERS 0
+#endif
+
+/*%
+ * If 64-bit atomic operations are not available but
+ * 32-bit operations are then split the counter into two,
+ * using the atomic operations to try to ensure that any carry
+ * from the low word is correctly carried into the high word.
+ *
+ * Otherwise, just rely on standard 64-bit data types
+ * and operations
+ */
+#if !ISC_STATS_HAVEATOMICQ && defined(ISC_PLATFORM_HAVEXADD)
#define ISC_STATS_USEMULTIFIELDS 1
#else
#define ISC_STATS_USEMULTIFIELDS 0
#endif
-#endif /* ISC_STATS_USEMULTIFIELDS */
#if ISC_STATS_USEMULTIFIELDS
typedef struct {
@@ -65,7 +97,7 @@ struct isc_stats {
* Locked by counterlock or unlocked if efficient rwlock is not
* available.
*/
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_t counterlock;
#endif
isc_stat_t *counters;
@@ -111,7 +143,7 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
goto clean_counters;
}
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
result = isc_rwlock_init(&stats->counterlock, 0, 0);
if (result != ISC_R_SUCCESS)
goto clean_copiedcounters;
@@ -131,7 +163,7 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
clean_counters:
isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters);
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
clean_copiedcounters:
isc_mem_put(mctx, stats->copiedcounters,
sizeof(isc_stat_t) * ncounters);
@@ -177,7 +209,7 @@ isc_stats_detach(isc_stats_t **statsp) {
sizeof(isc_stat_t) * stats->ncounters);
UNLOCK(&stats->lock);
DESTROYLOCK(&stats->lock);
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_destroy(&stats->counterlock);
#endif
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
@@ -198,7 +230,7 @@ static inline void
incrementcounter(isc_stats_t *stats, int counter) {
isc_int32_t prev;
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
/*
* We use a "read" lock to prevent other threads from reading the
* counter while we "writing" a counter field. The write access itself
@@ -219,7 +251,7 @@ incrementcounter(isc_stats_t *stats, int counter) {
*/
if (prev == (isc_int32_t)0xffffffff)
isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi, 1);
-#elif defined(ISC_PLATFORM_HAVEXADDQ)
+#elif ISC_STATS_HAVEATOMICQ
UNUSED(prev);
isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], 1);
#else
@@ -227,7 +259,7 @@ incrementcounter(isc_stats_t *stats, int counter) {
stats->counters[counter]++;
#endif
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
#endif
}
@@ -236,7 +268,7 @@ static inline void
decrementcounter(isc_stats_t *stats, int counter) {
isc_int32_t prev;
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read);
#endif
@@ -245,7 +277,7 @@ decrementcounter(isc_stats_t *stats, int counter) {
if (prev == 0)
isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi,
-1);
-#elif defined(ISC_PLATFORM_HAVEXADDQ)
+#elif ISC_STATS_HAVEATOMICQ
UNUSED(prev);
isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], -1);
#else
@@ -253,7 +285,7 @@ decrementcounter(isc_stats_t *stats, int counter) {
stats->counters[counter]--;
#endif
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
#endif
}
@@ -262,7 +294,7 @@ static void
copy_counters(isc_stats_t *stats) {
int i;
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
/*
* We use a "write" lock before "reading" the statistics counters as
* an exclusive lock.
@@ -270,19 +302,21 @@ copy_counters(isc_stats_t *stats) {
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
#endif
-#if ISC_STATS_USEMULTIFIELDS
for (i = 0; i < stats->ncounters; i++) {
+#if ISC_STATS_USEMULTIFIELDS
stats->copiedcounters[i] =
- (isc_uint64_t)(stats->counters[i].hi) << 32 |
- stats->counters[i].lo;
- }
+ (isc_uint64_t)(stats->counters[i].hi) << 32 |
+ stats->counters[i].lo;
+#elif ISC_STATS_HAVEATOMICQ
+ /* use xaddq(..., 0) as an atomic load */
+ stats->copiedcounters[i] =
+ (isc_uint64_t)isc_atomic_xaddq((isc_int64_t *)&stats->counters[i], 0);
#else
- UNUSED(i);
- memmove(stats->copiedcounters, stats->counters,
- stats->ncounters * sizeof(isc_stat_t));
+ stats->copiedcounters[i] = stats->counters[i];
#endif
+ }
-#ifdef ISC_RWLOCK_USEATOMIC
+#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
}
diff --git a/lib/isc/string.c b/lib/isc/string.c
index 56ec444bffaa..04a25943734d 100644
--- a/lib/isc/string.c
+++ b/lib/isc/string.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2011, 2012, 2014, 2015 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
@@ -56,14 +56,14 @@
#include <isc/string.h>
#include <isc/util.h>
-static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
+static const char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
isc_uint64_t
isc_string_touint64(char *source, char **end, int base) {
isc_uint64_t tmp;
isc_uint64_t overflow;
char *s = source;
- char *o;
+ const char *o;
char c;
if ((base < 0) || (base == 1) || (base > 36)) {
diff --git a/lib/isc/task.c b/lib/isc/task.c
index 3503801e4517..81785e9a835b 100644
--- a/lib/isc/task.c
+++ b/lib/isc/task.c
@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id$ */
-
/*! \file
* \author Principal Author: Bob Halley
*/
@@ -1638,11 +1636,11 @@ isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
ISC_TASKFUNC_SCOPE void
isc__taskmgr_pause(isc_taskmgr_t *manager0) {
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
+ manager->pause_requested = ISC_TRUE;
LOCK(&manager->lock);
while (manager->tasks_running > 0) {
WAIT(&manager->paused, &manager->lock);
}
- manager->pause_requested = ISC_TRUE;
UNLOCK(&manager->lock);
}
diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c
index c2abd440e18c..3fc2a29125c4 100644
--- a/lib/isc/unix/file.c
+++ b/lib/isc/unix/file.c
@@ -204,8 +204,9 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
isc_result_t
isc_file_template(const char *path, const char *templet, char *buf,
- size_t buflen) {
- char *s;
+ size_t buflen)
+{
+ const char *s;
REQUIRE(path != NULL);
REQUIRE(templet != NULL);
@@ -262,7 +263,7 @@ isc_file_renameunique(const char *file, char *templet) {
if (errno != EEXIST)
return (isc__errno2result(errno));
for (cp = x;;) {
- char *t;
+ const char *t;
if (*cp == '\0')
return (ISC_R_FAILURE);
t = strchr(alphnum, *cp);
@@ -461,7 +462,7 @@ isc_file_ischdiridempotent(const char *filename) {
const char *
isc_file_basename(const char *filename) {
- char *s;
+ const char *s;
REQUIRE(filename != NULL);
@@ -579,9 +580,11 @@ isc_file_safecreate(const char *filename, FILE **fp) {
}
isc_result_t
-isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
+isc_file_splitpath(isc_mem_t *mctx, const char *path, char **dirname,
+ char const **basename)
{
- char *dir, *file, *slash;
+ char *dir;
+ const char *file, *slash;
if (path == NULL)
return (ISC_R_INVALIDFILE);
diff --git a/lib/isc/unix/include/isc/Makefile.in b/lib/isc/unix/include/isc/Makefile.in
index 9cd96d71b750..f37036ac10ff 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-2014 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012-2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -19,7 +19,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = dir.h int.h keyboard.h net.h netdb.h offset.h stat.h \
stdtime.h strerror.h syslog.h time.h
diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c
index c811d1ba4194..7ed73aad5b4f 100644
--- a/lib/isc/unix/net.c
+++ b/lib/isc/unix/net.c
@@ -103,10 +103,10 @@ const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
# if defined(WANT_IPV6)
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
-# endif
-# if defined(ISC_PLATFORM_HAVEIN6PKTINFO)
+# if defined(ISC_PLATFORM_HAVEIN6PKTINFO)
static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
+# endif
# endif
#endif /* ISC_PLATFORM_HAVEIPV6 */
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 5e6320d821c6..42fc47f6deaa 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -394,6 +394,9 @@ struct isc__socketmgr {
/* Locked by fdlock. */
isc__socket_t **fds;
int *fdstate;
+#if defined(USE_EPOLL)
+ uint32_t *epoll_events;
+#endif
#ifdef USE_DEVPOLL
pollinfo_t *fdpollinfo;
#endif
@@ -835,15 +838,27 @@ watch_fd(isc__socketmgr_t *manager, int fd, int msg) {
return (result);
#elif defined(USE_EPOLL)
struct epoll_event event;
+ uint32_t oldevents;
+ int ret;
+ int op;
+ oldevents = manager->epoll_events[fd];
if (msg == SELECT_POKE_READ)
- event.events = EPOLLIN;
+ manager->epoll_events[fd] |= EPOLLIN;
else
- event.events = EPOLLOUT;
+ manager->epoll_events[fd] |= EPOLLOUT;
+
+ event.events = manager->epoll_events[fd];
memset(&event.data, 0, sizeof(event.data));
event.data.fd = fd;
- if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1 &&
- errno != EEXIST) {
+
+ op = (oldevents == 0U) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
+ ret = epoll_ctl(manager->epoll_fd, op, fd, &event);
+ if (ret == -1) {
+ if (errno == EEXIST)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "epoll_ctl(ADD/MOD) returned "
+ "EEXIST for fd %d", fd);
result = isc__errno2result(errno);
}
@@ -903,15 +918,21 @@ unwatch_fd(isc__socketmgr_t *manager, int fd, int msg) {
return (result);
#elif defined(USE_EPOLL)
struct epoll_event event;
+ int ret;
+ int op;
if (msg == SELECT_POKE_READ)
- event.events = EPOLLIN;
+ manager->epoll_events[fd] &= ~(EPOLLIN);
else
- event.events = EPOLLOUT;
+ manager->epoll_events[fd] &= ~(EPOLLOUT);
+
+ event.events = manager->epoll_events[fd];
memset(&event.data, 0, sizeof(event.data));
event.data.fd = fd;
- if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_DEL, fd, &event) == -1 &&
- errno != ENOENT) {
+
+ op = (event.events == 0U) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
+ ret = epoll_ctl(manager->epoll_fd, op, fd, &event);
+ if (ret == -1 && errno != ENOENT) {
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -1553,15 +1574,19 @@ build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev,
msg->msg_iovlen = iovcount;
#ifdef ISC_NET_BSD44MSGHDR
- msg->msg_control = NULL;
- msg->msg_controllen = 0;
- msg->msg_flags = 0;
#if defined(USE_CMSG)
if (sock->type == isc_sockettype_udp) {
msg->msg_control = sock->recvcmsgbuf;
msg->msg_controllen = sock->recvcmsgbuflen;
+ } else {
+ msg->msg_control = NULL;
+ msg->msg_controllen = 0;
}
+#else
+ msg->msg_control = NULL;
+ msg->msg_controllen = 0;
#endif /* USE_CMSG */
+ msg->msg_flags = 0;
#else /* ISC_NET_BSD44MSGHDR */
msg->msg_accrights = NULL;
msg->msg_accrightslen = 0;
@@ -1872,8 +1897,11 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
if (send_errno == EINTR && ++attempts < NRETRIES)
goto resend;
- if (SOFT_ERROR(send_errno))
+ if (SOFT_ERROR(send_errno)) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ dev->result = ISC_R_WOULDBLOCK;
return (DOIO_SOFT);
+ }
#define SOFT_OR_HARD(_system, _isc) \
if (send_errno == _system) { \
@@ -2035,7 +2063,7 @@ destroy(isc__socket_t **sockp) {
INSIST(ISC_LIST_EMPTY(sock->recv_list));
INSIST(ISC_LIST_EMPTY(sock->send_list));
INSIST(sock->connect_ev == NULL);
- REQUIRE(sock->fd == -1 || sock->fd < (int)manager->maxsocks);
+ INSIST(sock->fd >= -1 && sock->fd < (int)manager->maxsocks);
if (sock->fd >= 0) {
fd = sock->fd;
@@ -2192,8 +2220,8 @@ static void
free_socket(isc__socket_t **socketp) {
isc__socket_t *sock = *socketp;
- INSIST(sock->references == 0);
INSIST(VALID_SOCKET(sock));
+ INSIST(sock->references == 0);
INSIST(!sock->connecting);
INSIST(!sock->pending_recv);
INSIST(!sock->pending_send);
@@ -2633,6 +2661,9 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
LOCK(&manager->fdlock[lockid]);
manager->fds[sock->fd] = sock;
manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[sock->fd] = 0;
+#endif
#ifdef USE_DEVPOLL
INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 &&
sock->manager->fdpollinfo[sock->fd].want_write == 0);
@@ -2710,6 +2741,9 @@ isc__socket_open(isc_socket_t *sock0) {
LOCK(&sock->manager->fdlock[lockid]);
sock->manager->fds[sock->fd] = sock;
sock->manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ sock->manager->epoll_events[sock->fd] = 0;
+#endif
#ifdef USE_DEVPOLL
INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 &&
sock->manager->fdpollinfo[sock->fd].want_write == 0);
@@ -2747,6 +2781,9 @@ isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
+ if (fd < 0 || (unsigned int)fd >= manager->maxsocks)
+ return (ISC_R_RANGE);
+
result = allocate_socket(manager, isc_sockettype_fdwatch, &sock);
if (result != ISC_R_SUCCESS)
return (result);
@@ -2771,6 +2808,9 @@ isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
LOCK(&manager->fdlock[lockid]);
manager->fds[sock->fd] = sock;
manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[sock->fd] = 0;
+#endif
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
@@ -3310,6 +3350,9 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
LOCK(&manager->fdlock[lockid]);
manager->fds[fd] = NEWCONNSOCK(dev);
manager->fdstate[fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[fd] = 0;
+#endif
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
@@ -4260,6 +4303,15 @@ isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
result = ISC_R_NOMEMORY;
goto free_manager;
}
+#if defined(USE_EPOLL)
+ manager->epoll_events = isc_mem_get(mctx, (manager->maxsocks *
+ sizeof(uint32_t)));
+ if (manager->epoll_events == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto free_manager;
+ }
+ memset(manager->epoll_events, 0, manager->maxsocks * sizeof(uint32_t));
+#endif
manager->stats = NULL;
manager->common.methods = &socketmgrmethods;
@@ -4329,7 +4381,9 @@ isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
result = setup_watcher(mctx, manager);
if (result != ISC_R_SUCCESS)
goto cleanup;
+
memset(manager->fdstate, 0, manager->maxsocks * sizeof(int));
+
#ifdef USE_WATCHER_THREAD
/*
* Start up the select/poll thread.
@@ -4378,6 +4432,12 @@ free_manager:
isc_mem_put(mctx, manager->fdlock,
FDLOCK_COUNT * sizeof(isc_mutex_t));
}
+#if defined(USE_EPOLL)
+ if (manager->epoll_events != NULL) {
+ isc_mem_put(mctx, manager->epoll_events,
+ manager->maxsocks * sizeof(uint32_t));
+ }
+#endif
if (manager->fdstate != NULL) {
isc_mem_put(mctx, manager->fdstate,
manager->maxsocks * sizeof(int));
@@ -4493,6 +4553,10 @@ isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */
(void)close(i);
+#if defined(USE_EPOLL)
+ isc_mem_put(manager->mctx, manager->epoll_events,
+ manager->maxsocks * sizeof(uint32_t));
+#endif
isc_mem_put(manager->mctx, manager->fds,
manager->maxsocks * sizeof(isc__socket_t *));
isc_mem_put(manager->mctx, manager->fdstate,
diff --git a/lib/isc/x86_32/include/isc/Makefile.in b/lib/isc/x86_32/include/isc/Makefile.in
index 4927e210f38e..df7561585b0a 100644
--- a/lib/isc/x86_32/include/isc/Makefile.in
+++ b/lib/isc/x86_32/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/x86_32/include/isc/atomic.h b/lib/isc/x86_32/include/isc/atomic.h
index bf2148cb33f5..36088e4d53ae 100644
--- a/lib/isc/x86_32/include/isc/atomic.h
+++ b/lib/isc/x86_32/include/isc/atomic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005, 2007, 2008, 2015 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
@@ -62,7 +62,7 @@ isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
#endif /* ISC_PLATFORM_HAVEXADDQ */
/*
- * This routine atomically stores the value 'val' in 'p'.
+ * This routine atomically stores the value 'val' in 'p' (32-bit version).
*/
static __inline__ void
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
@@ -81,6 +81,28 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
: "memory");
}
+#ifdef ISC_PLATFORM_HAVEATOMICSTOREQ
+/*
+ * This routine atomically stores the value 'val' in 'p' (64-bit version).
+ */
+static __inline__ void
+isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
+ __asm__ volatile(
+#ifdef ISC_PLATFORM_USETHREADS
+ /*
+ * xchg should automatically lock memory, but we add it
+ * explicitly just in case (it at least doesn't harm)
+ */
+ "lock;"
+#endif
+
+ "xchgq %1, %0"
+ :
+ : "r"(val), "m"(*p)
+ : "memory");
+}
+#endif /* ISC_PLATFORM_HAVEATOMICSTOREQ */
+
/*
* This routine atomically replaces the value in 'p' with 'val', if the
* original value is equal to 'cmpval'. The original value is returned in any
diff --git a/lib/isc/x86_64/include/isc/Makefile.in b/lib/isc/x86_64/include/isc/Makefile.in
index 9a988bb76159..74b7f95cf3ec 100644
--- a/lib/isc/x86_64/include/isc/Makefile.in
+++ b/lib/isc/x86_64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012, 2015 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
@@ -18,7 +18,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-@BIND9_VERSION@
+VERSION=@BIND9_VERSION@
HEADERS = atomic.h
diff --git a/lib/isc/x86_64/include/isc/atomic.h b/lib/isc/x86_64/include/isc/atomic.h
index f57bd2a78672..431600b73c33 100644
--- a/lib/isc/x86_64/include/isc/atomic.h
+++ b/lib/isc/x86_64/include/isc/atomic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005, 2007, 2008, 2015, 2016 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
@@ -87,12 +87,26 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
"lock;"
#endif
"xchgl (%rax), %edx\n"
- /*
- * XXX: assume %rax will be used as the return value.
- */
);
}
+#ifdef ISC_PLATFORM_HAVEATOMICSTOREQ
+static void
+isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
+ UNUSED(p);
+ UNUSED(val);
+
+ __asm (
+ "movq %rdi, %rax\n"
+ "movq %rsi, %rdx\n"
+#ifdef ISC_PLATFORM_USETHREADS
+ "lock;"
+#endif
+ "xchgq (%rax), %rdx\n"
+ );
+}
+#endif
+
static isc_int32_t
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
UNUSED(p);
@@ -100,6 +114,9 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
UNUSED(val);
__asm (
+ /*
+ * p is %rdi, cmpval is %esi, val is %edx.
+ */
"movl %edx, %ecx\n"
"movl %esi, %eax\n"
"movq %rdi, %rdx\n"
@@ -108,8 +125,12 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
"lock;"
#endif
/*
- * If (%rdi) == %eax then (%rdi) := %edx.
- * %eax is set to old (%ecx), which will be the return value.
+ * If [%rdi] == %eax then [%rdi] := %ecx (equal to %edx
+ * from above), and %eax is untouched (equal to %esi)
+ * from above.
+ *
+ * Else if [%rdi] != %eax then [%rdi] := [%rdi]
+ * (rewritten in write cycle) and %eax := [%rdi].
*/
"cmpxchgl %ecx, (%rdx)"
);