+ --- 9.4.2-P2 released ---
+
+2406. [bug] Some operating systems have FD_SETSIZE set to a
+ low value by default, which can cause resource
+ exhaustion when many simultaneous connections are
+ open. Linux in particular makes it difficult to
+ increase this value. To use more sockets with
+ select(), set ISC_SOCKET_FDSETSIZE. Example:
+ STD_CDEFINES="-DISC_SOCKET_FDSETSIZE=4096" ./configure
+ (This should not be necessary in most cases, and
+ never for an authoritative-only server.) [RT #18328]
+
+2404. [port] hpux: files unlimited support.
+
+2403. [bug] TSIG context leak. [RT #18341]
+
+2402. [port] Support Solaris 2.11 and over. [RT #18362]
+
+2401. [bug] Expect to get E[MN]FILE errno internal_accept()
+ (from accept() or fcntl() system calls). [RT #18358]
+
+2399. [bug] Abort timeout queries to reduce the number of open
+ UDP sockets. [RT #18367]
+
+2398. [bug] Improve file descriptor management. New,
+ temporary, named.conf option reserved-sockets,
+ default 512. [RT #18344]
+
+2396. [bug] Don't set SO_REUSEADDR for randomized ports.
+ [RT #18336]
+
+2395. [port] Avoid warning and no effect from "files unlimited"
+ on Linux when running as root. [RT #18335]
+
+2394. [bug] Default configuration options set the limit for
+ open files to 'unlimited' as described in the
+ documentation. [RT #18331]
+
+2392. [bug] remove 'grep -q' from acl test script, some platforms
+ don't support it. [RT #18253]
+
+2322. [port] MacOS: work around the limitation of setrlimit()
+ for RLIMIT_NOFILE. [RT #17526]
+
--- 9.4.2-P1 released ---
2375. [security] Fully randomize UDP query ports to improve
[RT #17113]
2249. [bug] Only set Authentic Data bit if client requested
- DNSSEC, per RFC 3655 [RT #17175]
+ DNSSEC, per RFC 3655 [RT #17175]
2248. [cleanup] Fix several errors reported by Coverity. [RT #17160]
-Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 1996-2003 Internet Software Consortium.
Permission to use, copy, modify, and/or distribute this software for any
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
-$ISC: COPYRIGHT,v 1.9.18.4 2007/08/28 07:19:54 tbox Exp $
+$ISC: COPYRIGHT,v 1.9.18.4.10.1 2008/07/23 07:28:54 tbox Exp $
Portions Copyright (C) 1996-2001 Nominum, Inc.
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: dighost.c,v 1.259.18.43 2007/08/28 07:19:55 tbox Exp $ */
+/* $ISC: dighost.c,v 1.259.18.43.10.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file
* \note
sockcount++;
debug("sockcount=%d", sockcount);
if (specified_source)
- result = isc_socket_bind(query->sock, &bind_address);
+ result = isc_socket_bind(query->sock, &bind_address,
+ ISC_SOCKET_REUSEADDRESS);
else {
if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) &&
have_ipv4)
isc_sockaddr_any(&bind_any);
else
isc_sockaddr_any6(&bind_any);
- result = isc_socket_bind(query->sock, &bind_any);
+ result = isc_socket_bind(query->sock, &bind_any, 0);
}
check_result(result, "isc_socket_bind");
bringup_timer(query, TCP_TIMEOUT);
sockcount++;
debug("sockcount=%d", sockcount);
if (specified_source) {
- result = isc_socket_bind(query->sock, &bind_address);
+ result = isc_socket_bind(query->sock, &bind_address,
+ ISC_SOCKET_REUSEADDRESS);
} else {
isc_sockaddr_anyofpf(&bind_any,
isc_sockaddr_pf(&query->sockaddr));
- result = isc_socket_bind(query->sock, &bind_any);
+ result = isc_socket_bind(query->sock, &bind_any, 0);
}
check_result(result, "isc_socket_bind");
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: client.c,v 1.219.18.28.10.1 2008/05/22 21:28:04 each Exp $ */
+/* $ISC: client.c,v 1.219.18.28.10.2 2008/07/23 07:28:54 tbox Exp $ */
#include <config.h>
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: config.c,v 1.47.18.32 2007/09/13 05:04:01 each Exp $ */
+/* $ISC: config.c,v 1.47.18.32.10.3 2008/07/23 23:48:17 tbox Exp $ */
/*! \file */
#ifndef WIN32
" coresize default;\n\
datasize default;\n\
- files default;\n\
+ files unlimited;\n\
stacksize default;\n"
#endif
" deallocate-on-exit true;\n\
use-ixfr true;\n\
edns-udp-size 4096;\n\
max-udp-size 4096;\n\
+ reserved-sockets 512;\n\
\n\
/* view */\n\
allow-notify {none;};\n\
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: controlconf.c,v 1.40.18.10 2006/12/07 04:53:02 marka Exp $ */
+/* $ISC: controlconf.c,v 1.40.18.10.40.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file */
type, &listener->sock);
if (result == ISC_R_SUCCESS)
- result = isc_socket_bind(listener->sock,
- &listener->address);
+ result = isc_socket_bind(listener->sock, &listener->address,
+ ISC_SOCKET_REUSEADDRESS);
if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) {
listener->perm = cfg_obj_asuint32(cfg_tuple_get(control,
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: interfacemgr.c,v 1.76.18.8 2006/07/20 01:10:30 marka Exp $ */
+/* $ISC: interfacemgr.c,v 1.76.18.8.44.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file */
#ifndef ISC_ALLOW_MAPPED
isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE);
#endif
- result = isc_socket_bind(ifp->tcpsocket, &ifp->addr);
+ result = isc_socket_bind(ifp->tcpsocket, &ifp->addr,
+ ISC_SOCKET_REUSEADDRESS);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"binding TCP socket: %s",
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: lwresd.c,v 1.46.18.7 2006/03/02 00:37:21 marka Exp $ */
+/* $ISC: lwresd.c,v 1.46.18.7.52.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file
* \brief
return (result);
}
- result = isc_socket_bind(sock, &listener->address);
+ result = isc_socket_bind(sock, &listener->address,
+ ISC_SOCKET_REUSEADDRESS);
if (result != ISC_R_SUCCESS) {
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&listener->address, socktext,
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2008 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
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $ISC: named.conf.docbook,v 1.1.2.29 2007/08/28 07:20:01 tbox Exp $ -->
+<!-- $ISC: named.conf.docbook,v 1.1.2.29.12.2 2008/07/23 23:48:17 tbox Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
<year>2005</year>
<year>2006</year>
<year>2007</year>
+ <year>2008</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
port <replaceable>integer</replaceable>;
querylog <replaceable>boolean</replaceable>;
recursing-file <replaceable>quoted_string</replaceable>;
+ reserved-sockets <replaceable>integer</replaceable>;
random-device <replaceable>quoted_string</replaceable>;
recursive-clients <replaceable>integer</replaceable>;
serial-query-rate <replaceable>integer</replaceable>;
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: server.c,v 1.419.18.57.10.1 2008/05/22 21:28:04 each Exp $ */
+/* $ISC: server.c,v 1.419.18.57.10.3 2008/07/23 12:04:32 marka Exp $ */
/*! \file */
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
{
- isc_result_t result;
- isc_interval_t interval;
- cfg_parser_t *parser = NULL;
+ cfg_aclconfctx_t aclconfctx;
cfg_obj_t *config;
- const cfg_obj_t *options;
- const cfg_obj_t *views;
+ cfg_parser_t *parser = NULL;
+ const cfg_listelt_t *element;
+ const cfg_obj_t *builtin_views;
+ const cfg_obj_t *maps[3];
const cfg_obj_t *obj;
+ const cfg_obj_t *options;
const cfg_obj_t *v4ports, *v6ports;
- const cfg_obj_t *maps[3];
- const cfg_obj_t *builtin_views;
- const cfg_listelt_t *element;
+ const cfg_obj_t *views;
dns_view_t *view = NULL;
dns_view_t *view_next;
- dns_viewlist_t viewlist;
dns_viewlist_t tmpviewlist;
- cfg_aclconfctx_t aclconfctx;
- isc_uint32_t interface_interval;
- isc_uint32_t heartbeat_interval;
- isc_uint32_t udpsize;
+ dns_viewlist_t viewlist;
in_port_t listen_port;
int i;
+ isc_interval_t interval;
+ isc_resourcevalue_t files;
+ isc_result_t result;
+ isc_uint32_t heartbeat_interval;
+ isc_uint32_t interface_interval;
+ isc_uint32_t reserved;
+ isc_uint32_t udpsize;
cfg_aclconfctx_init(&aclconfctx);
ISC_LIST_INIT(viewlist);
*/
set_limits(maps);
+ /*
+ * Sanity check on "files" limit.
+ */
+ result = isc_resource_curlimit(isc_resource_openfiles, &files);
+ if (result == ISC_R_SUCCESS && files < FD_SETSIZE) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "the 'files' limit (%" ISC_PRINT_QUADFORMAT "u) "
+ "is less than FD_SETSIZE (%d), increase "
+ "'files' in named.conf or recompile with a "
+ "smaller FD_SETSIZE.", files, FD_SETSIZE);
+ if (files > FD_SETSIZE)
+ files = FD_SETSIZE;
+ } else
+ files = FD_SETSIZE;
+
+ /*
+ * Set the number of socket reserved for TCP, stdio etc.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "reserved-sockets", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ reserved = cfg_obj_asuint32(obj);
+ if (files < 128U) /* Prevent underflow. */
+ reserved = 0;
+ else if (reserved > files - 128U) /* Mimimum UDP space. */
+ reserved = files - 128;
+ if (reserved < 128U) /* Mimimum TCP/stdio space. */
+ reserved = 128;
+ if (reserved + 128U > files) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "less than 128 UDP sockets available after "
+ "applying 'reserved-sockets' and 'files'");
+ }
+ isc__socketmgr_setreserved(ns_g_socketmgr, reserved);
+
/*
* Configure various server options.
*/
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rndc.c,v 1.96.18.17 2006/08/04 03:03:41 marka Exp $ */
+/* $ISC: rndc.c,v 1.96.18.17.42.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file */
DO("create socket", isc_socket_create(socketmgr, pf, type, &sock));
switch (isc_sockaddr_pf(addr)) {
case AF_INET:
- DO("bind socket", isc_socket_bind(sock, &local4));
+ DO("bind socket", isc_socket_bind(sock, &local4, 0));
break;
case AF_INET6:
- DO("bind socket", isc_socket_bind(sock, &local6));
+ DO("bind socket", isc_socket_bind(sock, &local6, 0));
break;
default:
break;
*-solaris2.[89])
hack_shutup_pthreadonceinit=yes
;;
- *-solaris2.10)
+ *-solaris2.1[0-9])
hack_shutup_pthreadonceinit=yes
;;
esac
-# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.15 $)
+AC_REVISION($Revision: 1.16 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
[*-solaris2.[89]])
hack_shutup_pthreadonceinit=yes
;;
- *-solaris2.10)
+ *-solaris2.1[0-9])
hack_shutup_pthreadonceinit=yes
;;
esac
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $ISC: Bv9ARM-book.xml,v 1.241.18.82.8.1 2008/05/22 21:28:04 each Exp $ -->
+<!-- File: $ISC: Bv9ARM-book.xml,v 1.241.18.82.8.3 2008/07/23 12:04:32 marka Exp$ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
<year>2005</year>
<year>2006</year>
<year>2007</year>
+ <year>2008</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
<optional> max-transfer-idle-in <replaceable>number</replaceable>; </optional>
<optional> max-transfer-idle-out <replaceable>number</replaceable>; </optional>
<optional> tcp-clients <replaceable>number</replaceable>; </optional>
+ <optional> reserved-sockets <replaceable>number</replaceable>; </optional>
<optional> recursive-clients <replaceable>number</replaceable>; </optional>
<optional> serial-query-rate <replaceable>number</replaceable>; </optional>
<optional> serial-queries <replaceable>number</replaceable>; </optional>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>reserved-sockets</command></term>
+ <listitem>
+ <para>
+ The number of file descriptors reserved for TCP, stdio,
+ etc. This needs to be big enough to cover the number of
+ interfaces named listens on, tcp-clients as well as
+ to provide room for outgoing TCP queries and incoming zone
+ transfers. The default is <literal>512</literal>.
+ The minimum value is <literal>128</literal> and the
+ maximum value is <literal>128</literal> less than
+ 'files' or FD_SETSIZE (whichever is smaller). This
+ option may be removed in the future.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><command>max-cache-size</command></term>
<listitem>
LIBINTERFACE = 35
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: dispatch.c,v 1.116.18.19.12.1 2008/05/22 21:28:06 each Exp $ */
+/* $ISC: dispatch.c,v 1.116.18.19.12.5 2008/07/23 23:16:43 marka Exp $ */
/*! \file */
}
/*
- * ARC4 random number generator obtained from OpenBSD
+ * ARC4 random number generator derived from OpenBSD.
+ * Only dispatch_arc4random() and dispatch_arc4uniformrandom() are expected
+ * to be called from general dispatch routines; the rest of them are subroutines
+ * for these two.
+ *
+ * The original copyright follows:
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static void
dispatch_arc4init(arc4ctx_t *actx) {
static isc_result_t
create_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
- isc_socket_t **sockp)
+ unsigned int options, isc_socket_t **sockp)
{
isc_socket_t *sock;
isc_result_t result;
#ifndef ISC_ALLOW_MAPPED
isc_socket_ipv6only(sock, ISC_TRUE);
#endif
- result = isc_socket_bind(sock, local);
+ result = isc_socket_bind(sock, local, options);
if (result != ISC_R_SUCCESS) {
isc_socket_detach(&sock);
return (result);
attributes &= ~DNS_DISPATCHATTR_RANDOMPORT;
goto getsocket;
}
- result = create_socket(sockmgr, &localaddr_bound, &sock);
+ result = create_socket(sockmgr, &localaddr_bound, 0, &sock);
if (result == ISC_R_ADDRINUSE) {
if (++k == 1024)
attributes &= ~DNS_DISPATCHATTR_RANDOMPORT;
isc_sockaddr_t localaddr_listen;
isc_sockaddr_setport(&localaddr_bound, 0);
- result = create_socket(sockmgr, &localaddr_bound, &sock);
+ result = create_socket(sockmgr, &localaddr_bound, 0, &sock);
if (result != ISC_R_SUCCESS) {
if (++k == 1024)
attributes &= ~DNS_DISPATCHATTR_RANDOMPORT;
localport = isc_sockaddr_getport(&localaddr_listen);
#endif
} else
- result = create_socket(sockmgr, localaddr, &sock);
+ result = create_socket(sockmgr, localaddr,
+ ISC_SOCKET_REUSEADDRESS, &sock);
if (result != ISC_R_SUCCESS)
goto deallocate_dispatch;
if ((attributes & DNS_DISPATCHATTR_RANDOMPORT) == 0 &&
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: dispatch.h,v 1.48.18.5.12.1 2008/05/22 21:28:06 each Exp $ */
+/* $ISC: dispatch.h,v 1.48.18.5.12.2 2008/07/23 07:28:56 tbox Exp $ */
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: request.c,v 1.72.18.5 2006/08/21 00:40:53 marka Exp $ */
+/* $ISC: request.c,v 1.72.18.5.42.2 2008/07/23 07:28:56 tbox Exp $ */
/*! \file */
if (srcaddr == NULL) {
isc_sockaddr_anyofpf(&bind_any,
isc_sockaddr_pf(destaddr));
- result = isc_socket_bind(socket, &bind_any);
+ result = isc_socket_bind(socket, &bind_any, 0);
} else {
src = *srcaddr;
isc_sockaddr_setport(&src, 0);
- result = isc_socket_bind(socket, &src);
+ result = isc_socket_bind(socket, &src, 0);
}
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: resolver.c,v 1.284.18.66.8.1 2008/05/22 21:28:06 each Exp $ */
+/* $ISC: resolver.c,v 1.284.18.66.8.4 2008/07/24 05:00:48 jinmei Exp $ */
/*! \file */
goto cleanup_query;
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- result = isc_socket_bind(query->tcpsocket, &addr);
+ result = isc_socket_bind(query->tcpsocket, &addr, 0);
if (result != ISC_R_SUCCESS)
goto cleanup_socket;
#endif
static void
fctx_timeout(isc_task_t *task, isc_event_t *event) {
fetchctx_t *fctx = event->ev_arg;
+ isc_timerevent_t *tevent = (isc_timerevent_t *)event;
+ resquery_t *query;
REQUIRE(VALID_FCTX(fctx));
fctx->timeouts++;
/*
* We could cancel the running queries here, or we could let
- * them keep going. Right now we choose the latter...
+ * them keep going. Since we normally use separate sockets for
+ * different queries, we adopt the former approach to reduce
+ * the number of open sockets: cancel the oldest query if it
+ * expired after the query had started (this is usually the
+ * case but is not always so, depending on the task schedule
+ * timing).
*/
+ query = ISC_LIST_HEAD(fctx->queries);
+ if (query != NULL &&
+ isc_time_compare(&tevent->due, &query->start) >= 0) {
+ fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
+ }
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
/*
* Our timer has triggered. Reestablish the fctx lifetime
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: xfrin.c,v 1.135.18.16 2007/10/31 01:59:47 marka Exp $ */
+/* $ISC: xfrin.c,v 1.135.18.16.10.3 2008/07/23 23:16:43 marka Exp $ */
/*! \file */
isc_sockettype_tcp,
&xfr->socket));
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr));
+ CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
+ ISC_SOCKET_REUSEADDRESS));
#endif
CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
xfrin_connect_done, xfr));
-LIBINTERFACE = 32
-LIBREVISION = 5
+LIBINTERFACE = 35
+LIBREVISION = 0
LIBAGE = 0
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: resource.h,v 1.5.18.2 2005/04/29 00:17:02 marka Exp $ */
+/* $ISC: resource.h,v 1.5.18.2.52.2 2008/07/23 23:48:17 tbox Exp $ */
#ifndef ISC_RESOURCE_H
#define ISC_RESOURCE_H 1
*\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
*/
+isc_result_t
+isc_resource_curlimit(isc_resource_t resource, isc_resourcevalue_t *value);
+/*
+ * Get the current limit on a resource.
+ *
+ * Requires:
+ * 'resource' is a valid member of the isc_resource_t enumeration.
+ *
+ * Returns:
+ * ISC_R_SUCCESS Success.
+ * ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_RESOURCE_H */
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket.h,v 1.57.18.6 2006/06/07 00:29:45 marka Exp $ */
+/* $ISC: socket.h,v 1.57.18.6.46.4 2008/07/23 23:16:43 marka Exp $ */
#ifndef ISC_SOCKET_H
#define ISC_SOCKET_H 1
*/
#define ISC_SOCKET_MAXSCATTERGATHER 8
+/*%
+ * In isc_socket_bind() set socket option SO_REUSEADDR prior to calling
+ * bind() if a non zero port is specified (AF_INET and AF_INET6).
+ */
+#define ISC_SOCKET_REUSEADDRESS 0x01U
+
/***
*** Types
***/
*/
isc_result_t
-isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp);
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp,
+ unsigned int options);
/*%<
* Bind 'socket' to '*addressp'.
*
* \li #ISC_R_FAILURE
*/
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t);
+/*%<
+ * Temporary. For use by named only.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_SOCKET_H */
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: timer.h,v 1.31.18.3 2005/10/26 06:50:50 marka Exp $ */
+/* $ISC: timer.h,v 1.31.18.3.52.2 2008/07/24 23:48:09 tbox Exp $ */
#ifndef ISC_TIMER_H
#define ISC_TIMER_H 1
#include <isc/event.h>
#include <isc/eventclass.h>
#include <isc/lang.h>
+#include <isc/time.h>
ISC_LANG_BEGINDECLS
typedef struct isc_timerevent {
struct isc_event common;
+ isc_time_t due;
} isc_timerevent_t;
#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: timer.c,v 1.73.18.7 2007/10/24 23:46:26 tbox Exp $ */
+/* $ISC: timer.c,v 1.73.18.7.10.3 2008/07/29 18:35:53 jinmei Exp $ */
/*! \file */
static void
dispatch(isc_timermgr_t *manager, isc_time_t *now) {
isc_boolean_t done = ISC_FALSE, post_event, need_schedule;
- isc_event_t *event;
+ isc_timerevent_t *event;
isc_eventtype_t type = 0;
isc_timer_t *timer;
isc_result_t result;
/*
* XXX We could preallocate this event.
*/
- event = isc_event_allocate(manager->mctx,
+ event = (isc_timerevent_t *)isc_event_allocate(manager->mctx,
timer,
type,
timer->action,
timer->arg,
sizeof(*event));
- if (event != NULL)
- isc_task_send(timer->task, &event);
- else
+ if (event != NULL) {
+ event->due = timer->due;
+ isc_task_send(timer->task,
+ ISC_EVENT_PTR(&event));
+ } else
UNEXPECTED_ERROR(__FILE__, __LINE__,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_TIMER,
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: app.c,v 1.50.18.2 2005/04/29 00:17:06 marka Exp $ */
+/* $ISC: app.c,v 1.50.18.2.50.1 2008/07/29 04:47:31 each Exp $ */
/*! \file */
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: resource.c,v 1.12 2004/03/05 05:11:46 marka Exp $ */
+/* $ISC: resource.c,v 1.12.944.4 2008/07/28 22:44:46 marka Exp $ */
#include <config.h>
#include <isc/result.h>
#include <isc/util.h>
+#ifdef __linux__
+#include <linux/fs.h> /* To get the large NR_OPEN. */
+#endif
+
+#ifdef __hpux
+#include <sys/dyntune.h>
+#endif
+
#include "errno2result.h"
static isc_result_t
if (unixresult == 0)
return (ISC_R_SUCCESS);
- else
- return (isc__errno2result(errno));
+
+#if defined(OPEN_MAX) && defined(__APPLE__)
+ /*
+ * The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the
+ * maximum possible value is OPEN_MAX. BIND8 used to use
+ * sysconf(_SC_OPEN_MAX) for such a case, but this value is much
+ * smaller than OPEN_MAX and is not really effective.
+ */
+ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
+ rl.rlim_cur = OPEN_MAX;
+ unixresult = setrlimit(unixresource, &rl);
+ if (unixresult == 0)
+ return (ISC_R_SUCCESS);
+ }
+#elif defined(NR_OPEN) && defined(__linux__)
+ /*
+ * Some Linux kernels don't accept RLIM_INFINIT; the maximum
+ * possible value is the NR_OPEN defined in linux/fs.h.
+ */
+ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
+ rl.rlim_cur = rl.rlim_max = NR_OPEN;
+ unixresult = setrlimit(unixresource, &rl);
+ if (unixresult == 0)
+ return (ISC_R_SUCCESS);
+ }
+#elif defined(__hpux)
+ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
+ uint64_t maxfiles;
+ if (gettune("maxfiles_lim", &maxfiles) == 0) {
+ rl.rlim_cur = rl.rlim_max = maxfiles;
+ unixresult = setrlimit(unixresource, &rl);
+ if (unixresult == 0)
+ return (ISC_R_SUCCESS);
+ }
+ }
+#endif
+ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
+ if (getrlimit(unixresource, &rl) == 0) {
+ rl.rlim_cur = rl.rlim_max;
+ unixresult = setrlimit(unixresource, &rl);
+ if (unixresult == 0)
+ return (ISC_R_SUCCESS);
+ }
+ }
+ return (isc__errno2result(errno));
}
isc_result_t
return (result);
}
+
+isc_result_t
+isc_resource_curlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
+ int unixresult;
+ int unixresource;
+ struct rlimit rl;
+ isc_result_t result;
+
+ result = resource2rlim(resource, &unixresource);
+ if (result == ISC_R_SUCCESS) {
+ unixresult = getrlimit(unixresource, &rl);
+ INSIST(unixresult == 0);
+ *value = rl.rlim_cur;
+ }
+
+ return (result);
+}
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket.c,v 1.237.18.29 2007/08/28 07:20:06 tbox Exp $ */
+/* $ISC: socket.c,v 1.237.18.29.10.6 2008/07/29 04:47:31 each Exp $ */
/*! \file */
#include "socket_p.h"
#endif /* ISC_PLATFORM_USETHREADS */
+/*%
+ * Max number of open sockets. In the vast majority of cases the default size
+ * of FD_SETSIZE should be fine, and this constant should be increased only
+ * when absolutely necessary and possible, i.e., the server is exhausting all
+ * available file descriptors (up to FD_SETSIZE) and the select() function
+ * and FD_xxx macros support larger values than FD_SETSIZE (which may not
+ * always by true, but we keep using some of them to ensure as much
+ * portability as possible). Note also that overall server performance
+ * may be rather worsened with a larger value of this constant due to
+ * inherent scalability problems of select().
+ *
+ * As a special note, this value shouldn't have to be touched if
+ * this is a build for an authoritative only DNS server.
+ */
+
+#ifndef ISC_SOCKET_FDSETSIZE
+#define ISC_SOCKET_FDSETSIZE FD_SETSIZE
+#endif
+
+/*%
+ * Mac OS X needs a special definition to support larger values in select()
+ */
+#if ISC_SOCKET_FDSETSIZE > FD_SETSIZE
+#ifdef __APPLE__
+#define _DARWIN_UNLIMITED_SELECT
+#endif /* __APPLE__ */
+#endif
+
/*%
* Some systems define the socket length argument as an int, some as size_t,
* some as socklen_t. This is here so it can be easily changed if needed.
unsigned int magic;
isc_mem_t *mctx;
isc_mutex_t lock;
+ int fd_bufsize;
+ int fdsize;
/* Locked by manager lock. */
ISC_LIST(isc_socket_t) socklist;
- fd_set *read_fds, *read_fds_copy;
- fd_set *write_fds, *write_fds_copy;
- isc_socket_t **fds;
- int *fdstate;
+ fd_set *read_fds;
+ fd_set *read_fds_copy;
+ fd_set *write_fds;
+ fd_set *write_fds_copy;
+ isc_socket_t **fds;
+ int *fdstate;
int maxfd;
- int fdsize;
+ int reserved; /* unlocked */
#ifdef ISC_PLATFORM_USETHREADS
isc_thread_t watcher;
isc_condition_t shutdown_ok;
struct msghdr *, struct iovec *, size_t *);
static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-static void expand_fdsets(isc_socketmgr_t *, int, isc_mem_t *);
+static void cleanup_fdsets(isc_socketmgr_t *, isc_mem_t *);
+static isc_result_t create_fdsets(isc_socketmgr_t *, isc_mem_t *);
+static isc_result_t expand_fdsets(isc_socketmgr_t *, int, isc_mem_t *);
#define SELECT_POKE_SHUTDOWN (-1)
#define SELECT_POKE_NOTHING (-2)
*socketp = NULL;
}
-static void
-expand_fdsets(isc_socketmgr_t *manager, int maxfd, isc_mem_t *mctx) {
- void *tmp;
- int newsize = manager->fdsize;
-
- if (mctx == NULL)
- mctx = manager->mctx;
-
- do {
- newsize += FD_SETSIZE;
- } while (newsize <= maxfd);
-
- tmp = isc_mem_get(mctx, sizeof(manager->fds[0]) * newsize);
- memset(tmp, 0, sizeof(manager->fds[0]) * newsize);
- if (manager->fdsize) {
- memcpy(tmp, manager->fds,
- sizeof(manager->fds[0]) * manager->fdsize);
- isc_mem_put(mctx, manager->fds,
- sizeof(manager->fds[0]) * manager->fdsize);
- }
- manager->fds = tmp;
-
- tmp = isc_mem_get(mctx, sizeof(manager->fdstate[0]) * newsize);
- memset(tmp, 0, sizeof(manager->fdstate[0]) * newsize);
- if (manager->fdsize) {
- memcpy(tmp, manager->fdstate,
- sizeof(manager->fdstate[0]) * manager->fdsize);
- isc_mem_put(mctx, manager->fdstate,
- sizeof(manager->fdstate[0]) * manager->fdsize);
- }
- manager->fdstate = tmp;
-
- tmp = isc_mem_get(mctx, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- memset(tmp, 0, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- if (manager->fdsize) {
- memcpy(tmp, manager->read_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- isc_mem_put(mctx, manager->read_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- }
- manager->read_fds = tmp;
-
- tmp = isc_mem_get(mctx, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- memset(tmp, 0, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- if (manager->fdsize) {
- memcpy(tmp, manager->write_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- isc_mem_put(mctx, manager->write_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- }
- manager->write_fds = tmp;
-
- /* Don't bother copying these, they are copied before use */
- tmp = isc_mem_get(mctx, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- memset(tmp, 0, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- if (manager->fdsize) {
- isc_mem_put(mctx, manager->read_fds_copy,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- }
- manager->read_fds_copy = tmp;
-
- tmp = isc_mem_get(mctx, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- memset(tmp, 0, howmany(newsize, NFDBITS) * sizeof(fd_mask));
- if (manager->fdsize) {
- isc_mem_put(mctx, manager->write_fds_copy,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- }
- manager->write_fds_copy = tmp;
-
- manager->fdsize = newsize;
-}
-
#ifdef SO_BSDCOMPAT
/*
* This really should not be necessary to do. Having to workout
#ifdef F_DUPFD
/*
- * Leave a space for stdio to work in.
+ * Leave a space for stdio and TCP to work in.
*/
- if (sock->fd >= 0 && sock->fd < 20) {
+ if (manager->reserved != 0 && type == isc_sockettype_udp &&
+ sock->fd >= 0 && sock->fd < manager->reserved) {
+ int new, tmp;
+ new = fcntl(sock->fd, F_DUPFD, manager->reserved);
+ tmp = errno;
+ (void)close(sock->fd);
+ errno = tmp;
+ sock->fd = new;
+ err = "isc_socket_create: fcntl/reserved";
+ } else if (sock->fd >= 0 && sock->fd < 20) {
int new, tmp;
new = fcntl(sock->fd, F_DUPFD, 20);
tmp = errno;
}
#endif
- if (sock->fd >= sock->manager->fdsize)
- expand_fdsets(sock->manager, sock->fd, NULL);
+ if (sock->fd >= manager->fdsize &&
+ expand_fdsets(sock->manager, sock->fd, NULL) != ISC_R_SUCCESS) {
+ (void)close(sock->fd);
+ isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ isc_msgcat, ISC_MSGSET_SOCKET,
+ ISC_MSG_TOOMANYFDS,
+ "%s: too many open file descriptors", "socket");
+ free_socket(&sock);
+ return (ISC_R_NORESOURCES);
+ }
if (sock->fd < 0) {
free_socket(&sock);
(void)close(fd);
errno = tmp;
fd = new;
- err = "fcntl";
+ err = "accept/fcntl";
}
#endif
if (SOFT_ERROR(errno))
goto soft_error;
switch (errno) {
- case ENOBUFS:
case ENFILE:
+ case EMFILE:
+ isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ isc_msgcat, ISC_MSGSET_SOCKET,
+ ISC_MSG_TOOMANYFDS,
+ "%s: too many open file descriptors",
+ err);
+ goto soft_error;
+
+ case ENOBUFS:
case ENOMEM:
case ECONNRESET:
case ECONNABORTED:
sock->pf);
(void)close(fd);
goto soft_error;
- } else if (fd >= sock->manager->fdsize) {
- expand_fdsets(sock->manager, fd, NULL);
+ } else if (fd >= manager->fdsize &&
+ expand_fdsets(sock->manager, fd, NULL) != ISC_R_SUCCESS) {
+ isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ isc_msgcat, ISC_MSGSET_SOCKET,
+ ISC_MSG_TOOMANYFDS,
+ "%s: too many open file descriptors",
+ "accept");
+ (void)close(fd);
+ goto soft_error;
}
}
*/
dev->address = dev->newsocket->address;
- if (manager->maxfd < fd)
- manager->maxfd = fd;
- if (manager->maxfd >= manager->fdsize)
- expand_fdsets(manager, manager->maxfd, NULL);
-
manager->fds[fd] = dev->newsocket;
manager->fdstate[fd] = MANAGED;
+ if (manager->maxfd < fd)
+ manager->maxfd = fd;
socket_log(sock, &dev->newsocket->address, CREATION,
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
isc_boolean_t done;
int ctlfd;
int cc;
- fd_set readfds;
- fd_set writefds;
int msg, fd;
int maxfd;
char strbuf[ISC_STRERRORSIZE];
done = ISC_FALSE;
while (!done) {
do {
- readfds = manager->read_fds;
- writefds = manager->write_fds;
+ memcpy(manager->read_fds_copy, manager->read_fds,
+ manager->fd_bufsize);
+ memcpy(manager->write_fds_copy, manager->write_fds,
+ manager->fd_bufsize);
maxfd = manager->maxfd + 1;
UNLOCK(&manager->lock);
- cc = select(maxfd, &readfds, &writefds, NULL, NULL);
+ cc = select(maxfd, manager->read_fds_copy,
+ manager->write_fds_copy, NULL, NULL);
if (cc < 0) {
if (!SOFT_ERROR(errno)) {
isc__strerror(errno, strbuf,
/*
* Process reads on internal, control fd.
*/
- if (FD_ISSET(ctlfd, &readfds)) {
+ if (FD_ISSET(ctlfd, manager->read_fds_copy)) {
for (;;) {
select_readmsg(manager, &fd, &msg);
}
}
- process_fds(manager, maxfd, &readfds, &writefds);
+ process_fds(manager, maxfd, manager->read_fds_copy,
+ manager->write_fds_copy);
}
manager_log(manager, TRACE,
}
#endif /* ISC_PLATFORM_USETHREADS */
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) {
+
+ REQUIRE(VALID_MANAGER(manager));
+
+ manager->reserved = reserved;
+}
+
+/*
+ * Initialize fdsets in socketmgr structure.
+ */
+static isc_result_t
+create_fdsets(isc_socketmgr_t *manager, isc_mem_t *mctx) {
+#if ISC_SOCKET_FDSETSIZE > FD_SETSIZE
+ manager->fdsize = ISC_SOCKET_FDSETSIZE;
+ manager->fd_bufsize = howmany(ISC_SOCKET_FDSETSIZE, NFDBITS) *
+ sizeof(fd_mask);
+#else
+ manager->fdsize = FD_SETSIZE;
+ manager->fd_bufsize = sizeof(fd_set);
+#endif
+
+ manager->fds = NULL;
+ manager->fdstate = NULL;
+ manager->read_fds = NULL;
+ manager->read_fds_copy = NULL;
+ manager->write_fds = NULL;
+ manager->write_fds_copy = NULL;
+
+ manager->fds = isc_mem_get(mctx,
+ manager->fdsize * sizeof(manager->fds[0]));
+ if (manager->fds == NULL)
+ goto fail;
+
+ manager->fdstate = isc_mem_get(mctx, manager->fdsize *
+ sizeof(manager->fdstate[0]));
+ if (manager->fdstate == NULL)
+ goto fail;
+
+ manager->read_fds = isc_mem_get(mctx, manager->fd_bufsize);
+ if (manager->read_fds == NULL)
+ goto fail;
+ manager->read_fds_copy = isc_mem_get(mctx, manager->fd_bufsize);
+ if (manager->read_fds_copy == NULL)
+ goto fail;
+ manager->write_fds = isc_mem_get(mctx, manager->fd_bufsize);
+ if (manager->write_fds == NULL)
+ goto fail;
+ manager->write_fds_copy = isc_mem_get(mctx, manager->fd_bufsize);
+ if (manager->write_fds_copy == NULL)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ cleanup_fdsets(manager, mctx);
+ return (ISC_R_NOMEMORY);
+}
+
+/*
+ * Clean up fdsets in socketmgr structure.
+ */
+static void
+cleanup_fdsets(isc_socketmgr_t *manager, isc_mem_t *mctx) {
+ if (manager->fds != NULL) {
+ isc_mem_put(mctx, manager->fds,
+ manager->fdsize * sizeof(manager->fds[0]));
+ }
+ if (manager->fdstate != NULL) {
+ isc_mem_put(mctx, manager->fdstate,
+ manager->fdsize * sizeof(manager->fdstate[0]));
+ }
+ if (manager->read_fds != NULL)
+ isc_mem_put(mctx, manager->read_fds, manager->fd_bufsize);
+ if (manager->read_fds_copy != NULL)
+ isc_mem_put(mctx, manager->read_fds_copy, manager->fd_bufsize);
+ if (manager->write_fds != NULL)
+ isc_mem_put(mctx, manager->write_fds, manager->fd_bufsize);
+ if (manager->write_fds_copy != NULL)
+ isc_mem_put(mctx, manager->write_fds_copy, manager->fd_bufsize);
+}
+
+/*
+ * Expand fdsets in socketmgr structure.
+ */
+static isc_result_t
+expand_fdsets(isc_socketmgr_t *manager, int maxfd, isc_mem_t *mctx) {
+ fd_set *read_fds = NULL, *read_fds_copy = NULL;
+ fd_set *write_fds = NULL, *write_fds_copy = NULL;
+ isc_socket_t **fds = NULL;
+ int *fdstate = NULL, fdsize, fd_bufsize;
+
+ if (mctx == NULL)
+ mctx = manager->mctx;
+
+ fdsize = manager->fdsize;
+ do {
+ fdsize <<= 1;
+ } while (fdsize <= maxfd);
+ fd_bufsize = howmany(fdsize, NFDBITS) * sizeof(fd_mask);
+
+ fds = isc_mem_get(mctx, sizeof(manager->fds[0]) * fdsize);
+ fdstate = isc_mem_get(mctx, sizeof(manager->fdstate[0]) * fdsize);
+ read_fds = isc_mem_get(mctx, fd_bufsize);
+ write_fds = isc_mem_get(mctx, fd_bufsize);
+ read_fds_copy = isc_mem_get(mctx, fd_bufsize);
+ write_fds_copy = isc_mem_get(mctx, fd_bufsize);
+ if (fds == NULL || fdstate == NULL || read_fds == NULL ||
+ write_fds == NULL || read_fds_copy == NULL || write_fds_copy == NULL)
+ goto fail;
+
+ /* Copy old values. */
+ memset(fds, 0, sizeof(manager->fds[0]) * fdsize);
+ if (manager->fdsize) {
+ memcpy(fds, manager->fds,
+ sizeof(manager->fds[0]) * manager->fdsize);
+ isc_mem_put(mctx, manager->fds,
+ sizeof(manager->fds[0]) * manager->fdsize);
+ }
+ manager->fds = fds;
+
+ memset(fdstate, 0, sizeof(manager->fdstate[0]) * fdsize);
+ if (manager->fdsize) {
+ memcpy(fdstate, manager->fdstate,
+ sizeof(manager->fdstate[0]) * manager->fdsize);
+ isc_mem_put(mctx, manager->fdstate,
+ sizeof(manager->fdstate[0]) * manager->fdsize);
+ }
+ manager->fdstate = fdstate;
+
+ memset(read_fds, 0, fd_bufsize);
+ if (manager->fdsize) {
+ memcpy(read_fds, manager->read_fds, manager->fd_bufsize);
+ isc_mem_put(mctx, manager->read_fds, manager->fd_bufsize);
+ }
+ manager->read_fds = read_fds;
+
+ memset(write_fds, 0, fd_bufsize);
+ if (manager->fdsize) {
+ memcpy(write_fds, manager->write_fds, manager->fd_bufsize);
+ isc_mem_put(mctx, manager->write_fds, manager->fd_bufsize);
+ }
+ manager->write_fds = write_fds;
+
+ /* Don't bother copying these, they are copied before use */
+ memset(read_fds_copy, 0, howmany(fdsize, NFDBITS) * sizeof(fd_mask));
+ if (manager->fdsize)
+ isc_mem_put(mctx, manager->read_fds_copy, manager->fd_bufsize);
+ manager->read_fds_copy = read_fds_copy;
+
+ memset(write_fds_copy, 0, howmany(fdsize, NFDBITS) * sizeof(fd_mask));
+ if (manager->fdsize)
+ isc_mem_put(mctx, manager->write_fds_copy, manager->fd_bufsize);
+ manager->write_fds_copy = write_fds_copy;
+
+ manager->fdsize = fdsize;
+ manager->fd_bufsize = fd_bufsize;
+
+ return (ISC_R_SUCCESS);
+ fail:
+ if (fds != NULL) {
+ isc_mem_put(mctx, fds,
+ howmany(fdsize, NFDBITS) * sizeof(fd_mask));
+ }
+ if (fdstate != NULL)
+ isc_mem_put(mctx, fdstate, sizeof(fdstate[0]) * fdsize);
+ if (read_fds != NULL)
+ isc_mem_put(mctx, read_fds, fd_bufsize);
+ if (write_fds != NULL)
+ isc_mem_put(mctx, write_fds, fd_bufsize);
+ if (read_fds_copy != NULL)
+ isc_mem_put(mctx, read_fds_copy, fd_bufsize);
+ if (write_fds_copy != NULL)
+ isc_mem_put(mctx, write_fds_copy, fd_bufsize);
+ return (ISC_R_NOMEMORY);
+}
+
+
/*
* Create a new socket manager.
*/
if (manager == NULL)
return (ISC_R_NOMEMORY);
+ result = create_fdsets(manager, mctx);
+ if (result != ISC_R_SUCCESS) {
+ cleanup_fdsets(manager, mctx);
+ isc_mem_put(mctx, manager, sizeof(*manager));
+ return (result);
+ }
+
manager->magic = SOCKET_MANAGER_MAGIC;
manager->mctx = NULL;
- manager->read_fds = NULL;
- manager->write_fds = NULL;
- manager->fds = NULL;
- manager->fdstate = NULL;
- manager->fdsize = NULL;
+ memset(manager->fds, 0, sizeof(manager->fds[0]) * manager->fdsize);
ISC_LIST_INIT(manager->socklist);
result = isc_mutex_init(&manager->lock);
if (result != ISC_R_SUCCESS) {
+ cleanup_fdsets(manager, mctx);
isc_mem_put(mctx, manager, sizeof(*manager));
return (result);
}
#ifdef ISC_PLATFORM_USETHREADS
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
+ cleanup_fdsets(manager, mctx);
DESTROYLOCK(&manager->lock);
isc_mem_put(mctx, manager, sizeof(*manager));
UNEXPECTED_ERROR(__FILE__, __LINE__,
* select/poll loop when something internal needs to be done.
*/
if (pipe(manager->pipe_fds) != 0) {
+ cleanup_fdsets(manager, mctx);
DESTROYLOCK(&manager->lock);
isc_mem_put(mctx, manager, sizeof(*manager));
isc__strerror(errno, strbuf, sizeof(strbuf));
/*
* Set up initial state for the select loop
*/
+ memset(manager->read_fds, 0, manager->fd_bufsize);
+ memset(manager->write_fds, 0, manager->fd_bufsize);
#ifdef ISC_PLATFORM_USETHREADS
FD_SET(manager->pipe_fds[0], manager->read_fds);
manager->maxfd = manager->pipe_fds[0];
#else /* ISC_PLATFORM_USETHREADS */
manager->maxfd = 0;
#endif /* ISC_PLATFORM_USETHREADS */
- expand_fdsets(manager, manager->maxfd, mctx);
+ manager->reserved = 0;
+ memset(manager->fdstate, 0,
+ manager->fdsize * sizeof(manager->fdstate[0]));
#ifdef ISC_PLATFORM_USETHREADS
/*
(void)isc_condition_destroy(&manager->shutdown_ok);
#endif /* ISC_PLATFORM_USETHREADS */
- if (manager->fdsize) {
- for (i = 0; i < manager->fdsize; i++)
- if (manager->fdstate[i] == CLOSE_PENDING)
- (void)close(i);
- isc_mem_put(manager->mctx, manager->fds,
- sizeof(manager->fds[0]) * manager->fdsize);
- isc_mem_put(manager->mctx, manager->fdstate,
- sizeof(manager->fdstate[0]) * manager->fdsize);
- isc_mem_put(manager->mctx, manager->read_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- isc_mem_put(manager->mctx, manager->write_fds,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- isc_mem_put(manager->mctx, manager->read_fds_copy,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- isc_mem_put(manager->mctx, manager->write_fds_copy,
- howmany(manager->fdsize, NFDBITS) * sizeof(fd_mask));
- }
+ for (i = 0; i < manager->fdsize; i++)
+ if (manager->fdstate[i] == CLOSE_PENDING)
+ (void)close(i);
DESTROYLOCK(&manager->lock);
+ cleanup_fdsets(manager, manager->mctx);
manager->magic = 0;
mctx= manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
}
isc_result_t
-isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options) {
char strbuf[ISC_STRERRORSIZE];
int on = 1;
if (sock->pf == AF_UNIX)
goto bind_socket;
#endif
- if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
+ if ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
+ isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on)) < 0) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
if (socketmgr == NULL)
*maxfd = 0;
else {
-
/* Prepare duplicates of fd_sets, as select() will modify */
- if (socketmgr->fdsize) {
- memcpy(socketmgr->read_fds_copy, socketmgr->read_fds,
- howmany(socketmgr->fdsize, NFDBITS) *
- sizeof(fd_mask));
- memcpy(socketmgr->write_fds_copy, socketmgr->write_fds,
- howmany(socketmgr->fdsize, NFDBITS) *
- sizeof(fd_mask));
- }
+ memcpy(socketmgr->read_fds_copy, socketmgr->read_fds,
+ socketmgr->fd_bufsize);
+ memcpy(socketmgr->write_fds_copy, socketmgr->write_fds,
+ socketmgr->fd_bufsize);
*readset = socketmgr->read_fds_copy;
*writeset = socketmgr->write_fds_copy;
*maxfd = socketmgr->maxfd + 1;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket_p.h,v 1.7.18.2 2005/04/29 00:17:08 marka Exp $ */
+/* $ISC: socket_p.h,v 1.7.18.2.52.1 2008/07/29 04:47:31 each Exp $ */
#ifndef ISC_SOCKET_P_H
#define ISC_SOCKET_P_H
LIBINTERFACE = 30
-LIBREVISION = 3
+LIBREVISION = 4
LIBAGE = 0
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: namedconf.c,v 1.30.18.38 2006/05/03 01:46:40 marka Exp $ */
+/* $ISC: namedconf.c,v 1.30.18.38.50.2 2008/07/23 23:48:17 tbox Exp $ */
/*! \file */
{ "recursing-file", &cfg_type_qstring, 0 },
{ "random-device", &cfg_type_qstring, 0 },
{ "recursive-clients", &cfg_type_uint32, 0 },
+ { "reserved-sockets", &cfg_type_uint32, 0 },
{ "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
{ "serial-query-rate", &cfg_type_uint32, 0 },
{ "server-id", &cfg_type_serverid, 0 },
-# $ISC: version,v 1.29.134.18.8.1 2008/05/22 21:28:03 each Exp $
+# $Id: version,v 1.13 2008/08/04 16:34:20 millert Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
MINORVER=4
PATCHVER=2
RELEASETYPE=-P
-RELEASEVER=1
+RELEASEVER=2