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 @@
#include <isc/rwlock.h>
#include <isc/log.h>
#include <isc/net.h>
#include <isc/netmgr.h>
#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
......@@ -62,6 +63,7 @@ EXTERN bool named_g_run_done INIT(false);
*/
EXTERN isc_timermgr_t * named_g_timermgr 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_addparser INIT(NULL);
EXTERN const char * named_g_version INIT(VERSION);
......
......@@ -24,6 +24,7 @@
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/httpd.h>
#include <isc/netmgr.h>
#include <isc/os.h>
#include <isc/platform.h>
#include <isc/print.h>
......@@ -124,7 +125,6 @@ static int maxudp = 0;
/*
* -T options:
*/
static bool clienttest = false;
static bool dropedns = false;
static bool ednsformerr = false;
static bool ednsnotimp = false;
......@@ -622,17 +622,12 @@ parse_T_opt(char *option) {
/*
* force the server to behave (or misbehave) in
* specified ways for testing purposes.
*
* clienttest: make clients single shot with their
* own memory context.
* delay=xxxx: delay client responses by xxxx ms to
* simulate remote servers.
* dscp=x: check that dscp values are as
* expected and assert otherwise.
*/
if (!strcmp(option, "clienttest")) {
clienttest = true;
} else if (!strncmp(option, "delay=", 6)) {
if (!strncmp(option, "delay=", 6)) {
delay = atoi(option + 6);
} else if (!strcmp(option, "dropedns")) {
dropedns = true;
......@@ -897,8 +892,15 @@ create_managers(void) {
"using %u UDP listener%s per interface",
named_g_udpdisp, named_g_udpdisp == 1 ? "" : "s");
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0, NULL,
&named_g_taskmgr);
named_g_nm = isc_nm_start(named_g_mctx, named_g_cpus);
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) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_taskmgr_create() failed: %s",
......@@ -923,6 +925,7 @@ create_managers(void) {
return (ISC_R_UNEXPECTED);
}
isc_socketmgr_maxudp(named_g_socketmgr, maxudp);
isc_nm_maxudp(named_g_nm, maxudp);
result = isc_socketmgr_getmaxsockets(named_g_socketmgr, &socks);
if (result == ISC_R_SUCCESS) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
......@@ -941,6 +944,7 @@ destroy_managers(void) {
isc_taskmgr_destroy(&named_g_taskmgr);
isc_timermgr_destroy(&named_g_timermgr);
isc_socketmgr_destroy(&named_g_socketmgr);
isc_nm_destroy(&named_g_nm);
}
static void
......@@ -1254,8 +1258,6 @@ setup(void) {
/*
* Modify server context according to command line options
*/
if (clienttest)
ns_server_setoption(sctx, NS_SERVER_CLIENTTEST, true);
if (disable4)
ns_server_setoption(sctx, NS_SERVER_DISABLE4, true);
if (disable6)
......
......@@ -9462,6 +9462,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
CHECKFATAL(ns_interfacemgr_create(named_g_mctx, server->sctx,
named_g_taskmgr, named_g_timermgr,
named_g_socketmgr,
named_g_nm,
named_g_dispatchmgr,
server->task, named_g_udpdisp, geoip,
&server->interfacemgr),
......@@ -9525,6 +9526,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
UNUSED(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);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
......@@ -9582,7 +9589,6 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
isc_timer_detach(&server->pps_timer);
isc_timer_detach(&server->tat_timer);
ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr);
dns_dispatchmgr_destroy(&named_g_dispatchmgr);
......
......@@ -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
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.
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.
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
ARM. The "clienttest" option has already been mentioned, but the presence of
certain files in the "nsN" directory adds flags to the default command line
(the content of the files is irrelevant - it is only the presence that counts):
ARM. The presence of certain files in the "nsN" directory adds flags to
the default command line (the content of the files is irrelevant - it
is only the presence that counts):
named.noaa Appends "-T noaa" to the command line, which causes
"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
the additional section if the response is triggered by RPZ
rewriting).
Starting Other Nameservers
---
In contrast to "named", nameservers written in Perl or Python (whose script
......
# 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
-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"
PIDFILE="${THISDIR}/${CONFDIR}/named.pid"
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
# 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
# -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 {
$command .= "-D $test-$server ";
$command .= "-X named.lock ";
$command .= "-m record,size,mctx ";
$command .= "-T clienttest ";
foreach my $t_option(
"dropedns", "ednsformerr", "ednsnotimp", "ednsrefused",
......
......@@ -598,7 +598,8 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
dns_qid_t *qid;
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) {
qid = DNS_QID(disp);
......
......@@ -1103,7 +1103,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
result = ISC_R_NOMEMORY;
goto cleanup;
}
rdataset = isc_mempool_get(msg->rdspool);
rdataset = isc_mempool_get(msg->rdspool);
if (rdataset == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
......
This diff is collapsed.
......@@ -36,10 +36,10 @@
* notified of this by calling one of the following functions
* exactly once in the context of its task:
* \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_error() (sending an error response)
* ns_client_next() (sending no response)
* ns_client_error() (sending an error response)
* ns_client_drop() (sending no response, logging the reason)
*\endcode
* This will release any resources used by the request and
* and allow the ns_client_t to listen for the next request.
......@@ -60,6 +60,7 @@
#include <isc/buffer.h>
#include <isc/list.h>
#include <isc/magic.h>
#include <isc/netmgr.h>
#include <isc/stdtime.h>
#include <isc/quota.h>
#include <isc/platform.h>
......@@ -80,58 +81,141 @@
*** Types
***/
/*% reference-counted TCP connection object */
typedef struct ns_tcpconn {
isc_refcount_t refs;
isc_quota_t *tcpquota;
bool pipelined;
} ns_tcpconn_t;
#define NS_CLIENT_TCP_BUFFER_SIZE (65535 + 2)
#define NS_CLIENT_SEND_BUFFER_SIZE 4096
#define NS_CLIENT_RECV_BUFFER_SIZE 4096
#define CLIENT_NMCTXS 100
/*%<
* 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 */
struct ns_client {
unsigned int magic;
isc_mem_t *mctx;
bool allocated; /* Do we need to free it? */
ns_server_t *sctx;
ns_clientmgr_t *manager;
int state;
int newstate;
ns_clientstate_t state;
int naccepts;
int nreads;
int nsends;
int nrecvs;
int nupdates;
int nctls;
isc_refcount_t references;
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.
*/
bool shuttingdown;
unsigned int attributes;
isc_task_t *task;
dns_view_t *view;
dns_dispatch_t *dispatch;
isc_socket_t *udpsocket;
isc_socket_t *tcplistener;
isc_socket_t *tcpsocket;
isc_nmhandle_t *handle;
unsigned char *tcpbuf;
dns_tcpmsg_t tcpmsg;
bool tcpmsg_valid;
isc_timer_t *timer;
isc_timer_t *delaytimer;
bool timerset;
dns_message_t *message;
isc_socketevent_t *sendevent;
isc_socketevent_t *recvevent;
unsigned char *recvbuf;
unsigned char sendbuf[NS_CLIENT_SEND_BUFFER_SIZE];
dns_rdataset_t *opt;
uint16_t udpsize;
uint16_t extflags;
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_arg;
ns_query_t query;
......@@ -141,9 +225,7 @@ struct ns_client {
dns_name_t signername; /*%< [T]SIG key name */
dns_name_t *signer; /*%< NULL if not valid sig */
bool mortal; /*%< Die after handling request */
ns_tcpconn_t *tcpconn;
isc_quota_t *recursionquota;
ns_interface_t *interface;
isc_sockaddr_t peeraddr;
bool peeraddr_valid;
......@@ -154,7 +236,6 @@ struct ns_client {
struct in6_pktinfo pktinfo;
isc_dscp_t dscp;
isc_event_t ctlevent;
/*%
* Information about recent FORMERR response(s), for
* FORMERR loop avoidance. This is separate for each
......@@ -170,9 +251,7 @@ struct ns_client {
/*% Callback function to send a response when unit testing */
void (*sendcb)(isc_buffer_t *buf);
ISC_LINK(ns_client_t) link;
ISC_LINK(ns_client_t) rlink;
ISC_QLINK(ns_client_t) ilink;
unsigned char cookie[8];
uint32_t expire;
unsigned char *keytag;
......@@ -187,9 +266,6 @@ struct ns_client {
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_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
......@@ -256,10 +332,10 @@ ns_client_error(ns_client_t *client, isc_result_t result);
*/
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,
* return no response to the client.
* Log the reason the current client request has failed; no response
* will be sent.
*/
bool
......@@ -268,18 +344,6 @@ ns_client_shuttingdown(ns_client_t *client);
* Return true iff the client is currently shutting down.
*/
void
ns_client_attach(ns_client_t *source, ns_client_t **target);
/*%<
* Attach '*targetp' to 'source'.
*/
void
ns_client_detach(ns_client_t **clientp);
/*%<
* Detach '*clientp' from its client.
*/
isc_result_t
ns_client_replace(ns_client_t *client);
/*%<
......@@ -296,7 +360,8 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds);
isc_result_t
ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, ns_clientmgr_t **managerp);
isc_timermgr_t *timermgr, ns_interface_t *ifp,
ns_clientmgr_t **managerp);
/*%<
* Create a client manager.
*/
......@@ -308,15 +373,6 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp);
* managed by it.
*/
isc_result_t
ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
ns_interface_t *ifp, bool tcp);
/*%<
* Create up to 'n' clients listening on interface 'ifp'.
* If 'tcp' is true, the clients will listen for TCP connections,
* otherwise for UDP requests.
*/
isc_sockaddr_t *
ns_client_getsockaddr(ns_client_t *client);
/*%<
......@@ -427,16 +483,14 @@ isc_result_t
ns_client_addopt(ns_client_t *client, dns_message_t *message,
dns_rdataset_t **opt);
isc_result_t
ns__clientmgr_getclient(ns_clientmgr_t *manager, ns_interface_t *ifp,
bool tcp, ns_client_t **clientp);
/*
* Get a client object from the inactive queue, or create one, as needed.
* (Not intended for use outside this module and associated tests.)
*/
void
ns__client_request(isc_task_t *task, isc_event_t *event);
ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg);
/*
* Handle client requests.
* (Not intended for use outside this module and associated tests.)
......@@ -508,4 +562,24 @@ ns_client_findversion(ns_client_t *client, dns_db_t *db);
* allocated by ns_client_newdbversion().
*/
isc_result_t
ns__client_setup(ns_client_t *client, ns_clientmgr_t *manager, bool new);
/*%<
* Perform initial setup of an allocated client.
*/
void
ns__client_reset_cb(void *client0);
/*%<
* Reset the client object so that it can be reused.
*/
void
ns__client_put_cb(void *client0);
/*%<
* Free all resources allocated to this client object, so that
* it can be freed.
*/
#endif /* NS_CLIENT_H */
......@@ -44,6 +44,7 @@
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/socket.h>
#include <isc/refcount.h>
......@@ -66,16 +67,18 @@
/*% The nameserver interface structure */
struct ns_interface {
unsigned int magic; /*%< Magic number. */
ns_interfacemgr_t * mgr; /*%< Interface manager. */
ns_interfacemgr_t *mgr; /*%< Interface manager. */
isc_mutex_t lock;
isc_refcount_t references;
unsigned int generation; /*%< Generation number. */
isc_sockaddr_t addr; /*%< Address and port. */
unsigned int flags; /*%< Interface characteristics */
unsigned int flags; /*%< Interface flags */
char name[32]; /*%< Null terminated. */
dns_dispatch_t * udpdispatch[MAX_UDP_DISPATCH];
dns_dispatch_t *udpdispatch[MAX_UDP_DISPATCH];
/*%< UDP dispatchers. */
isc_socket_t * tcpsocket; /*%< TCP socket. */
isc_socket_t *tcpsocket; /*%< TCP socket. */
isc_nmsocket_t *udplistensocket;
isc_nmsocket_t *tcplistensocket;
isc_dscp_t dscp; /*%< "listen-on" DSCP value */
isc_refcount_t ntcpaccepting; /*%< Number of clients
ready to accept new
......@@ -86,7 +89,7 @@ struct ns_interface {
(whether accepting or
connected) */
int nudpdispatch; /*%< Number of UDP dispatches */
ns_clientmgr_t * clientmgr; /*%< Client manager. */
ns_clientmgr_t *clientmgr; /*%< Client manager. */
ISC_LINK(ns_interface_t) link;
};
......@@ -95,15 +98,11 @@ struct ns_interface {
***/
isc_result_t
ns_interfacemgr_create(isc_mem_t *mctx,
ns_server_t *sctx,
isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr,
dns_dispatchmgr_t *dispatchmgr,
isc_task_t *task,
unsigned int udpdisp,
dns_geoip_databases_t *geoip,
ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr, isc_nm_t *nm,
dns_dispatchmgr_t *dispatchmgr, isc_task_t *task,
unsigned int udpdisp, dns_geoip_databases_t *geoip,
ns_interfacemgr_t **mgrp);
/*%<
* Create a new interface manager.
......
......@@ -36,7 +36,6 @@
#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */
#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */
#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */
#define NS_SERVER_CLIENTTEST 0x00000010U /*%< -T clienttest */
#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */
#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */
#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */
......