Commit 53f0b6c3 authored by Evan Hunt's avatar Evan Hunt

convert ns_client and related objects to use netmgr

- ns__client_request() is now called by netmgr with an isc_nmhandle_t
  parameter. The handle can then be permanently associated with an
  ns_client object.
- The task manager is paused so that isc_task events that may be
  triggred during client processing will not fire until after the netmgr is
  finished with it. Before any asynchronous event, the client MUST
  call isc_nmhandle_ref(client->handle), to prevent the client from
  being reset and reused while waiting for an event to process. When
  the asynchronous event is complete, isc_nmhandle_unref(client->handle)
  must be called to ensure the handle can be reused later.
- reference counting of client objects is now handled in the nmhandle
  object.  when the handle references drop to zero, the client's "reset"
  callback is used to free temporary resources and reiniialize it,
  whereupon the handle (and associated client) is placed in the
  "inactive handles" queue.  when the sysstem is shutdown and the
  handles are cleaned up, the client's "put" callback is called to free
  all remaining resources.
- because client allocation is no longer handled in the same way,
  the '-T clienttest' option has now been removed and is no longer
  used by any system tests.
- the unit tests require wrapping the isc_nmhandle_unref() function;
  when LD_WRAP is supported, that is used. otherwise we link a
  libwrap.so interposer library and use that.
parent 33bf9033
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <isc/rwlock.h> #include <isc/rwlock.h>
#include <isc/log.h> #include <isc/log.h>
#include <isc/net.h> #include <isc/net.h>
#include <isc/netmgr.h>
#include <isccfg/aclconf.h> #include <isccfg/aclconf.h>
#include <isccfg/cfg.h> #include <isccfg/cfg.h>
...@@ -62,6 +63,7 @@ EXTERN bool named_g_run_done INIT(false); ...@@ -62,6 +63,7 @@ EXTERN bool named_g_run_done INIT(false);
*/ */
EXTERN isc_timermgr_t * named_g_timermgr INIT(NULL); EXTERN isc_timermgr_t * named_g_timermgr INIT(NULL);
EXTERN isc_socketmgr_t * named_g_socketmgr INIT(NULL); EXTERN isc_socketmgr_t * named_g_socketmgr INIT(NULL);
EXTERN isc_nm_t * named_g_nm INIT(NULL);
EXTERN cfg_parser_t * named_g_parser INIT(NULL); EXTERN cfg_parser_t * named_g_parser INIT(NULL);
EXTERN cfg_parser_t * named_g_addparser INIT(NULL); EXTERN cfg_parser_t * named_g_addparser INIT(NULL);
EXTERN const char * named_g_version INIT(VERSION); EXTERN const char * named_g_version INIT(VERSION);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <isc/file.h> #include <isc/file.h>
#include <isc/hash.h> #include <isc/hash.h>
#include <isc/httpd.h> #include <isc/httpd.h>
#include <isc/netmgr.h>
#include <isc/os.h> #include <isc/os.h>
#include <isc/platform.h> #include <isc/platform.h>
#include <isc/print.h> #include <isc/print.h>
...@@ -124,7 +125,6 @@ static int maxudp = 0; ...@@ -124,7 +125,6 @@ static int maxudp = 0;
/* /*
* -T options: * -T options:
*/ */
static bool clienttest = false;
static bool dropedns = false; static bool dropedns = false;
static bool ednsformerr = false; static bool ednsformerr = false;
static bool ednsnotimp = false; static bool ednsnotimp = false;
...@@ -622,17 +622,12 @@ parse_T_opt(char *option) { ...@@ -622,17 +622,12 @@ parse_T_opt(char *option) {
/* /*
* force the server to behave (or misbehave) in * force the server to behave (or misbehave) in
* specified ways for testing purposes. * specified ways for testing purposes.
*
* clienttest: make clients single shot with their
* own memory context.
* delay=xxxx: delay client responses by xxxx ms to * delay=xxxx: delay client responses by xxxx ms to
* simulate remote servers. * simulate remote servers.
* dscp=x: check that dscp values are as * dscp=x: check that dscp values are as
* expected and assert otherwise. * expected and assert otherwise.
*/ */
if (!strcmp(option, "clienttest")) { if (!strncmp(option, "delay=", 6)) {
clienttest = true;
} else if (!strncmp(option, "delay=", 6)) {
delay = atoi(option + 6); delay = atoi(option + 6);
} else if (!strcmp(option, "dropedns")) { } else if (!strcmp(option, "dropedns")) {
dropedns = true; dropedns = true;
...@@ -897,8 +892,15 @@ create_managers(void) { ...@@ -897,8 +892,15 @@ create_managers(void) {
"using %u UDP listener%s per interface", "using %u UDP listener%s per interface",
named_g_udpdisp, named_g_udpdisp == 1 ? "" : "s"); named_g_udpdisp, named_g_udpdisp == 1 ? "" : "s");
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0, NULL, named_g_nm = isc_nm_start(named_g_mctx, named_g_cpus);
&named_g_taskmgr); if (named_g_nm == NULL) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_nm_start() failed");
return (ISC_R_UNEXPECTED);
}
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0,
named_g_nm, &named_g_taskmgr);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_taskmgr_create() failed: %s", "isc_taskmgr_create() failed: %s",
...@@ -923,6 +925,7 @@ create_managers(void) { ...@@ -923,6 +925,7 @@ create_managers(void) {
return (ISC_R_UNEXPECTED); return (ISC_R_UNEXPECTED);
} }
isc_socketmgr_maxudp(named_g_socketmgr, maxudp); isc_socketmgr_maxudp(named_g_socketmgr, maxudp);
isc_nm_maxudp(named_g_nm, maxudp);
result = isc_socketmgr_getmaxsockets(named_g_socketmgr, &socks); result = isc_socketmgr_getmaxsockets(named_g_socketmgr, &socks);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
...@@ -941,6 +944,7 @@ destroy_managers(void) { ...@@ -941,6 +944,7 @@ destroy_managers(void) {
isc_taskmgr_destroy(&named_g_taskmgr); isc_taskmgr_destroy(&named_g_taskmgr);
isc_timermgr_destroy(&named_g_timermgr); isc_timermgr_destroy(&named_g_timermgr);
isc_socketmgr_destroy(&named_g_socketmgr); isc_socketmgr_destroy(&named_g_socketmgr);
isc_nm_destroy(&named_g_nm);
} }
static void static void
...@@ -1254,8 +1258,6 @@ setup(void) { ...@@ -1254,8 +1258,6 @@ setup(void) {
/* /*
* Modify server context according to command line options * Modify server context according to command line options
*/ */
if (clienttest)
ns_server_setoption(sctx, NS_SERVER_CLIENTTEST, true);
if (disable4) if (disable4)
ns_server_setoption(sctx, NS_SERVER_DISABLE4, true); ns_server_setoption(sctx, NS_SERVER_DISABLE4, true);
if (disable6) if (disable6)
......
...@@ -9462,6 +9462,7 @@ run_server(isc_task_t *task, isc_event_t *event) { ...@@ -9462,6 +9462,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
CHECKFATAL(ns_interfacemgr_create(named_g_mctx, server->sctx, CHECKFATAL(ns_interfacemgr_create(named_g_mctx, server->sctx,
named_g_taskmgr, named_g_timermgr, named_g_taskmgr, named_g_timermgr,
named_g_socketmgr, named_g_socketmgr,
named_g_nm,
named_g_dispatchmgr, named_g_dispatchmgr,
server->task, named_g_udpdisp, geoip, server->task, named_g_udpdisp, geoip,
&server->interfacemgr), &server->interfacemgr),
...@@ -9525,6 +9526,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { ...@@ -9525,6 +9526,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
UNUSED(task); UNUSED(task);
INSIST(task == server->task); INSIST(task == server->task);
/*
* We need to shutdown the interface before going
* exclusive (which would pause the netmgr).
*/
ns_interfacemgr_shutdown(server->interfacemgr);
result = isc_task_beginexclusive(server->task); result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
...@@ -9582,7 +9589,6 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { ...@@ -9582,7 +9589,6 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
isc_timer_detach(&server->pps_timer); isc_timer_detach(&server->pps_timer);
isc_timer_detach(&server->tat_timer); isc_timer_detach(&server->tat_timer);
ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr); ns_interfacemgr_detach(&server->interfacemgr);
dns_dispatchmgr_destroy(&named_g_dispatchmgr); dns_dispatchmgr_destroy(&named_g_dispatchmgr);
......
...@@ -584,10 +584,6 @@ By default, start.pl starts a "named" server with the following options: ...@@ -584,10 +584,6 @@ By default, start.pl starts a "named" server with the following options:
preventing multiple instances of this named running in this preventing multiple instances of this named running in this
directory (which could possibly interfere with the test). directory (which could possibly interfere with the test).
In addition, start.pl also sets the following undocumented flag:
-T clienttest Makes clients single-shot with their own memory context.
All output is sent to a file called "named.run" in the nameserver directory. All output is sent to a file called "named.run" in the nameserver directory.
The options used to start named can be altered. There are three ways of doing The options used to start named can be altered. There are three ways of doing
...@@ -608,9 +604,9 @@ the named command-line arguments. The rest of the file is ignored. ...@@ -608,9 +604,9 @@ the named command-line arguments. The rest of the file is ignored.
3. Tweaking the default command line arguments with "-T" options. This flag is 3. Tweaking the default command line arguments with "-T" options. This flag is
used to alter the behavior of BIND for testing and is not documented in the used to alter the behavior of BIND for testing and is not documented in the
ARM. The "clienttest" option has already been mentioned, but the presence of ARM. The presence of certain files in the "nsN" directory adds flags to
certain files in the "nsN" directory adds flags to the default command line the default command line (the content of the files is irrelevant - it
(the content of the files is irrelevant - it is only the presence that counts): is only the presence that counts):
named.noaa Appends "-T noaa" to the command line, which causes named.noaa Appends "-T noaa" to the command line, which causes
"named" to never set the AA bit in an answer. "named" to never set the AA bit in an answer.
...@@ -635,7 +631,6 @@ certain files in the "nsN" directory adds flags to the default command line ...@@ -635,7 +631,6 @@ certain files in the "nsN" directory adds flags to the default command line
the additional section if the response is triggered by RPZ the additional section if the response is triggered by RPZ
rewriting). rewriting).
Starting Other Nameservers Starting Other Nameservers
--- ---
In contrast to "named", nameservers written in Perl or Python (whose script In contrast to "named", nameservers written in Perl or Python (whose script
......
# this server runs named with only one worker thread # this server runs named with only one worker thread
-m record,size,mctx -c named.conf -d 99 -D additional-ns1 -X named.lock -g -T clienttest -n 1 -m record,size,mctx -c named.conf -d 99 -D additional-ns1 -X named.lock -g -n 1
# this server only has 127.0.0.1 in its localhost/localnets ACLs # this server only has 127.0.0.1 in its localhost/localnets ACLs
-m record,size,mctx -c named.conf -d 99 -D allow-query-ns3 -X named.lock -g -T clienttest -T fixedlocal -m record,size,mctx -c named.conf -d 99 -D allow-query-ns3 -X named.lock -g -T fixedlocal
-D delzone-ns2 -X named.lock -m record,size,mctx -T clienttest -c named.conf -g -U 4 -D delzone-ns2 -X named.lock -m record,size,mctx -c named.conf -g -U 4
-m record,size,mctx -c named.conf -d 99 -D dnssec-ns6 -X named.lock -g -T nonearest -T clienttest -T tat=1 -m record,size,mctx -c named.conf -d 99 -D dnssec-ns6 -X named.lock -g -T nonearest -T tat=1
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns1 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns1 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns2 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns2 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns3 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns3 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns4 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns4 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns5 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns5 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns6 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns6 -X named.lock -g -U 4 -T dscp=46
-m record,size,mctx -T clienttest -c named.conf -d 99 -D dscp-ns7 -X named.lock -g -U 4 -T dscp=46 -m record,size,mctx -c named.conf -d 99 -D dscp-ns7 -X named.lock -g -U 4 -T dscp=46
-D dupsigs-ns1 -X named.lock -m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T sigvalinsecs -D dupsigs-ns1 -X named.lock -m record,size,mctx -c named.conf -d 99 -g -U 4 -T sigvalinsecs
# Don't specify '-T clienttest' as it consumes lots of memory with this test
-D fetchlimit-ns3 -X named.lock -m record,size,mctx -c named.conf -d 99 -g -U 4
-m record,size,mctx -T clienttest -c named.conf -d 99 -D legacy-ns4 -X named.lock -g -U 4 -T noedns -m record,size,mctx -c named.conf -d 99 -D legacy-ns4 -X named.lock -g -U 4 -T noedns
-m record,size,mctx -T clienttest -c named.conf -d 99 -D legacy-ns5 -X named.lock -g -U 4 -T noedns -m record,size,mctx -c named.conf -d 99 -D legacy-ns5 -X named.lock -g -U 4 -T noedns
-m record,size,mctx -T clienttest -c named.conf -d 99 -D legacy-ns6 -X named.lock -g -U 4 -T maxudp512 -m record,size,mctx -c named.conf -d 99 -D legacy-ns6 -X named.lock -g -U 4 -T maxudp512
-m record,size,mctx -T clienttest -c named.conf -d 99 -D legacy-ns7 -X named.lock -g -U 4 -T maxudp512 -m record,size,mctx -c named.conf -d 99 -D legacy-ns7 -X named.lock -g -U 4 -T maxudp512
...@@ -36,7 +36,7 @@ DLFILE="named_deflog" ...@@ -36,7 +36,7 @@ DLFILE="named_deflog"
PIDFILE="${THISDIR}/${CONFDIR}/named.pid" PIDFILE="${THISDIR}/${CONFDIR}/named.pid"
myRNDC="$RNDC -c ${THISDIR}/${CONFDIR}/rndc.conf" myRNDC="$RNDC -c ${THISDIR}/${CONFDIR}/rndc.conf"
myNAMED="$NAMED -c ${THISDIR}/${CONFDIR}/named.conf -m record,size,mctx -T clienttest -T nosyslog -d 99 -D logfileconfig-ns1 -X named.lock -U 4" myNAMED="$NAMED -c ${THISDIR}/${CONFDIR}/named.conf -m record,size,mctx -T nosyslog -d 99 -D logfileconfig-ns1 -X named.lock -U 4"
# Test given condition. If true, test again after a second. Used for testing # Test given condition. If true, test again after a second. Used for testing
# filesystem-dependent conditions in order to prevent false negatives caused by # filesystem-dependent conditions in order to prevent false negatives caused by
......
-D mirror-ns3 -X named.lock -m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T tat=3 -D mirror-ns3 -X named.lock -m record,size,mctx -c named.conf -d 99 -g -U 4 -T tat=3
-m record,size,mctx -T clienttest -c named.conf -d 99 -D mkeys-ns2 -X named.lock -g -T mkeytimers=5/10/20 -T tat=1 -m record,size,mctx -c named.conf -d 99 -D mkeys-ns2 -X named.lock -g -T mkeytimers=5/10/20 -T tat=1
-m record,size,mctx -T clienttest -c named.conf -d 99 -D mkeys-ns3 -X named.lock -g -T mkeytimers=5/10/20 -m record,size,mctx -c named.conf -d 99 -D mkeys-ns3 -X named.lock -g -T mkeytimers=5/10/20
-m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -m record,size,mctx -c named.conf -d 99 -X named.lock -g
-m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -T mkeytimers=2/20/40 -m record,size,mctx -c named.conf -d 99 -X named.lock -g -T mkeytimers=2/20/40
-m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -T mkeytimers=5/10/20 -m record,size,mctx -c named.conf -d 99 -X named.lock -g -T mkeytimers=5/10/20
-D nsupdate-ns5 -m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -U 4 -T fixedlocal -D nsupdate-ns5 -m record,size,mctx -c named.conf -d 99 -X named.lock -g -U 4 -T fixedlocal
-D nsupdate-ns6 -m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -U 4 -T fixedlocal -D nsupdate-ns6 -m record,size,mctx -c named.conf -d 99 -X named.lock -g -U 4 -T fixedlocal
# this server runs named with the "-T clienttest" option omitted
-m record,size,mctx -c named.conf -d 99 -D resolver-ns7 -X named.lock -g
# teardown of a huge zone with tracing enabled takes way too long # teardown of a huge zone with tracing enabled takes way too long
# -m none is set so that stop.pl does not timeout # -m none is set so that stop.pl does not timeout
-D rndc-ns6 -X named.lock -m none -T clienttest -c named.conf -d 99 -g -U 4 -D rndc-ns6 -X named.lock -m none -c named.conf -d 99 -g -U 4
...@@ -257,7 +257,6 @@ sub construct_ns_command { ...@@ -257,7 +257,6 @@ sub construct_ns_command {
$command .= "-D $test-$server "; $command .= "-D $test-$server ";
$command .= "-X named.lock "; $command .= "-X named.lock ";
$command .= "-m record,size,mctx "; $command .= "-m record,size,mctx ";
$command .= "-T clienttest ";
foreach my $t_option( foreach my $t_option(
"dropedns", "ednsformerr", "ednsnotimp", "ednsrefused", "dropedns", "ednsformerr", "ednsnotimp", "ednsrefused",
......
...@@ -598,7 +598,8 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { ...@@ -598,7 +598,8 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
dns_qid_t *qid; dns_qid_t *qid;
REQUIRE(disp->port_table != NULL); REQUIRE(disp->port_table != NULL);
REQUIRE(portentry != NULL && isc_refcount_current(&portentry->refs) > 0); REQUIRE(portentry != NULL &&
isc_refcount_current(&portentry->refs) > 0);
if (isc_refcount_decrement(&portentry->refs) == 1) { if (isc_refcount_decrement(&portentry->refs) == 1) {
qid = DNS_QID(disp); qid = DNS_QID(disp);
......
...@@ -1103,7 +1103,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -1103,7 +1103,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;
goto cleanup; goto cleanup;
} }
rdataset = isc_mempool_get(msg->rdspool); rdataset = isc_mempool_get(msg->rdspool);
if (rdataset == NULL) { if (rdataset == NULL) {
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;
goto cleanup; goto cleanup;
......
This diff is collapsed.
...@@ -36,10 +36,10 @@ ...@@ -36,10 +36,10 @@
* notified of this by calling one of the following functions * notified of this by calling one of the following functions
* exactly once in the context of its task: * exactly once in the context of its task:
* \code * \code
* ns_client_send() (sending a non-error response) * ns_client_send() (sending a non-error response)
* ns_client_sendraw() (sending a raw response) * ns_client_sendraw() (sending a raw response)
* ns_client_error() (sending an error response) * ns_client_error() (sending an error response)
* ns_client_next() (sending no response) * ns_client_drop() (sending no response, logging the reason)
*\endcode *\endcode
* This will release any resources used by the request and * This will release any resources used by the request and
* and allow the ns_client_t to listen for the next request. * and allow the ns_client_t to listen for the next request.
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include <isc/buffer.h> #include <isc/buffer.h>
#include <isc/list.h> #include <isc/list.h>
#include <isc/magic.h> #include <isc/magic.h>
#include <isc/netmgr.h>
#include <isc/stdtime.h> #include <isc/stdtime.h>
#include <isc/quota.h> #include <isc/quota.h>
#include <isc/platform.h> #include <isc/platform.h>
...@@ -80,58 +81,141 @@ ...@@ -80,58 +81,141 @@
*** Types *** Types
***/ ***/
/*% reference-counted TCP connection object */ #define NS_CLIENT_TCP_BUFFER_SIZE (65535 + 2)
typedef struct ns_tcpconn { #define NS_CLIENT_SEND_BUFFER_SIZE 4096
isc_refcount_t refs; #define NS_CLIENT_RECV_BUFFER_SIZE 4096
isc_quota_t *tcpquota;
bool pipelined; #define CLIENT_NMCTXS 100
} ns_tcpconn_t; /*%<
* Number of 'mctx pools' for clients. (Should this be configurable?)
* When enabling threads, we use a pool of memory contexts shared by
* client objects, since concurrent access to a shared context would cause
* heavy contentions. The above constant is expected to be enough for
* completely avoiding contentions among threads for an authoritative-only
* server.
*/
#define CLIENT_NTASKS 100
/*%<
* Number of tasks to be used by clients - those are used only when recursing
*/
/*!
* Client object states. Ordering is significant: higher-numbered
* states are generally "more active", meaning that the client can
* have more dynamically allocated data, outstanding events, etc.
* In the list below, any such properties listed for state N
* also apply to any state > N.
*/
typedef enum {
NS_CLIENTSTATE_FREED = 0,
/*%<
* The client object no longer exists.
*/
NS_CLIENTSTATE_INACTIVE = 1,
/*%<
* The client object exists and has a task and timer.
* Its "query" struct and sendbuf are initialized.
* It has a message and OPT, both in the reset state.
*/
NS_CLIENTSTATE_READY = 2,
/*%<
* The client object is either a TCP or a UDP one, and
* it is associated with a network interface. It is on the
* client manager's list of active clients.
*
* If it is a TCP client object, it has a TCP listener socket
* and an outstanding TCP listen request.
*
* If it is a UDP client object, it has a UDP listener socket
* and an outstanding UDP receive request.
*/
NS_CLIENTSTATE_WORKING = 3,
/*%<
* The client object has received a request and is working
* on it. It has a view, and it may have any of a non-reset OPT,
* recursion quota, and an outstanding write request.
*/
NS_CLIENTSTATE_RECURSING = 4,
/*%<
* The client object is recursing. It will be on the
* 'recursing' list.
*/
NS_CLIENTSTATE_MAX = 5
/*%<
* Sentinel value used to indicate "no state".
*/
} ns_clientstate_t;
typedef ISC_LIST(ns_client_t) client_list_t;
/*% nameserver client manager structure */
struct ns_clientmgr {
/* Unlocked. */
unsigned int magic;
isc_mem_t * mctx;
ns_server_t * sctx;
isc_taskmgr_t * taskmgr;
isc_timermgr_t * timermgr;
isc_task_t * excl;
isc_refcount_t references;
/* Attached by clients, needed for e.g. recursion */
isc_task_t ** taskpool;
ns_interface_t *interface;
/* Lock covers manager state. */
isc_mutex_t lock;
bool exiting;
/* Lock covers the recursing list */
isc_mutex_t reclock;
client_list_t recursing; /*%< Recursing clients */
#if CLIENT_NMCTXS > 0
/*%< mctx pool for clients. */
unsigned int nextmctx;
isc_mem_t * mctxpool[CLIENT_NMCTXS];
#endif
};
/*% nameserver client structure */ /*% nameserver client structure */
struct ns_client { struct ns_client {
unsigned int magic; unsigned int magic;
isc_mem_t *mctx; isc_mem_t *mctx;
bool allocated; /* Do we need to free it? */
ns_server_t *sctx; ns_server_t *sctx;
ns_clientmgr_t *manager; ns_clientmgr_t *manager;
int state; ns_clientstate_t state;
int newstate;
int naccepts; int naccepts;
int nreads; int nreads;
int nsends; int nsends;
int nrecvs; int nrecvs;
int nupdates; int nupdates;
int nctls; int nctls;
isc_refcount_t references; bool shuttingdown;
bool tcpactive;
bool needshutdown; /*
* Used by clienttest to get
* the client to go from
* inactive to free state
* by shutting down the
* client's task.
*/
unsigned int attributes; unsigned int attributes;
isc_task_t *task; isc_task_t *task;
dns_view_t *view; dns_view_t *view;
dns_dispatch_t *dispatch; dns_dispatch_t *dispatch;
isc_socket_t *udpsocket; isc_nmhandle_t *handle;
isc_socket_t *tcplistener;
isc_socket_t *tcpsocket;
unsigned char *tcpbuf; unsigned char *tcpbuf;
dns_tcpmsg_t tcpmsg;
bool tcpmsg_valid;
isc_timer_t *timer;
isc_timer_t *delaytimer;
bool timerset;
dns_message_t *message; dns_message_t *message;
isc_socketevent_t *sendevent;
isc_socketevent_t *recvevent;
unsigned char *recvbuf; unsigned char *recvbuf;
unsigned char sendbuf[NS_CLIENT_SEND_BUFFER_SIZE];
dns_rdataset_t *opt; dns_rdataset_t *opt;
uint16_t udpsize; uint16_t udpsize;
uint16_t extflags; uint16_t extflags;
int16_t ednsversion; /* -1 noedns */ int16_t ednsversion; /* -1 noedns */
void (*next)(ns_client_t *); void (*cleanup)(ns_client_t *);
void (*shutdown)(void *arg, isc_result_t result); void (*shutdown)(void *arg, isc_result_t result);
void *shutdown_arg; void *shutdown_arg;
ns_query_t query; ns_query_t query;
...@@ -141,9 +225,7 @@ struct ns_client { ...@@ -141,9 +225,7 @@ struct ns_client {
dns_name_t signername; /*%< [T]SIG key name */ dns_name_t signername; /*%< [T]SIG key name */
dns_name_t *signer; /*%< NULL if not valid sig */ dns_name_t *signer; /*%< NULL if not valid sig */
bool mortal; /*%< Die after handling request */ bool mortal; /*%< Die after handling request */
ns_tcpconn_t *tcpconn;
isc_quota_t *recursionquota; isc_quota_t *recursionquota;
ns_interface_t *interface;
isc_sockaddr_t peeraddr; isc_sockaddr_t peeraddr;
bool peeraddr_valid; bool peeraddr_valid;
...@@ -154,7 +236,6 @@ struct ns_client { ...@@ -154,7 +236,6 @@ struct ns_client {
struct in6_pktinfo pktinfo; struct in6_pktinfo pktinfo;
isc_dscp_t dscp; isc_dscp_t dscp;
isc_event_t ctlevent;
/*% /*%
* Information about recent FORMERR response(s), for * Information about recent FORMERR response(s), for
* FORMERR loop avoidance. This is separate for each * FORMERR loop avoidance. This is separate for each
...@@ -170,9 +251,7 @@ struct ns_client { ...@@ -170,9 +251,7 @@ struct ns_client {
/*% Callback function to send a response when unit testing */ /*% Callback function to send a response when unit testing */
void (*sendcb)(isc_buffer_t *buf); void (*sendcb)(isc_buffer_t *buf);
ISC_LINK(ns_client_t) link;
ISC_LINK(ns_client_t) rlink; ISC_LINK(ns_client_t) rlink;
ISC_QLINK(ns_client_t) ilink;
unsigned char cookie[8]; unsigned char cookie[8];
uint32_t expire; uint32_t expire;
unsigned char *keytag; unsigned char *keytag;
...@@ -187,9 +266,6 @@ struct ns_client { ...@@ -187,9 +266,6 @@ struct ns_client {
int32_t rcode_override; int32_t rcode_override;
}; };
typedef ISC_QUEUE(ns_client_t) client_queue_t;
typedef ISC_LIST(ns_client_t) client_list_t;
#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') #define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c')
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) #define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
...@@ -256,10 +332,10 @@ ns_client_error(ns_client_t *client, isc_result_t result); ...@@ -256,10 +332,10 @@ ns_client_error(ns_client_t *client, isc_result_t result);
*/ */
void void
ns_client_next(ns_client_t *client, isc_result_t result); ns_client_drop(ns_client_t *client, isc_result_t result);
/*%< /*%<
* Finish processing the current client request, * Log the reason the current client request has failed; no response
* return no response to the client. * will be sent.
*/ */
bool bool
...@@ -268,18 +344,6 @@ ns_client_shuttingdown(ns_client_t *client); ...@@ -268,18 +344,6 @@ ns_client_shuttingdown(ns_client_t *client);
* Return true iff the client is currently shutting down. * Return true iff the client is currently shutting down.
*/