summaryrefslogtreecommitdiff
path: root/dist/bind/lib/isc
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>2004-11-06 23:53:21 +0000
committerchristos <christos@NetBSD.org>2004-11-06 23:53:21 +0000
commitdfd98c8a16d53dff0d1bdca29bcddc6571054129 (patch)
tree24f3891f470a8e79f037a71c4b43266f23767859 /dist/bind/lib/isc
parentaefec4290d9fd9e83eaf8b2b4ada33ff37ecaedb (diff)
Import bind-9.3.0
Diffstat (limited to 'dist/bind/lib/isc')
-rw-r--r--dist/bind/lib/isc/Makefile.in4
-rw-r--r--dist/bind/lib/isc/api2
-rw-r--r--dist/bind/lib/isc/include/isc/result.h7
-rw-r--r--dist/bind/lib/isc/inet_ntop.c5
-rw-r--r--dist/bind/lib/isc/lex.c5
-rw-r--r--dist/bind/lib/isc/log.c27
-rw-r--r--dist/bind/lib/isc/netaddr.c7
-rw-r--r--dist/bind/lib/isc/result.c9
-rw-r--r--dist/bind/lib/isc/sockaddr.c12
-rw-r--r--dist/bind/lib/isc/unix/Makefile.in5
-rw-r--r--dist/bind/lib/isc/unix/ifiter_ioctl.c39
-rw-r--r--dist/bind/lib/isc/unix/interfaceiter.c10
-rw-r--r--dist/bind/lib/isc/unix/socket.c10
-rw-r--r--dist/bind/lib/isc/win32/socket.c437
14 files changed, 331 insertions, 248 deletions
diff --git a/dist/bind/lib/isc/Makefile.in b/dist/bind/lib/isc/Makefile.in
index 0c0c65df60c..c7bb871674d 100644
--- a/dist/bind/lib/isc/Makefile.in
+++ b/dist/bind/lib/isc/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# Id: Makefile.in,v 1.71.2.2.2.7 2004/03/08 09:04:48 marka Exp
+# Id: Makefile.in,v 1.71.2.2.2.8 2004/07/20 07:01:58 marka Exp
srcdir = @srcdir@
VPATH = @srcdir@
@@ -94,7 +94,7 @@ libisc.@SA@: ${OBJS}
libisc.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
- ${CC} ${ALL_CFLAGS} -o libisc.la -rpath ${libdir} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
${OBJS} ${LIBS}
diff --git a/dist/bind/lib/isc/api b/dist/bind/lib/isc/api
index 75a502768ef..9d7fc51c828 100644
--- a/dist/bind/lib/isc/api
+++ b/dist/bind/lib/isc/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 10
-LIBREVISION = 0
+LIBREVISION = 4
LIBAGE = 1
diff --git a/dist/bind/lib/isc/include/isc/result.h b/dist/bind/lib/isc/include/isc/result.h
index 431c57e643e..33e4ef70309 100644
--- a/dist/bind/lib/isc/include/isc/result.h
+++ b/dist/bind/lib/isc/include/isc/result.h
@@ -1,4 +1,4 @@
-/* $NetBSD: result.h,v 1.1.1.1 2004/05/17 23:45:04 christos Exp $ */
+/* $NetBSD: result.h,v 1.1.1.2 2004/11/06 23:55:51 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: result.h,v 1.57.2.2.8.4 2004/03/08 09:04:53 marka Exp */
+/* Id: result.h,v 1.57.2.2.8.5 2004/05/15 03:46:13 jinmei Exp */
#ifndef ISC_RESULT_H
#define ISC_RESULT_H 1
@@ -84,11 +84,12 @@
#define ISC_R_BADNUMBER 56 /* not a valid number */
#define ISC_R_DISABLED 57 /* disabled */
#define ISC_R_MAXSIZE 58 /* max size */
+#define ISC_R_BADADDRESSFORM 59 /* invalid address format */
/*
* Not a result code: the number of results.
*/
-#define ISC_R_NRESULTS 59
+#define ISC_R_NRESULTS 60
ISC_LANG_BEGINDECLS
diff --git a/dist/bind/lib/isc/inet_ntop.c b/dist/bind/lib/isc/inet_ntop.c
index af350d36992..85f3d5eb000 100644
--- a/dist/bind/lib/isc/inet_ntop.c
+++ b/dist/bind/lib/isc/inet_ntop.c
@@ -1,4 +1,4 @@
-/* $NetBSD: inet_ntop.c,v 1.1.1.1 2004/05/17 23:45:02 christos Exp $ */
+/* $NetBSD: inet_ntop.c,v 1.1.1.2 2004/11/06 23:55:49 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -19,7 +19,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] =
- "Id: inet_ntop.c,v 1.12.12.3 2004/03/08 09:04:49 marka Exp";
+ "Id: inet_ntop.c,v 1.12.12.4 2004/08/28 06:25:21 marka Exp";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
@@ -29,6 +29,7 @@ static char rcsid[] =
#include <string.h>
#include <isc/net.h>
+#include <isc/print.h>
#define NS_INT16SZ 2
#define NS_IN6ADDRSZ 16
diff --git a/dist/bind/lib/isc/lex.c b/dist/bind/lib/isc/lex.c
index 2d9072c39e1..53f5d21ffda 100644
--- a/dist/bind/lib/isc/lex.c
+++ b/dist/bind/lib/isc/lex.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.1.1.1 2004/05/17 23:45:02 christos Exp $ */
+/* $NetBSD: lex.c,v 1.1.1.2 2004/11/06 23:55:49 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: lex.c,v 1.66.2.6.2.7 2004/03/06 08:14:31 marka Exp */
+/* Id: lex.c,v 1.66.2.6.2.8 2004/08/28 06:25:21 marka Exp */
#include <config.h>
@@ -31,6 +31,7 @@
#include <isc/mem.h>
#include <isc/msgs.h>
#include <isc/parseint.h>
+#include <isc/print.h>
#include <isc/stdio.h>
#include <isc/string.h>
#include <isc/util.h>
diff --git a/dist/bind/lib/isc/log.c b/dist/bind/lib/isc/log.c
index 9192bac76f0..777532810c1 100644
--- a/dist/bind/lib/isc/log.c
+++ b/dist/bind/lib/isc/log.c
@@ -1,4 +1,4 @@
-/* $NetBSD: log.c,v 1.1.1.1 2004/05/17 23:45:02 christos Exp $ */
+/* $NetBSD: log.c,v 1.1.1.2 2004/11/06 23:55:49 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: log.c,v 1.70.2.8.2.10 2004/04/10 04:31:40 marka Exp */
+/* Id: log.c,v 1.70.2.8.2.12 2004/06/11 00:35:38 marka Exp */
/* Principal Authors: DCL */
@@ -1142,6 +1142,10 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
unsigned int basenamelen;
isc_dir_t dir;
isc_result_t result;
+ char sep = '/';
+#ifdef _WIN32
+ char *basename2;
+#endif
REQUIRE(channel->type == ISC_LOG_TOFILE);
@@ -1149,7 +1153,15 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
* It is safe to DE_CONST the file.name because it was copied
* with isc_mem_strdup in isc_log_createchannel.
*/
- basename = strrchr(FILE_NAME(channel), '/');
+ basename = strrchr(FILE_NAME(channel), sep);
+#ifdef _WIN32
+ basename2 = strrchr(FILE_NAME(channel), '\\');
+ if ((basename != NULL && basename2 != NULL && basename2 > basename) ||
+ (basename == NULL && basename2 != NULL)) {
+ basename = basename2;
+ sep = '\\';
+ }
+#endif
if (basename != NULL) {
*basename++ = '\0';
dirname = FILE_NAME(channel);
@@ -1166,7 +1178,7 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
* Replace the file separator if it was taken out.
*/
if (basename != FILE_NAME(channel))
- *(basename - 1) = '/';
+ *(basename - 1) = sep;
/*
* Return if the directory open failed.
@@ -1319,8 +1331,11 @@ isc_log_open(isc_logchannel_t *channel) {
if (stat(path, &statbuf) == 0) {
regular_file = S_ISREG(statbuf.st_mode) ? ISC_TRUE : ISC_FALSE;
/* XXXDCL if not regular_file complain? */
- roll = ISC_TF(regular_file && FILE_MAXSIZE(channel) > 0 &&
- statbuf.st_size >= FILE_MAXSIZE(channel));
+ if ((FILE_MAXSIZE(channel) == 0 &&
+ FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) ||
+ (FILE_MAXSIZE(channel) > 0 &&
+ statbuf.st_size >= FILE_MAXSIZE(channel)))
+ roll = regular_file;
} else if (errno == ENOENT)
regular_file = ISC_TRUE;
else
diff --git a/dist/bind/lib/isc/netaddr.c b/dist/bind/lib/isc/netaddr.c
index f19890d1166..9d318f0676a 100644
--- a/dist/bind/lib/isc/netaddr.c
+++ b/dist/bind/lib/isc/netaddr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: netaddr.c,v 1.1.1.1 2004/05/17 23:45:02 christos Exp $ */
+/* $NetBSD: netaddr.c,v 1.1.1.2 2004/11/06 23:55:49 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: netaddr.c,v 1.18.12.8 2004/03/08 09:04:49 marka Exp */
+/* Id: netaddr.c,v 1.18.12.9 2004/05/15 03:46:12 jinmei Exp */
#include <config.h>
@@ -49,7 +49,8 @@ isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
break;
case AF_INET6:
if (memcmp(&a->type.in6, &b->type.in6,
- sizeof(a->type.in6)) != 0)
+ sizeof(a->type.in6)) != 0 ||
+ a->zone != b->zone)
return (ISC_FALSE);
break;
default:
diff --git a/dist/bind/lib/isc/result.c b/dist/bind/lib/isc/result.c
index dc9c17af9b8..18127be04ce 100644
--- a/dist/bind/lib/isc/result.c
+++ b/dist/bind/lib/isc/result.c
@@ -1,4 +1,4 @@
-/* $NetBSD: result.c,v 1.1.1.1 2004/05/17 23:45:03 christos Exp $ */
+/* $NetBSD: result.c,v 1.1.1.2 2004/11/06 23:55:50 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: result.c,v 1.56.2.2.8.5 2004/03/08 09:04:50 marka Exp */
+/* Id: result.c,v 1.56.2.2.8.7 2004/06/11 00:31:01 marka Exp */
#include <config.h>
@@ -98,7 +98,8 @@ static const char *text[ISC_R_NRESULTS] = {
"soft quota reached", /* 55 */
"not a valid number", /* 56 */
"disabled", /* 57 */
- "max size" /* 58 */
+ "max size", /* 58 */
+ "invalid address format" /* 59 */
};
#define ISC_RESULT_RESULTSET 2
@@ -126,7 +127,7 @@ register_table(unsigned int base, unsigned int nresults, const char **text,
if (table == NULL)
return (ISC_R_NOMEMORY);
table->base = base;
- table->last = base + nresults;
+ table->last = base + nresults - 1;
table->text = text;
table->msgcat = msgcat;
table->set = set;
diff --git a/dist/bind/lib/isc/sockaddr.c b/dist/bind/lib/isc/sockaddr.c
index b34e261749f..66ee4cabc12 100644
--- a/dist/bind/lib/isc/sockaddr.c
+++ b/dist/bind/lib/isc/sockaddr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sockaddr.c,v 1.1.1.1 2004/05/17 23:45:02 christos Exp $ */
+/* $NetBSD: sockaddr.c,v 1.1.1.2 2004/11/06 23:55:50 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: sockaddr.c,v 1.48.2.1.2.9 2004/03/08 09:04:50 marka Exp */
+/* Id: sockaddr.c,v 1.48.2.1.2.10 2004/05/15 03:46:12 jinmei Exp */
#include <config.h>
@@ -59,6 +59,10 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
sizeof(a->type.sin6.sin6_addr)) != 0)
return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+ return (ISC_FALSE);
+#endif
if (a->type.sin6.sin6_port != b->type.sin6.sin6_port)
return (ISC_FALSE);
break;
@@ -88,6 +92,10 @@ isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
sizeof(a->type.sin6.sin6_addr)) != 0)
return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+ return (ISC_FALSE);
+#endif
break;
default:
if (memcmp(&a->type, &b->type, a->length) != 0)
diff --git a/dist/bind/lib/isc/unix/Makefile.in b/dist/bind/lib/isc/unix/Makefile.in
index 84eaa8cfc9e..d0c6c4b6c2a 100644
--- a/dist/bind/lib/isc/unix/Makefile.in
+++ b/dist/bind/lib/isc/unix/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# Id: Makefile.in,v 1.35.2.1.10.1 2004/03/06 08:14:57 marka Exp
+# Id: Makefile.in,v 1.35.2.1.10.2 2004/06/22 02:48:36 marka Exp
srcdir = @srcdir@
VPATH = @srcdir@
@@ -46,3 +46,6 @@ SUBDIRS = include
TARGETS = ${OBJS}
@BIND9_MAKE_RULES@
+
+interfaceiter.@O@: interfaceiter.c ifiter_ioctl.c ifiter_sysctl.c ifiter_getifaddrs.c
+
diff --git a/dist/bind/lib/isc/unix/ifiter_ioctl.c b/dist/bind/lib/isc/unix/ifiter_ioctl.c
index 2f4c958b0bc..6ef96fbb387 100644
--- a/dist/bind/lib/isc/unix/ifiter_ioctl.c
+++ b/dist/bind/lib/isc/unix/ifiter_ioctl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ifiter_ioctl.c,v 1.1.1.1 2004/05/17 23:45:05 christos Exp $ */
+/* $NetBSD: ifiter_ioctl.c,v 1.1.1.2 2004/11/06 23:55:52 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: ifiter_ioctl.c,v 1.19.2.5.2.10 2004/04/15 07:03:50 marka Exp */
+/* Id: ifiter_ioctl.c,v 1.19.2.5.2.14 2004/06/22 04:40:23 marka Exp */
/*
* Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
@@ -52,7 +52,7 @@
#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
#define ISC_IF_INET6_SZ \
- sizeof("00000000000000000000000000000001 01 80 10 80 lo\n")
+ sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
struct isc_interfaceiter {
unsigned int magic; /* Magic number. */
@@ -102,6 +102,16 @@ struct isc_interfaceiter {
#define IFCONF_BUFSIZE_INITIAL 4096
#define IFCONF_BUFSIZE_MAX 1048576
+#ifdef __linux
+#ifndef IF_NAMESIZE
+# ifdef IFNAMSIZ
+# define IF_NAMESIZE IFNAMSIZ
+# else
+# define IF_NAMESIZE 16
+# endif
+#endif
+#endif
+
static isc_result_t
getbuf4(isc_interfaceiter_t *iter) {
char strbuf[ISC_STRERRORSIZE];
@@ -446,15 +456,28 @@ linux_if_inet6_current(isc_interfaceiter_t *iter) {
if (iter->valid != ISC_R_SUCCESS)
return (iter->valid);
- if (iter->proc == NULL)
+ if (iter->proc == NULL) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:iter->proc == NULL");
return (ISC_R_FAILURE);
+ }
res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
address, &ifindex, &prefix, &flag3, &flag4, name);
- if (res != 6)
+ if (res != 6) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
+ res);
return (ISC_R_FAILURE);
- if (strlen(address) != 32)
+ }
+ if (strlen(address) != 32) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:strlen(%s) != 32", address);
return (ISC_R_FAILURE);
+ }
for (i = 0; i < 16; i++) {
unsigned char byte;
static const char hex[] = "0123456789abcdef";
@@ -945,7 +968,7 @@ internal_next(isc_interfaceiter_t *iter) {
#endif
#ifdef HAVE_TRUCLUSTER
if (!iter->clua_done) {
- clua_result = clua_getaliasaddress(&intr->clua_sa,
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
&iter->clua_context);
if (clua_result != CLUA_SUCCESS)
iter->clua_done = ISC_TRUE;
@@ -985,7 +1008,7 @@ void internal_first(isc_interfaceiter_t *iter) {
#endif
#ifdef HAVE_TRUCLUSTER
iter->clua_context = 0;
- clua_result = clua_getaliasaddress(&intr->clua_sa,
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
&iter->clua_context);
iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS);
#endif
diff --git a/dist/bind/lib/isc/unix/interfaceiter.c b/dist/bind/lib/isc/unix/interfaceiter.c
index a8427bfeaff..db8ec2ed0d5 100644
--- a/dist/bind/lib/isc/unix/interfaceiter.c
+++ b/dist/bind/lib/isc/unix/interfaceiter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: interfaceiter.c,v 1.1.1.1 2004/05/17 23:45:05 christos Exp $ */
+/* $NetBSD: interfaceiter.c,v 1.1.1.2 2004/11/06 23:55:52 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: interfaceiter.c,v 1.22.2.1.10.12 2004/04/20 06:46:53 marka Exp */
+/* Id: interfaceiter.c,v 1.22.2.1.10.14 2004/08/28 06:25:22 marka Exp */
#include <config.h>
@@ -38,6 +38,7 @@
#include <isc/mem.h>
#include <isc/msgs.h>
#include <isc/net.h>
+#include <isc/print.h>
#include <isc/result.h>
#include <isc/strerror.h>
#include <isc/string.h>
@@ -67,6 +68,11 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
{
struct sockaddr_in6 *sa6;
+#if !defined(ISC_PLATFORM_HAVEIFNAMETOINDEX) || \
+ !defined(ISC_PLATFORM_HAVESCOPEID)
+ UNUSED(ifname);
+#endif
+
/* clear any remaining value for safety */
memset(dst, 0, sizeof(*dst));
diff --git a/dist/bind/lib/isc/unix/socket.c b/dist/bind/lib/isc/unix/socket.c
index a75a4b2d69d..c5ff6c293b8 100644
--- a/dist/bind/lib/isc/unix/socket.c
+++ b/dist/bind/lib/isc/unix/socket.c
@@ -1,4 +1,4 @@
-/* $NetBSD: socket.c,v 1.1.1.1 2004/05/17 23:45:06 christos Exp $ */
+/* $NetBSD: socket.c,v 1.1.1.2 2004/11/06 23:55:53 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: socket.c,v 1.207.2.19.2.11 2004/04/19 03:05:22 marka Exp */
+/* Id: socket.c,v 1.207.2.19.2.13 2004/07/01 04:51:15 marka Exp */
#include <config.h>
@@ -2861,7 +2861,11 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
UNLOCK(&sock->lock);
return (ISC_R_FAMILYMISMATCH);
}
- if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
+ /*
+ * Only set SO_REUSEADDR when we want a specific port.
+ */
+ if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
+ setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on)) < 0) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d) %s", sock->fd,
diff --git a/dist/bind/lib/isc/win32/socket.c b/dist/bind/lib/isc/win32/socket.c
index d8ed9e78bef..980f11ad7f5 100644
--- a/dist/bind/lib/isc/win32/socket.c
+++ b/dist/bind/lib/isc/win32/socket.c
@@ -1,4 +1,4 @@
-/* $NetBSD: socket.c,v 1.1.1.1 2004/05/17 23:45:07 christos Exp $ */
+/* $NetBSD: socket.c,v 1.1.1.2 2004/11/06 23:55:58 christos Exp $ */
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* Id: socket.c,v 1.5.2.13.2.8 2004/03/06 08:15:10 marka Exp */
+/* Id: socket.c,v 1.5.2.13.2.13 2004/09/01 04:32:18 marka Exp */
/* This code has been rewritten to take advantage of Windows Sockets
* I/O Completion Ports and Events. I/O Completion Ports is ONLY
@@ -241,8 +241,10 @@ struct isc_socket {
listener : 1, /* listener socket */
connected : 1,
connecting : 1, /* connect pending */
- bound : 1; /* bound to local addr */
-
+ bound : 1, /* bound to local addr */
+ pending_free: 1;
+ unsigned int pending_recv;
+ unsigned int pending_send;
};
/*
@@ -348,11 +350,8 @@ static isc_threadresult_t WINAPI SocketIoThread(LPVOID ThreadContext);
static void free_socket(isc_socket_t **);
enum {
- SOCKET_CANCEL,
- SOCKET_SHUTDOWN,
SOCKET_RECV,
SOCKET_SEND,
- SOCK_ACCEPT
};
enum {
@@ -360,9 +359,6 @@ enum {
EVENT_DELETE
};
-#define SOCK_DEAD(s) ((s)->references == 0)
-
-
#if defined(ISC_SOCKET_DEBUG)
/*
* This is used to dump the contents of the sock structure
@@ -456,7 +452,7 @@ iocompletionport_createthreads(int total_threads, isc_socketmgr_t *manager) {
* We need at least one
*/
for (i = 0; i < total_threads; i++) {
- manager->hIOCPThreads[i] = CreateThread( NULL, 0, SocketIoThread,
+ manager->hIOCPThreads[i] = CreateThread(NULL, 0, SocketIoThread,
manager, 0,
&manager->dwIOCPThreadIds[i]);
if(manager->hIOCPThreads[i] == NULL) {
@@ -523,7 +519,8 @@ iocompletionport_exit(isc_socketmgr_t *manager) {
}
/*
- * Add sockets in here and pass the sock data in as part of the information needed
+ * Add sockets in here and pass the sock data in as part of the
+ * information needed.
*/
void
iocompletionport_update(isc_socket_t *sock) {
@@ -654,9 +651,10 @@ socket_eventlist_add(event_change_t *evchange, sock_event_list *evlist,
sock->evthread_id = GetCurrentThreadId();
return (ISC_TRUE);
}
+
/*
- * Note that the eventLock is locked before calling this function
- * All Events and associated sockes are closed here
+ * Note that the eventLock is locked before calling this function.
+ * All Events and associated sockets are closed here.
*/
isc_boolean_t
socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) {
@@ -666,7 +664,7 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) {
REQUIRE(evchange != NULL);
/* Make sure this is the right thread from which to delete the event */
- if(evchange->evthread_id != GetCurrentThreadId())
+ if (evchange->evthread_id != GetCurrentThreadId())
return (ISC_FALSE);
REQUIRE(evlist != NULL);
@@ -680,6 +678,7 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) {
break;
}
}
+
/* Actual event start at 1 */
if (iEvent < 1)
return (ISC_FALSE);
@@ -688,6 +687,7 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) {
evlist->aEventList[i] = evlist->aEventList[i + 1];
evlist->aSockList[i] = evlist->aSockList[i + 1];
}
+
evlist->aEventList[evlist->max_event - 1] = 0;
evlist->aSockList[evlist->max_event - 1] = NULL;
@@ -700,6 +700,7 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist) {
return (ISC_TRUE);
}
+
/*
* Get the event changes off of the list and apply the
* requested changes. The manager lock is taken out at
@@ -724,15 +725,20 @@ process_eventlist(sock_event_list *evlist, isc_socketmgr_t *manager) {
LOCK(&manager->lock);
- /* First the deletes */
+ /*
+ * First the deletes.
+ */
evchange = ISC_LIST_HEAD(manager->event_updates);
while (evchange != NULL) {
next = ISC_LIST_NEXT(evchange, link);
del = ISC_FALSE;
- if(evchange->action == EVENT_DELETE) {
+ if (evchange->action == EVENT_DELETE) {
del = socket_eventlist_delete(evchange, evlist);
- /* Delete only if this thread's socket list was updated */
+ /*
+ * Delete only if this thread's socket list was
+ * updated.
+ */
if (del) {
ISC_LIST_DEQUEUE(manager->event_updates,
evchange, link);
@@ -742,15 +748,21 @@ process_eventlist(sock_event_list *evlist, isc_socketmgr_t *manager) {
}
evchange = next;
}
- /* Now the adds */
+
+ /*
+ * Now the adds.
+ */
evchange = ISC_LIST_HEAD(manager->event_updates);
while (evchange != NULL) {
next = ISC_LIST_NEXT(evchange, link);
del = ISC_FALSE;
- if(evchange->action == EVENT_ADD) {
+ if (evchange->action == EVENT_ADD) {
del = socket_eventlist_add(evchange, evlist, manager);
- /* Delete only if this thread's socket list was updated */
+ /*
+ * Delete only if this thread's socket list was
+ * updated.
+ */
if (del) {
ISC_LIST_DEQUEUE(manager->event_updates,
evchange, link);
@@ -763,13 +775,15 @@ process_eventlist(sock_event_list *evlist, isc_socketmgr_t *manager) {
UNLOCK(&manager->lock);
return (ISC_R_SUCCESS);
}
+
/*
* Add the event list changes to the queue and notify the
* event loop
*/
static void
notify_eventlist(isc_socket_t *sock, isc_socketmgr_t *manager,
- unsigned int action) {
+ unsigned int action)
+{
event_change_t *evchange;
@@ -795,6 +809,7 @@ notify_eventlist(isc_socket_t *sock, isc_socketmgr_t *manager,
else
WSASetEvent(manager->prime_alert);
}
+
/*
* Note that the socket is already locked before calling this function
*/
@@ -832,6 +847,7 @@ socket_event_add(isc_socket_t *sock, long type) {
notify_eventlist(sock, sock->manager, EVENT_ADD);
return (ISC_R_SUCCESS);
}
+
/*
* Note that the socket is not locked before calling this function
*/
@@ -849,8 +865,8 @@ socket_event_delete(isc_socket_t *sock) {
sock->hAlert = NULL;
sock->evthread_id = 0;
}
-
}
+
/*
* Routine to cleanup and then close the socket.
* Only close the socket here if it is NOT associated
@@ -874,6 +890,7 @@ socket_close(isc_socket_t *sock) {
}
}
+
/*
* Initialize socket services
*/
@@ -895,7 +912,8 @@ BOOL InitSockets() {
int
internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
- struct msghdr *messagehdr, int flags, int *Error) {
+ struct msghdr *messagehdr, int flags, int *Error)
+{
int Result;
DWORD BytesSent;
DWORD Flags = flags;
@@ -920,19 +938,20 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
*Error = WSAGetLastError();
switch (*Error) {
+ case WSA_IO_INCOMPLETE :
+ case WSA_WAIT_IO_COMPLETION :
+ case WSA_IO_PENDING :
+ sock->pending_send++;
+ case NO_ERROR :
+ break;
- case NO_ERROR :
- case WSA_IO_INCOMPLETE :
- case WSA_WAIT_IO_COMPLETION :
- case WSA_IO_PENDING :
- break;
-
- default :
- return (-1);
- break;
- }
- }
- if(lpo != NULL)
+ default :
+ return (-1);
+ break;
+ }
+ } else
+ sock->pending_send++;
+ if (lpo != NULL)
return (0);
else
return (total_sent);
@@ -940,7 +959,8 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
int
internal_recvmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
- struct msghdr *messagehdr, int flags, int *Error) {
+ struct msghdr *messagehdr, int flags, int *Error)
+{
DWORD Flags = 0;
DWORD NumBytes = 0;
int total_bytes = 0;
@@ -948,14 +968,14 @@ internal_recvmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
*Error = 0;
Result = WSARecvFrom((SOCKET) sock->fd,
- messagehdr->msg_iov,
- messagehdr->msg_iovlen,
- &NumBytes,
- &Flags,
- messagehdr->msg_name,
- (int *)&(messagehdr->msg_namelen),
- (LPOVERLAPPED) lpo,
- NULL);
+ messagehdr->msg_iov,
+ messagehdr->msg_iovlen,
+ &NumBytes,
+ &Flags,
+ messagehdr->msg_name,
+ (int *)&(messagehdr->msg_namelen),
+ (LPOVERLAPPED) lpo,
+ NULL);
total_bytes = (int) NumBytes;
@@ -965,31 +985,32 @@ internal_recvmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
*Error = WSAGetLastError();
switch (*Error) {
+ case WSA_IO_INCOMPLETE:
+ case WSA_WAIT_IO_COMPLETION:
+ case WSA_IO_PENDING:
+ sock->pending_recv++;
+ case NO_ERROR:
+ break;
- case NO_ERROR :
- case WSA_IO_INCOMPLETE :
- case WSA_WAIT_IO_COMPLETION :
- case WSA_IO_PENDING :
- break;
+ default :
+ return (-1);
+ break;
+ }
+ } else
+ sock->pending_recv++;
- default :
- return (-1);
- break;
- }
- }
/* Return the flags received in header */
messagehdr->msg_flags = Flags;
- if(lpo != NULL)
+ if (lpo != NULL)
return (-1);
else
return (total_bytes);
-
}
static void
-manager_log(isc_socketmgr_t *sockmgr,
- isc_logcategory_t *category, isc_logmodule_t *module, int level,
- const char *fmt, ...) {
+manager_log(isc_socketmgr_t *sockmgr, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *fmt, ...)
+{
char msgbuf[2048];
va_list ap;
@@ -1009,11 +1030,13 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10);
+
static void
socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
- const char *fmt, ...) {
+ const char *fmt, ...)
+{
char msgbuf[2048];
char peerbuf[256];
va_list ap;
@@ -1060,6 +1083,7 @@ make_nonblock(SOCKET fd) {
return (ISC_R_SUCCESS);
}
+
/*
* Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
* to not work correctly, returning a WSACONNRESET error when a WSASendTo
@@ -1109,7 +1133,8 @@ connection_reset_fix(SOCKET fd) {
static void
build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, char *cmsg,
- WSABUF *iov, size_t *write_countp) {
+ WSABUF *iov, size_t *write_countp)
+{
unsigned int iovcount;
isc_buffer_t *buffer;
isc_region_t used;
@@ -1196,7 +1221,8 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
static void
build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, char *cmsg,
- WSABUF *iov, size_t *read_countp) {
+ WSABUF *iov, size_t *read_countp)
+{
unsigned int iovcount;
isc_buffer_t *buffer;
isc_region_t available;
@@ -1226,10 +1252,10 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
iov[0].len = read_count;
iovcount = 1;
} else {
- /*
- * Multibuffer I/O.
- * Skip empty buffers.
- */
+ /*
+ * Multibuffer I/O.
+ * Skip empty buffers.
+ */
while (buffer != NULL) {
REQUIRE(ISC_BUFFER_VALID(buffer));
if (isc_buffer_availablelength(buffer) != 0)
@@ -1268,7 +1294,8 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
static void
set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
- isc_socketevent_t *dev) {
+ isc_socketevent_t *dev)
+{
if (sock->type == isc_sockettype_udp) {
if (address != NULL)
dev->address = *address;
@@ -1282,14 +1309,14 @@ set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
static isc_socketevent_t *
allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
- isc_taskaction_t action, const void *arg) {
+ isc_taskaction_t action, const void *arg)
+{
isc_socketevent_t *ev;
ev = (isc_socketevent_t *)isc_event_allocate(sock->manager->mctx,
sock, eventtype,
action, arg,
sizeof(*ev));
-
if (ev == NULL)
return (NULL);
@@ -1326,7 +1353,8 @@ dump_msg(struct msghdr *msg, isc_socket_t *sock) {
static int
completeio_recv(isc_socket_t *sock, isc_socketevent_t *dev,
- struct msghdr *messagehdr, int cc, int recv_errno) {
+ struct msghdr *messagehdr, int cc, int recv_errno)
+{
size_t actual_count;
isc_buffer_t *buffer;
@@ -1444,31 +1472,27 @@ completeio_recv(isc_socket_t *sock, isc_socketevent_t *dev,
dev->result = ISC_R_SUCCESS;
return (DOIO_SUCCESS);
}
+
static int
startio_recv(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
- BOOL bwait, int *recv_errno) {
+ int *recv_errno)
+{
char *cmsg = NULL;
char strbuf[ISC_STRERRORSIZE];
IoCompletionInfo *lpo;
int status;
- struct msghdr messagehdr;
struct msghdr *msghdr;
- if (!bwait) {
- lpo = (IoCompletionInfo *) HeapAlloc(hHeapHandle,
- HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo));
- lpo->request_type = SOCKET_RECV;
- lpo->dev = dev;
- msghdr = &lpo->messagehdr;
- } else { /* Wait for recv to complete */
- lpo = NULL;
- msghdr = &messagehdr;
- }
- sock->references++;
+ lpo = (IoCompletionInfo *) HeapAlloc(hHeapHandle,
+ HEAP_ZERO_MEMORY,
+ sizeof(IoCompletionInfo));
+ lpo->request_type = SOCKET_RECV;
+ lpo->dev = dev;
+ msghdr = &lpo->messagehdr;
memset(msghdr, 0, sizeof(struct msghdr));
build_msghdr_recv(sock, dev, msghdr, cmsg, sock->iov,
- &(sock->totalBytes));
+ &(sock->totalBytes));
#if defined(ISC_SOCKET_DEBUG)
dump_msg(msghdr, sock);
@@ -1487,13 +1511,12 @@ startio_recv(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
socket_log(sock, NULL, IOEVENT,
isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_DOIORECV,
- "startio_recv: recvmsg(%d) %d bytes, err %d/%s",
+ "startio_recv: recvmsg(%d) %d bytes, "
+ "err %d/%s",
sock->fd, *nbytes, *recv_errno, strbuf);
}
- status = completeio_recv(sock, dev, msghdr, *nbytes, *recv_errno);
- if(status != DOIO_SOFT) {
- sock->references--;
- }
+ status = completeio_recv(sock, dev, msghdr,
+ *nbytes, *recv_errno);
goto done;
}
dev->result = ISC_R_SUCCESS;
@@ -1501,6 +1524,7 @@ startio_recv(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
done:
return (status);
}
+
/*
* Returns:
* DOIO_SUCCESS The operation succeeded. dev->result contains
@@ -1515,8 +1539,9 @@ done:
* No other return values are possible.
*/
static int
-completeio_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messagehdr, int cc,
- int send_errno) {
+completeio_send(isc_socket_t *sock, isc_socketevent_t *dev,
+ struct msghdr *messagehdr, int cc, int send_errno)
+{
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
char strbuf[ISC_STRERRORSIZE];
@@ -1594,28 +1619,24 @@ completeio_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messa
dev->result = ISC_R_SUCCESS;
return (DOIO_SUCCESS);
}
+
static int
startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
- BOOL bwait, int *send_errno) {
+ int *send_errno)
+{
char *cmsg = NULL;
char strbuf[ISC_STRERRORSIZE];
IoCompletionInfo *lpo;
int status;
- struct msghdr messagehdr;
struct msghdr *msghdr;
- if (!bwait) {
- lpo = (IoCompletionInfo *) HeapAlloc(hHeapHandle,
- HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo));
- lpo->request_type = SOCKET_SEND;
- lpo->dev = dev;
- msghdr = &lpo->messagehdr;
- } else { /* Wait for send to complete */
- lpo = NULL;
- msghdr = &messagehdr;
- }
+ lpo = (IoCompletionInfo *) HeapAlloc(hHeapHandle,
+ HEAP_ZERO_MEMORY,
+ sizeof(IoCompletionInfo));
+ lpo->request_type = SOCKET_SEND;
+ lpo->dev = dev;
+ msghdr = &lpo->messagehdr;
memset(msghdr, 0, sizeof(struct msghdr));
- sock->references++;
build_msghdr_send(sock, dev, msghdr, cmsg, sock->iov,
&(sock->totalBytes));
@@ -1633,13 +1654,12 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
socket_log(sock, NULL, IOEVENT,
isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_INTERNALSEND,
- "startio_send: internal_sendmsg(%d) %d bytes, err %d/%s",
+ "startio_send: internal_sendmsg(%d) %d "
+ "bytes, err %d/%s",
sock->fd, *nbytes, *send_errno, strbuf);
}
- status = completeio_send(sock, dev, msghdr, *nbytes, *send_errno);
- if(status != DOIO_SOFT) {
- sock->references--;
- }
+ status = completeio_send(sock, dev, msghdr,
+ *nbytes, *send_errno);
goto done;
}
dev->result = ISC_R_SUCCESS;
@@ -1647,6 +1667,7 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
done:
return (status);
}
+
/*
* Kill.
*
@@ -1657,6 +1678,7 @@ static void
destroy_socket(isc_socket_t **sockp) {
isc_socket_t *sock = *sockp;
isc_socketmgr_t *manager = sock->manager;
+ isc_boolean_t dofree = ISC_TRUE;
REQUIRE(sock != NULL);
@@ -1670,15 +1692,14 @@ destroy_socket(isc_socket_t **sockp) {
LOCK(&manager->lock);
- /*
- * No one has this socket open and the socket doesn't have to be
- * locked. The socket_close function makes sure that if needed
- * the event_wait loop removes any associated event from the list
- * of events being waited on.
- */
+ LOCK(&sock->lock);
socket_close(sock);
-
+ if (sock->pending_recv != 0 || sock->pending_send != 0) {
+ dofree = ISC_FALSE;
+ sock->pending_free = 1;
+ }
ISC_LIST_UNLINK(manager->socklist, sock, link);
+ UNLOCK(&sock->lock);
if (ISC_LIST_EMPTY(manager->socklist))
SIGNAL(&manager->shutdown_ok);
@@ -1686,10 +1707,10 @@ destroy_socket(isc_socket_t **sockp) {
/*
* XXX should reset manager->maxfd here
*/
-
UNLOCK(&manager->lock);
- free_socket(sockp);
+ if (dofree)
+ free_socket(sockp);
}
static isc_result_t
@@ -1723,6 +1744,9 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
sock->connect_ev = NULL;
sock->pending_accept = 0;
sock->pending_close = 0;
+ sock->pending_recv = 0;
+ sock->pending_send = 0;
+ sock->pending_free = 0;
sock->iocp = 0;
sock->listener = 0;
sock->connected = 0;
@@ -1824,11 +1848,13 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
switch (type) {
case isc_sockettype_udp:
sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
- result = connection_reset_fix(sock->fd);
- if (result != ISC_R_SUCCESS) {
- closesocket(sock->fd);
- free_socket(&sock);
- return (result);
+ if (sock->fd != INVALID_SOCKET) {
+ result = connection_reset_fix(sock->fd);
+ if (result != ISC_R_SUCCESS) {
+ closesocket(sock->fd);
+ free_socket(&sock);
+ return (result);
+ }
}
break;
case isc_sockettype_tcp:
@@ -1894,7 +1920,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
(void *)&on, sizeof(on)) < 0)) {
- isc__strerror(WSAGetLaastError(), strbuf, sizeof(strbuf));
+ isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_PKTINFO) %s: %s",
sock->fd,
@@ -2068,14 +2094,6 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
INSIST(sock->pending_accept == 1);
sock->pending_accept = 0;
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- UNLOCK(&sock->lock);
- destroy_socket(&sock);
- return;
- }
-
/*
* Check any possible error status from the event notification here.
* Note that we don't take any action since it was only
@@ -2287,18 +2305,6 @@ internal_connect(isc_socket_t *sock, int connect_errno) {
LOCK(&sock->lock);
/*
- * When the internal event was sent the reference count was bumped
- * to keep the socket around for us. Decrement the count here.
- */
- INSIST(sock->references > 0);
- sock->references--;
- if (sock->references == 0) {
- UNLOCK(&sock->lock);
- destroy_socket(&sock);
- return;
- }
-
- /*
* Has this event been canceled?
*/
dev = sock->connect_ev;
@@ -2368,7 +2374,9 @@ internal_connect(isc_socket_t *sock, int connect_errno) {
}
static void
-internal_recv(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messagehdr, int nbytes, int recv_errno) {
+internal_recv(isc_socket_t *sock, isc_socketevent_t *dev,
+ struct msghdr *messagehdr, int nbytes, int recv_errno)
+{
isc_socketevent_t *ldev;
int io_state;
int cc;
@@ -2380,14 +2388,8 @@ internal_recv(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *message
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV,
"internal_recv: task got socket event %p", dev);
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- UNLOCK(&sock->lock);
- destroy_socket(&sock);
- return;
- }
-
+ INSIST(sock->pending_recv > 0);
+ sock->pending_recv--;
/* If the event is no longer in the list we can just return */
ldev = ISC_LIST_HEAD(sock->recv_list);
while (ldev != NULL && ldev != dev) {
@@ -2400,34 +2402,36 @@ internal_recv(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *message
* Try to do as much I/O as possible on this socket. There are no
* limits here, currently.
*/
- switch (completeio_recv(sock, dev, messagehdr, nbytes, recv_errno)) {
- case DOIO_SOFT:
- cc = 0;
- recv_errno = 0;
- io_state = startio_recv(sock, dev, &cc, FALSE, &recv_errno);
- goto done;
+ switch (completeio_recv(sock, dev, messagehdr, nbytes, recv_errno)) {
+ case DOIO_SOFT:
+ cc = 0;
+ recv_errno = 0;
+ io_state = startio_recv(sock, dev, &cc, &recv_errno);
+ goto done;
- case DOIO_EOF:
- /*
- * read of 0 means the remote end was closed.
- * Run through the event queue and dispatch all
- * the events with an EOF result code.
- */
- dev->result = ISC_R_EOF;
- send_recvdone_event(sock, &dev);
- goto done;
+ case DOIO_EOF:
+ /*
+ * read of 0 means the remote end was closed.
+ * Run through the event queue and dispatch all
+ * the events with an EOF result code.
+ */
+ dev->result = ISC_R_EOF;
+ send_recvdone_event(sock, &dev);
+ goto done;
- case DOIO_SUCCESS:
- case DOIO_HARD:
- send_recvdone_event(sock, &dev);
- break;
- }
+ case DOIO_SUCCESS:
+ case DOIO_HARD:
+ send_recvdone_event(sock, &dev);
+ break;
+ }
done:
UNLOCK(&sock->lock);
}
static void
-internal_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messagehdr, int nbytes, int send_errno) {
+internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
+ struct msghdr *messagehdr, int nbytes, int send_errno)
+{
isc_socketevent_t *ldev;
int io_state;
int cc;
@@ -2442,13 +2446,8 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *message
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND,
"internal_send: task got socket event %p", dev);
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- UNLOCK(&sock->lock);
- destroy_socket(&sock);
- return;
- }
+ INSIST(sock->pending_send > 0);
+ sock->pending_send--;
/* If the event is no longer in the list we can just return */
ldev = ISC_LIST_HEAD(sock->send_list);
@@ -2465,7 +2464,7 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *message
case DOIO_SOFT:
cc = 0;
send_errno = 0;
- io_state = startio_send(sock, dev, &cc, FALSE, &send_errno);
+ io_state = startio_send(sock, dev, &cc, &send_errno);
goto done;
case DOIO_HARD:
@@ -2489,8 +2488,6 @@ SocketIoThread(LPVOID ThreadContext) {
isc_socketmgr_t *manager = ThreadContext;
BOOL bSuccess = FALSE;
DWORD nbytes;
- DWORD tbytes;
- DWORD tflags;
IoCompletionInfo *lpo = NULL;
isc_socket_t *sock = NULL;
int request;
@@ -2506,7 +2503,9 @@ SocketIoThread(LPVOID ThreadContext) {
* preempt normal recv packet processing, but not
* higher than the timer sync thread.
*/
- if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL)) {
+ if (!SetThreadPriority(GetCurrentThread(),
+ THREAD_PRIORITY_ABOVE_NORMAL))
+ {
errval = GetLastError();
isc__strerror(errval, strbuf, sizeof(strbuf));
FATAL_ERROR(__FILE__, __LINE__,
@@ -2516,33 +2515,53 @@ SocketIoThread(LPVOID ThreadContext) {
strbuf);
}
-
/*
* Loop forever waiting on I/O Completions and then processing them
*/
- while(TRUE) {
+ while (TRUE) {
bSuccess = GetQueuedCompletionStatus (
manager->hIoCompletionPort,
&nbytes,
(LPDWORD) &sock,
(LPOVERLAPPED *)&lpo,
- INFINITE
- );
- if(lpo == NULL ) {
+ INFINITE);
+ if (lpo == NULL) {
/*
* Received request to exit
*/
break;
}
errstatus = 0;
- if(!bSuccess) {
+ if (!bSuccess) {
+ isc_boolean_t dofree = ISC_FALSE;
+ REQUIRE(VALID_SOCKET(sock));
/*
- * I/O Failure
- * Find out why
+ * Was this the socket closed under us?
*/
- WSAGetOverlappedResult(sock->fd, (LPWSAOVERLAPPED) &lpo,
- &tbytes, FALSE, &tflags);
- dev = lpo->dev;
+ errstatus = WSAGetLastError();
+ if (nbytes == 0 && errstatus == WSA_OPERATION_ABORTED) {
+ LOCK(&sock->lock);
+ switch (lpo->request_type) {
+ case SOCKET_RECV:
+ INSIST(sock->pending_recv > 0);
+ sock->pending_recv--;
+ break;
+ case SOCKET_SEND:
+ INSIST(sock->pending_send > 0);
+ sock->pending_send--;
+ break;
+ }
+ if (sock->pending_recv == 0 &&
+ sock->pending_send == 0 &&
+ sock->pending_free)
+ dofree = ISC_TRUE;
+ UNLOCK(&sock->lock);
+ if (dofree)
+ free_socket(&sock);
+ if (lpo != NULL)
+ HeapFree(hHeapHandle, 0, lpo);
+ continue;
+ }
}
request = lpo->request_type;
@@ -2550,20 +2569,17 @@ SocketIoThread(LPVOID ThreadContext) {
messagehdr = &lpo->messagehdr;
switch (request) {
- case SOCKET_CANCEL:
- break;
case SOCKET_RECV:
internal_recv(sock, dev, messagehdr, nbytes, errstatus);
break;
case SOCKET_SEND:
internal_send(sock, dev, messagehdr, nbytes, errstatus);
break;
- default:
- break; /* Unknown: Just ignore it */
}
if (lpo != NULL)
HeapFree(hHeapHandle, 0, lpo);
}
+
/*
* Exit Completion Port Thread
*/
@@ -2572,6 +2588,7 @@ SocketIoThread(LPVOID ThreadContext) {
ISC_MSG_EXITING, "SocketIoThread exiting"));
return ((isc_threadresult_t)0);
}
+
/*
* This is the thread that will loop forever, waiting for an event to
* happen.
@@ -2633,7 +2650,6 @@ event_wait(void *uap) {
} while (cc < 0 && !manager->bShutdown
&& manager->event_written == 0);
-
if (manager->bShutdown)
break;
@@ -2692,11 +2708,9 @@ event_wait(void *uap) {
if (wsock->listener == 1 &&
wsock->pending_accept == 0) {
wsock->pending_accept = 1;
- wsock->references++;
internal_accept(wsock, event_errno);
}
else {
- wsock->references++;
internal_connect(wsock, event_errno);
}
}
@@ -2708,6 +2722,7 @@ event_wait(void *uap) {
return ((isc_threadresult_t)0);
}
+
/*
* Create a new socket manager.
*/
@@ -2863,7 +2878,8 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
static isc_result_t
socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
- unsigned int flags) {
+ unsigned int flags)
+{
int io_state;
int cc = 0;
isc_task_t *ntask = NULL;
@@ -2874,7 +2890,7 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
LOCK(&sock->lock);
iocompletionport_update(sock);
- io_state = startio_recv(sock, dev, &cc, FALSE, &recv_errno);
+ io_state = startio_recv(sock, dev, &cc, &recv_errno);
switch (io_state) {
case DOIO_SOFT:
@@ -3052,7 +3068,7 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
LOCK(&sock->lock);
have_lock = ISC_TRUE;
iocompletionport_update(sock);
- io_state = startio_send(sock, dev, &cc, FALSE, &send_errno);
+ io_state = startio_send(sock, dev, &cc, &send_errno);
switch (io_state) {
case DOIO_SOFT:
@@ -3211,7 +3227,11 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
UNLOCK(&sock->lock);
return (ISC_R_FAMILYMISMATCH);
}
- if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
+ /*
+ * Only set SO_REUSEADDR when we want a specific port.
+ */
+ if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
+ setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on)) < 0) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d) %s", sock->fd,
@@ -3645,7 +3665,6 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
isc_task_t *current_task;
dev = ISC_LIST_HEAD(sock->accept_list);
- socket_event_delete(sock);
while (dev != NULL) {
current_task = dev->ev_sender;