1999-06-16 01:32:31 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
1999-06-16 01:32:31 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
2000-06-22 22:00:42 +00:00
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
1999-06-16 01:32:31 +00:00
|
|
|
#include <stdlib.h>
|
2020-03-09 16:17:26 +01:00
|
|
|
#include <sys/types.h>
|
2007-06-26 02:52:15 +00:00
|
|
|
#include <unistd.h>
|
1999-06-16 01:32:31 +00:00
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
#include <isc/mem.h>
|
2000-05-10 21:34:50 +00:00
|
|
|
#include <isc/mutex.h>
|
2008-06-23 19:41:20 +00:00
|
|
|
#include <isc/portset.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/print.h>
|
2008-06-23 19:41:20 +00:00
|
|
|
#include <isc/random.h>
|
2012-04-28 14:52:28 -07:00
|
|
|
#include <isc/socket.h>
|
2009-01-27 22:30:00 +00:00
|
|
|
#include <isc/stats.h>
|
2000-05-13 21:57:02 +00:00
|
|
|
#include <isc/string.h>
|
2000-04-28 03:53:48 +00:00
|
|
|
#include <isc/task.h>
|
2007-06-26 06:02:37 +00:00
|
|
|
#include <isc/time.h>
|
1999-12-16 22:24:22 +00:00
|
|
|
#include <isc/util.h>
|
1999-06-16 01:32:31 +00:00
|
|
|
|
2000-11-03 02:45:55 +00:00
|
|
|
#include <dns/acl.h>
|
1999-06-16 01:32:31 +00:00
|
|
|
#include <dns/dispatch.h>
|
2000-04-29 00:45:26 +00:00
|
|
|
#include <dns/events.h>
|
|
|
|
#include <dns/log.h>
|
1999-06-30 01:33:11 +00:00
|
|
|
#include <dns/message.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/stats.h>
|
2000-05-10 21:34:50 +00:00
|
|
|
#include <dns/types.h>
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
|
2000-09-18 04:50:05 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
typedef struct dispsocket dispsocket_t;
|
|
|
|
typedef ISC_LIST(dispsocket_t) dispsocketlist_t;
|
2008-08-15 17:29:52 +00:00
|
|
|
|
2000-09-18 04:50:05 +00:00
|
|
|
typedef struct dns_qid {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
unsigned int qid_nbuckets; /*%< hash table size */
|
|
|
|
unsigned int qid_increment; /*%< id increment on collision */
|
|
|
|
isc_mutex_t lock;
|
|
|
|
dns_displist_t *qid_table; /*%< the table itself */
|
2020-02-12 13:59:18 +01:00
|
|
|
dispsocketlist_t *sock_table; /*%< socket table */
|
2000-09-18 04:50:05 +00:00
|
|
|
} dns_qid_t;
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
struct dns_dispatchmgr {
|
|
|
|
/* Unlocked. */
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
dns_acl_t *blackhole;
|
|
|
|
isc_stats_t *stats;
|
2000-05-10 21:34:50 +00:00
|
|
|
|
|
|
|
/* Locked by "lock". */
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mutex_t lock;
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int state;
|
|
|
|
ISC_LIST(dns_dispatch_t) list;
|
2000-09-19 06:59:28 +00:00
|
|
|
|
2014-06-04 13:38:59 +05:30
|
|
|
/* locked by buffer_lock */
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_qid_t *qid;
|
|
|
|
isc_mutex_t buffer_lock;
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int buffers; /*%< allocated buffers */
|
|
|
|
unsigned int buffersize; /*%< size of each buffer */
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_t irefs;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t *v4ports; /*%< available ports for IPv4 */
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int nv4ports; /*%< # of available ports for IPv4 */
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t *v6ports; /*%< available ports for IPv4 */
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int nv6ports; /*%< # of available ports for IPv4 */
|
2000-05-10 21:34:50 +00:00
|
|
|
};
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define MGR_SHUTTINGDOWN 0x00000001U
|
2020-02-12 13:59:18 +01:00
|
|
|
#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0)
|
2000-05-10 21:34:50 +00:00
|
|
|
|
1999-07-06 19:32:40 +00:00
|
|
|
struct dns_dispentry {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
dns_dispatch_t *disp;
|
|
|
|
dns_messageid_t id;
|
|
|
|
in_port_t port;
|
|
|
|
unsigned int bucket;
|
|
|
|
isc_sockaddr_t host;
|
|
|
|
isc_task_t *task;
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_taskaction_t action;
|
2020-02-13 14:44:37 -08:00
|
|
|
void *arg;
|
|
|
|
bool item_out;
|
|
|
|
dispsocket_t *dispsocket;
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LIST(dns_dispatchevent_t) items;
|
|
|
|
ISC_LINK(dns_dispentry_t) link;
|
2008-06-23 19:41:20 +00:00
|
|
|
};
|
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
/*%
|
|
|
|
* Fixed UDP buffer size.
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_UDPBUFSIZE
|
|
|
|
#define DNS_DISPATCH_UDPBUFSIZE 4096
|
|
|
|
#endif /* ifndef DNS_DISPATCH_UDPBUFSIZE */
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
struct dispsocket {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
isc_socket_t *socket;
|
|
|
|
dns_dispatch_t *disp;
|
|
|
|
isc_sockaddr_t host;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_dispentry_t *resp;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_task_t *task;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
in_port_t port;
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LINK(dispsocket_t) link;
|
|
|
|
unsigned int bucket;
|
|
|
|
ISC_LINK(dispsocket_t) blink;
|
1999-06-16 01:32:31 +00:00
|
|
|
};
|
1999-07-06 19:32:40 +00:00
|
|
|
|
2020-12-18 17:21:00 -08:00
|
|
|
typedef struct tcpmsg {
|
|
|
|
uint16_t size;
|
|
|
|
dns_dispatch_t *disp;
|
|
|
|
isc_buffer_t buffer;
|
|
|
|
isc_task_t *task;
|
|
|
|
isc_taskaction_t action;
|
|
|
|
void *arg;
|
|
|
|
isc_event_t event;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_sockaddr_t address;
|
|
|
|
} tcpmsg_t;
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
/*%
|
|
|
|
* Number of tasks for each dispatch that use separate sockets for different
|
|
|
|
* transactions. This must be a power of 2 as it will divide 32 bit numbers
|
|
|
|
* to get an uniformly random tasks selection. See get_dispsocket().
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
#define MAX_INTERNAL_TASKS 64
|
2008-06-23 19:41:20 +00:00
|
|
|
|
1999-06-16 01:32:31 +00:00
|
|
|
struct dns_dispatch {
|
|
|
|
/* Unlocked. */
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic; /*%< magic */
|
|
|
|
dns_dispatchmgr_t *mgr; /*%< dispatch manager */
|
|
|
|
int ntasks;
|
2008-06-23 19:41:20 +00:00
|
|
|
/*%
|
|
|
|
* internal task buckets. We use multiple tasks to distribute various
|
|
|
|
* socket events well when using separate dispatch sockets. We use the
|
|
|
|
* 1st task (task[0]) for internal control events.
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_task_t *task[MAX_INTERNAL_TASKS];
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
isc_socket_t *socket; /*%< isc socket attached to */
|
|
|
|
isc_sockaddr_t local; /*%< local address */
|
|
|
|
in_port_t localport; /*%< local UDP port */
|
|
|
|
isc_sockaddr_t peer; /*%< peer address (TCP) */
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_event_t *ctlevent;
|
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_t *sepool; /*%< pool for socket events */
|
2012-04-28 14:52:28 -07:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*% Locked by mgr->lock. */
|
2000-05-10 21:34:50 +00:00
|
|
|
ISC_LINK(dns_dispatch_t) link;
|
|
|
|
|
|
|
|
/* Locked by "lock". */
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mutex_t lock; /*%< locks all below */
|
|
|
|
isc_sockettype_t socktype;
|
|
|
|
unsigned int attributes;
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_t refcount;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */
|
2021-01-04 23:03:50 -08:00
|
|
|
unsigned int shutting_down : 1, shutdown_out : 1, recv_pending : 1,
|
|
|
|
tcpmsg_valid : 1;
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_result_t shutdown_why;
|
|
|
|
ISC_LIST(dispsocket_t) activesockets;
|
|
|
|
ISC_LIST(dispsocket_t) inactivesockets;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int nsockets;
|
|
|
|
unsigned int requests; /*%< how many requests we have */
|
|
|
|
unsigned int tcpbuffers; /*%< allocated buffers */
|
2020-12-18 17:21:00 -08:00
|
|
|
tcpmsg_t tcpmsg;
|
1999-06-16 01:32:31 +00:00
|
|
|
};
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC)
|
2000-09-18 04:50:05 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC)
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DISPSOCK_MAGIC ISC_MAGIC('D', 's', 'o', 'c')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_DISPSOCK(e) ISC_MAGIC_VALID((e), DISPSOCK_MAGIC)
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC)
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r')
|
2020-02-13 14:44:37 -08:00
|
|
|
#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC)
|
1999-06-18 02:01:42 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
/*%
|
|
|
|
* Maximum number of dispatch sockets that can be pooled for reuse. The
|
|
|
|
* appropriate value may vary, but experiments have shown a busy caching server
|
|
|
|
* may need more than 1000 sockets concurrently opened. The maximum allowable
|
|
|
|
* number of dispatch sockets (per manager) will be set to the double of this
|
|
|
|
* value.
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_POOLSOCKS
|
|
|
|
#define DNS_DISPATCH_POOLSOCKS 2048
|
|
|
|
#endif /* ifndef DNS_DISPATCH_POOLSOCKS */
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Quota to control the number of UDP dispatch sockets. If a dispatch has
|
|
|
|
* more than the quota of sockets, new queries will purge oldest ones, so
|
|
|
|
* that a massive number of outstanding queries won't prevent subsequent
|
|
|
|
* queries (especially if the older ones take longer time and result in
|
|
|
|
* timeout).
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_SOCKSQUOTA
|
|
|
|
#define DNS_DISPATCH_SOCKSQUOTA 3072
|
|
|
|
#endif /* ifndef DNS_DISPATCH_SOCKSQUOTA */
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Number of buffers available for all dispatches in the buffery memory
|
|
|
|
* pool.
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_MAXBUFFERS
|
|
|
|
#define DNS_DISPATCH_MAXBUFFERS 32768
|
|
|
|
#endif /* ifndef DNS_DISPATCH_MAXBUFFERS */
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Number of dispatch sockets available for all dispatches in the
|
|
|
|
* socket memory pool.
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_MAXSOCKETS
|
|
|
|
#define DNS_DISPATCH_MAXSOCKETS 32768
|
|
|
|
#endif /* ifndef DNS_DISPATCH_MAXSOCKETS */
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Quota to control the number of concurrent requests that can be handled
|
|
|
|
* by each TCP dispatch. (UDP dispatches do not currently support socket
|
|
|
|
* sharing.)
|
|
|
|
*/
|
|
|
|
#ifndef DNS_DISPATCH_MAXREQUESTS
|
|
|
|
#define DNS_DISPATCH_MAXREQUESTS 32768
|
|
|
|
#endif /* ifndef DNS_DISPATCH_MAXREQUESTS */
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
/*%
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
* Number of buckets in the QID hash table, and the value to
|
|
|
|
* increment the QID by when attempting to avoid collisions.
|
|
|
|
* The number of buckets should be prime, and the increment
|
|
|
|
* should be the next higher prime number.
|
2008-06-23 19:41:20 +00:00
|
|
|
*/
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
#ifndef DNS_QID_BUCKETS
|
|
|
|
#define DNS_QID_BUCKETS 16411
|
|
|
|
#endif /* ifndef DNS_QID_BUCKETS */
|
|
|
|
#ifndef DNS_QID_INCREMENT
|
|
|
|
#define DNS_QID_INCREMENT 16433
|
|
|
|
#endif /* ifndef DNS_QID_INCREMENT */
|
2008-06-23 19:41:20 +00:00
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
2000-05-13 21:57:02 +00:00
|
|
|
* Statics.
|
1999-06-30 01:33:11 +00:00
|
|
|
*/
|
2020-02-14 08:14:03 +01:00
|
|
|
static dns_dispentry_t *
|
|
|
|
entry_search(dns_qid_t *, const isc_sockaddr_t *, dns_messageid_t, in_port_t,
|
|
|
|
unsigned int);
|
|
|
|
static bool
|
|
|
|
destroy_disp_ok(dns_dispatch_t *);
|
|
|
|
static void
|
|
|
|
destroy_disp(isc_task_t *task, isc_event_t *event);
|
|
|
|
static void
|
|
|
|
destroy_dispsocket(dns_dispatch_t *, dispsocket_t **);
|
|
|
|
static void
|
|
|
|
deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *);
|
|
|
|
static void
|
2020-12-16 01:32:06 -08:00
|
|
|
udp_recv(isc_task_t *, isc_event_t *);
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
tcp_recv(isc_task_t *, isc_event_t *);
|
|
|
|
static isc_result_t
|
|
|
|
startrecv(dns_dispatch_t *, dispsocket_t *);
|
|
|
|
static uint32_t
|
|
|
|
dns_hash(dns_qid_t *, const isc_sockaddr_t *, dns_messageid_t, in_port_t);
|
|
|
|
static void
|
|
|
|
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
|
|
|
|
static void *
|
|
|
|
allocate_udp_buffer(dns_dispatch_t *disp);
|
|
|
|
static inline void
|
|
|
|
free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
|
|
|
|
static inline dns_dispatchevent_t *
|
|
|
|
allocate_devent(dns_dispatch_t *disp);
|
|
|
|
static void
|
|
|
|
do_cancel(dns_dispatch_t *disp);
|
|
|
|
static dns_dispentry_t *
|
|
|
|
linear_first(dns_qid_t *disp);
|
|
|
|
static dns_dispentry_t *
|
|
|
|
linear_next(dns_qid_t *disp, dns_dispentry_t *resp);
|
|
|
|
static void
|
|
|
|
dispatch_free(dns_dispatch_t **dispp);
|
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|
|
|
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
unsigned int attributes, dns_dispatch_t **dispp);
|
2020-02-14 08:14:03 +01:00
|
|
|
static bool
|
|
|
|
destroy_mgr_ok(dns_dispatchmgr_t *mgr);
|
|
|
|
static void
|
|
|
|
destroy_mgr(dns_dispatchmgr_t **mgrp);
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
static void
|
|
|
|
qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp);
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp);
|
|
|
|
static isc_result_t
|
|
|
|
open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
unsigned int options, isc_socket_t **sockp);
|
2021-01-04 23:51:07 -08:00
|
|
|
static isc_socket_t *
|
|
|
|
getentrysocket(dns_dispentry_t *resp);
|
|
|
|
static isc_socket_t *
|
|
|
|
getsocket(dns_dispatch_t *disp);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
#define LVL(x) ISC_LOG_DEBUG(x)
|
1999-07-08 02:50:00 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...)
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_FORMAT_PRINTF(3, 4);
|
2001-08-08 22:54:55 +00:00
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) {
|
|
|
|
char msgbuf[2048];
|
2000-04-29 00:45:26 +00:00
|
|
|
va_list ap;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!isc_log_wouldlog(dns_lctx, level)) {
|
2000-07-17 23:25:35 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-07-17 23:25:35 +00:00
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
|
|
|
|
DNS_LOGMODULE_DISPATCH, level, "dispatchmgr %p: %s", mgr,
|
|
|
|
msgbuf);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 00:10:24 +00:00
|
|
|
static inline void
|
2020-02-13 14:44:37 -08:00
|
|
|
inc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (mgr->stats != NULL) {
|
2009-01-31 00:10:24 +00:00
|
|
|
isc_stats_increment(mgr->stats, counter);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-31 00:10:24 +00:00
|
|
|
}
|
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
static inline void
|
2020-02-13 14:44:37 -08:00
|
|
|
dec_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (mgr->stats != NULL) {
|
2012-05-14 10:06:05 -07:00
|
|
|
isc_stats_decrement(mgr->stats, counter);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
}
|
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...)
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_FORMAT_PRINTF(3, 4);
|
2001-08-08 22:54:55 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) {
|
|
|
|
char msgbuf[2048];
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
va_list ap;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!isc_log_wouldlog(dns_lctx, level)) {
|
2000-07-13 01:16:22 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
|
|
|
|
DNS_LOGMODULE_DISPATCH, level, "dispatch %p: %s", disp,
|
|
|
|
msgbuf);
|
2000-04-29 00:45:26 +00:00
|
|
|
}
|
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level,
|
|
|
|
const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
|
2001-08-08 22:54:55 +00:00
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
static void
|
2020-02-12 13:59:18 +01:00
|
|
|
request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level,
|
2020-02-13 14:44:37 -08:00
|
|
|
const char *fmt, ...) {
|
|
|
|
char msgbuf[2048];
|
|
|
|
char peerbuf[256];
|
2000-04-29 00:45:26 +00:00
|
|
|
va_list ap;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!isc_log_wouldlog(dns_lctx, level)) {
|
2000-07-17 23:25:35 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-07-17 23:25:35 +00:00
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
if (VALID_RESPONSE(resp)) {
|
2001-11-12 19:05:39 +00:00
|
|
|
isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf));
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
|
|
|
|
DNS_LOGMODULE_DISPATCH, level,
|
2000-08-24 16:56:48 +00:00
|
|
|
"dispatch %p response %p %s: %s", disp, resp,
|
2000-04-29 00:45:26 +00:00
|
|
|
peerbuf, msgbuf);
|
|
|
|
} else {
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
|
|
|
|
DNS_LOGMODULE_DISPATCH, level,
|
|
|
|
"dispatch %p req/resp %p: %s", disp, resp,
|
|
|
|
msgbuf);
|
2000-04-29 00:45:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-01-07 01:17:47 +00:00
|
|
|
/*
|
|
|
|
* Return a hash of the destination and message id.
|
|
|
|
*/
|
2018-03-28 14:19:37 +02:00
|
|
|
static uint32_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_hash(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id,
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t port) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t ret;
|
2000-01-07 01:17:47 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
ret = isc_sockaddr_hash(dest, true);
|
2018-03-28 14:19:37 +02:00
|
|
|
ret ^= ((uint32_t)id << 16) | port;
|
2000-09-18 04:50:05 +00:00
|
|
|
ret %= qid->qid_nbuckets;
|
2000-01-07 01:17:47 +00:00
|
|
|
|
2000-09-18 04:50:05 +00:00
|
|
|
INSIST(ret < qid->qid_nbuckets);
|
2000-01-07 01:17:47 +00:00
|
|
|
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2001-01-25 13:47:59 +00:00
|
|
|
/*
|
|
|
|
* Find the first entry in 'qid'. Returns NULL if there are no entries.
|
|
|
|
*/
|
1999-07-08 02:50:00 +00:00
|
|
|
static dns_dispentry_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
linear_first(dns_qid_t *qid) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *ret = NULL;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
unsigned int bucket = 0;
|
1999-07-08 02:50:00 +00:00
|
|
|
|
2000-09-18 04:50:05 +00:00
|
|
|
while (bucket < qid->qid_nbuckets) {
|
|
|
|
ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != NULL) {
|
1999-07-08 02:50:00 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-08 02:50:00 +00:00
|
|
|
bucket++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2001-01-25 13:47:59 +00:00
|
|
|
/*
|
|
|
|
* Find the next entry after 'resp' in 'qid'. Return NULL if there are
|
|
|
|
* no more entries.
|
|
|
|
*/
|
1999-07-08 02:50:00 +00:00
|
|
|
static dns_dispentry_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
linear_next(dns_qid_t *qid, dns_dispentry_t *resp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *ret = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int bucket;
|
1999-07-08 02:50:00 +00:00
|
|
|
|
|
|
|
ret = ISC_LIST_NEXT(resp, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != NULL) {
|
1999-07-08 02:50:00 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-08 02:50:00 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
bucket = resp->bucket + 1;
|
2000-09-18 04:50:05 +00:00
|
|
|
while (bucket < qid->qid_nbuckets) {
|
|
|
|
ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != NULL) {
|
1999-07-08 02:50:00 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-08 02:50:00 +00:00
|
|
|
bucket++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
1999-06-30 01:33:11 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
/*
|
|
|
|
* The dispatch must be locked.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy_disp_ok(dns_dispatch_t *disp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
if (isc_refcount_current(&disp->refcount) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->recv_pending != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!ISC_LIST_EMPTY(disp->activesockets)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->shutting_down == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
}
|
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
2000-05-10 21:34:50 +00:00
|
|
|
* Called when refcount reaches 0 (and safe to destroy).
|
|
|
|
*
|
2013-12-23 09:50:18 -08:00
|
|
|
* The dispatcher must be locked.
|
|
|
|
* The manager must not be locked.
|
1999-06-30 01:33:11 +00:00
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy_disp(isc_task_t *task, isc_event_t *event) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool killmgr;
|
2020-12-09 19:44:41 -08:00
|
|
|
dispsocket_t *dispsocket = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
int i;
|
2000-05-10 21:34:50 +00:00
|
|
|
|
2001-01-27 02:08:07 +00:00
|
|
|
INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL);
|
|
|
|
|
|
|
|
UNUSED(task);
|
|
|
|
|
|
|
|
disp = event->ev_arg;
|
2000-05-10 21:34:50 +00:00
|
|
|
mgr = disp->mgr;
|
|
|
|
|
2001-01-27 02:08:07 +00:00
|
|
|
LOCK(&mgr->lock);
|
2000-05-10 21:34:50 +00:00
|
|
|
ISC_LIST_UNLINK(mgr->list, disp, link);
|
1999-07-08 02:50:00 +00:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
dispatch_log(disp, LVL(90), "shutting down; detaching from sock %p",
|
|
|
|
disp->socket);
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2012-04-28 14:52:28 -07:00
|
|
|
if (disp->sepool != NULL) {
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_destroy(&disp->sepool);
|
2012-04-28 14:52:28 -07:00
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->socket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_detach(&disp->socket);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(disp->inactivesockets, dispsocket, link);
|
|
|
|
destroy_dispsocket(disp, &dispsocket);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
for (i = 0; i < disp->ntasks; i++) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_detach(&disp->task[i]);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-27 02:08:07 +00:00
|
|
|
isc_event_free(&event);
|
2000-01-06 23:01:07 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dispatch_free(&disp);
|
2001-01-27 02:08:07 +00:00
|
|
|
|
|
|
|
killmgr = destroy_mgr_ok(mgr);
|
|
|
|
UNLOCK(&mgr->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killmgr) {
|
2001-01-27 02:08:07 +00:00
|
|
|
destroy_mgr(&mgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-06-30 01:33:11 +00:00
|
|
|
}
|
|
|
|
|
2008-08-15 17:29:52 +00:00
|
|
|
/*%
|
|
|
|
* Find a dispsocket for socket address 'dest', and port number 'port'.
|
2014-04-07 13:54:08 -07:00
|
|
|
* Return NULL if no such entry exists. Requires qid->lock to be held.
|
2008-08-15 17:29:52 +00:00
|
|
|
*/
|
|
|
|
static dispsocket_t *
|
2016-12-30 15:45:08 +11:00
|
|
|
socket_search(dns_qid_t *qid, const isc_sockaddr_t *dest, in_port_t port,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int bucket) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dispsocket_t *dispsock = NULL;
|
2008-08-15 17:29:52 +00:00
|
|
|
|
2013-12-23 09:50:18 -08:00
|
|
|
REQUIRE(VALID_QID(qid));
|
2008-08-15 17:29:52 +00:00
|
|
|
REQUIRE(bucket < qid->qid_nbuckets);
|
|
|
|
|
|
|
|
dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
|
|
|
|
|
|
|
|
while (dispsock != NULL) {
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
if (dispsock->port == port &&
|
|
|
|
isc_sockaddr_equal(dest, &dispsock->host)) {
|
2008-08-15 17:29:52 +00:00
|
|
|
return (dispsock);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-08-15 17:29:52 +00:00
|
|
|
dispsock = ISC_LIST_NEXT(dispsock, blink);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
/*%
|
|
|
|
* Make a new socket for a single dispatch with a random port number.
|
2012-04-28 14:52:28 -07:00
|
|
|
* The caller must hold the disp->lock
|
2008-06-23 19:41:20 +00:00
|
|
|
*/
|
|
|
|
static isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest,
|
2012-04-28 14:52:28 -07:00
|
|
|
isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp,
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t *portp) {
|
|
|
|
int i;
|
|
|
|
dns_dispatchmgr_t *mgr = disp->mgr;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dns_qid_t *qid = mgr->qid;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
isc_result_t result = ISC_R_FAILURE;
|
|
|
|
in_port_t port;
|
|
|
|
isc_sockaddr_t localaddr;
|
|
|
|
unsigned int bucket = 0;
|
2020-12-09 19:44:41 -08:00
|
|
|
dispsocket_t *dispsock = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int nports;
|
2020-12-09 19:44:41 -08:00
|
|
|
in_port_t *ports = NULL;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
if (isc_sockaddr_pf(&disp->local) == AF_INET) {
|
2020-12-09 19:44:41 -08:00
|
|
|
nports = mgr->nv4ports;
|
|
|
|
ports = mgr->v4ports;
|
2008-06-23 19:41:20 +00:00
|
|
|
} else {
|
2020-12-09 19:44:41 -08:00
|
|
|
nports = mgr->nv6ports;
|
|
|
|
ports = mgr->v6ports;
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (nports == 0) {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (ISC_R_ADDRNOTAVAIL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
dispsock = ISC_LIST_HEAD(disp->inactivesockets);
|
|
|
|
if (dispsock != NULL) {
|
|
|
|
ISC_LIST_UNLINK(disp->inactivesockets, dispsock, link);
|
|
|
|
sock = dispsock->socket;
|
|
|
|
dispsock->socket = NULL;
|
|
|
|
} else {
|
2021-05-12 21:16:17 +02:00
|
|
|
dispsock = isc_mem_get(mgr->mctx, sizeof(*dispsock));
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
disp->nsockets++;
|
2020-12-09 19:44:41 -08:00
|
|
|
|
|
|
|
*dispsock = (dispsocket_t){ .disp = disp };
|
2018-05-28 15:22:23 +02:00
|
|
|
isc_task_attach(disp->task[isc_random_uniform(disp->ntasks)],
|
|
|
|
&dispsock->task);
|
2008-06-23 19:41:20 +00:00
|
|
|
ISC_LINK_INIT(dispsock, link);
|
2008-08-15 17:29:52 +00:00
|
|
|
ISC_LINK_INIT(dispsock, blink);
|
2008-06-23 19:41:20 +00:00
|
|
|
dispsock->magic = DISPSOCK_MAGIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pick up a random UDP port and open a new socket with it. Avoid
|
|
|
|
* choosing ports that share the same destination because it will be
|
|
|
|
* very likely to fail in bind(2) or connect(2).
|
|
|
|
*/
|
|
|
|
localaddr = disp->local;
|
2012-04-28 14:52:28 -07:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
for (i = 0; i < 64; i++) {
|
2018-04-22 14:56:28 +02:00
|
|
|
port = ports[isc_random_uniform(nports)];
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_sockaddr_setport(&localaddr, port);
|
|
|
|
|
2012-04-28 14:52:28 -07:00
|
|
|
LOCK(&qid->lock);
|
2008-08-15 17:29:52 +00:00
|
|
|
bucket = dns_hash(qid, dest, 0, port);
|
2012-04-28 14:52:28 -07:00
|
|
|
if (socket_search(qid, dest, port, bucket) != NULL) {
|
|
|
|
UNLOCK(&qid->lock);
|
2008-06-23 19:41:20 +00:00
|
|
|
continue;
|
2012-04-28 14:52:28 -07:00
|
|
|
}
|
|
|
|
UNLOCK(&qid->lock);
|
2020-12-18 14:59:50 -08:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
result = open_socket(sockmgr, &localaddr,
|
|
|
|
ISC_SOCKET_REUSEADDRESS, &sock);
|
2008-11-12 23:10:57 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
break;
|
2011-04-06 10:27:16 +00:00
|
|
|
} else if (result == ISC_R_NOPERM) {
|
|
|
|
char buf[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
isc_sockaddr_format(&localaddr, buf, sizeof(buf));
|
|
|
|
dispatch_log(disp, ISC_LOG_WARNING,
|
2020-02-12 13:59:18 +01:00
|
|
|
"open_socket(%s) -> %s: continuing", buf,
|
|
|
|
isc_result_totext(result));
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_ADDRINUSE) {
|
2008-06-23 19:41:20 +00:00
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (sock != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_detach(&sock);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
destroy_dispsocket(disp, &dispsock);
|
2020-12-16 01:32:06 -08:00
|
|
|
return (result);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
dispsock->socket = sock;
|
|
|
|
dispsock->host = *dest;
|
|
|
|
dispsock->bucket = bucket;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dispsock->port = port;
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
LOCK(&qid->lock);
|
|
|
|
ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink);
|
|
|
|
UNLOCK(&qid->lock);
|
|
|
|
*dispsockp = dispsock;
|
|
|
|
*portp = port;
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Destroy a dedicated dispatch socket.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dispsocket_t *dispsock = NULL;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dns_qid_t *qid = disp->mgr->qid;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The dispatch must be locked.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(dispsockp != NULL && *dispsockp != NULL);
|
|
|
|
dispsock = *dispsockp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*dispsockp = NULL;
|
2008-06-23 19:41:20 +00:00
|
|
|
REQUIRE(!ISC_LINK_LINKED(dispsock, link));
|
|
|
|
|
|
|
|
disp->nsockets--;
|
|
|
|
dispsock->magic = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispsock->socket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_detach(&dispsock->socket);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-08-15 17:29:52 +00:00
|
|
|
if (ISC_LINK_LINKED(dispsock, blink)) {
|
|
|
|
LOCK(&qid->lock);
|
|
|
|
ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
|
|
|
|
blink);
|
|
|
|
UNLOCK(&qid->lock);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispsock->task != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_detach(&dispsock->task);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_put(disp->mgr->mctx, dispsock, sizeof(*dispsock));
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Deactivate a dedicated dispatch socket. Move it to the inactive list for
|
|
|
|
* future reuse unless the total number of sockets are exceeding the maximum.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
2008-07-03 00:13:25 +00:00
|
|
|
isc_result_t result;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dns_qid_t *qid = disp->mgr->qid;
|
2008-07-03 00:13:25 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
/*
|
|
|
|
* The dispatch must be locked.
|
|
|
|
*/
|
|
|
|
ISC_LIST_UNLINK(disp->activesockets, dispsock, link);
|
|
|
|
if (dispsock->resp != NULL) {
|
|
|
|
INSIST(dispsock->resp->dispsocket == dispsock);
|
|
|
|
dispsock->resp->dispsocket = NULL;
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS) {
|
2008-06-23 19:41:20 +00:00
|
|
|
destroy_dispsocket(disp, &dispsock);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-07-03 00:13:25 +00:00
|
|
|
result = isc_socket_close(dispsock->socket);
|
2008-08-15 17:29:52 +00:00
|
|
|
|
|
|
|
LOCK(&qid->lock);
|
|
|
|
ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
|
|
|
|
blink);
|
|
|
|
UNLOCK(&qid->lock);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2008-07-03 00:13:25 +00:00
|
|
|
ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-07-03 00:13:25 +00:00
|
|
|
/*
|
|
|
|
* If the underlying system does not allow this
|
|
|
|
* optimization, destroy this temporary structure (and
|
|
|
|
* create a new one for a new transaction).
|
|
|
|
*/
|
|
|
|
INSIST(result == ISC_R_NOTIMPLEMENTED);
|
|
|
|
destroy_dispsocket(disp, &dispsock);
|
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
}
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2001-01-25 13:47:59 +00:00
|
|
|
/*
|
2008-06-23 19:41:20 +00:00
|
|
|
* Find an entry for query ID 'id', socket address 'dest', and port number
|
2008-08-15 17:29:52 +00:00
|
|
|
* 'port'.
|
2001-01-25 13:47:59 +00:00
|
|
|
* Return NULL if no such entry exists.
|
|
|
|
*/
|
1999-07-06 19:32:40 +00:00
|
|
|
static dns_dispentry_t *
|
2016-12-30 15:45:08 +11:00
|
|
|
entry_search(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id,
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t port, unsigned int bucket) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *res = NULL;
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2013-12-23 09:50:18 -08:00
|
|
|
REQUIRE(VALID_QID(qid));
|
2000-09-18 04:50:05 +00:00
|
|
|
REQUIRE(bucket < qid->qid_nbuckets);
|
1999-07-09 20:34:26 +00:00
|
|
|
|
2008-08-15 17:29:52 +00:00
|
|
|
res = ISC_LIST_HEAD(qid->qid_table[bucket]);
|
1999-06-30 01:33:11 +00:00
|
|
|
|
|
|
|
while (res != NULL) {
|
2008-08-15 17:29:52 +00:00
|
|
|
if (res->id == id && isc_sockaddr_equal(dest, &res->host) &&
|
2008-06-23 19:41:20 +00:00
|
|
|
res->port == port) {
|
1999-06-30 01:33:11 +00:00
|
|
|
return (res);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
1999-06-30 01:33:11 +00:00
|
|
|
res = ISC_LIST_NEXT(res, link);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
1999-07-08 02:50:00 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
2020-12-09 15:45:13 -08:00
|
|
|
REQUIRE(buf != NULL && len != 0);
|
2000-09-19 06:59:28 +00:00
|
|
|
|
2000-06-16 00:52:05 +00:00
|
|
|
switch (disp->socktype) {
|
1999-07-13 01:49:33 +00:00
|
|
|
case isc_sockettype_tcp:
|
2000-09-19 06:59:28 +00:00
|
|
|
INSIST(disp->tcpbuffers > 0);
|
|
|
|
disp->tcpbuffers--;
|
2000-05-10 21:34:50 +00:00
|
|
|
isc_mem_put(disp->mgr->mctx, buf, len);
|
1999-07-12 23:44:31 +00:00
|
|
|
break;
|
1999-07-13 01:49:33 +00:00
|
|
|
case isc_sockettype_udp:
|
2000-09-19 06:59:28 +00:00
|
|
|
LOCK(&disp->mgr->buffer_lock);
|
|
|
|
INSIST(disp->mgr->buffers > 0);
|
2020-12-09 15:45:13 -08:00
|
|
|
INSIST(len == DNS_DISPATCH_UDPBUFSIZE);
|
2000-09-19 06:59:28 +00:00
|
|
|
disp->mgr->buffers--;
|
|
|
|
UNLOCK(&disp->mgr->buffer_lock);
|
2020-12-09 15:45:13 -08:00
|
|
|
isc_mem_put(disp->mgr->mctx, buf, len);
|
1999-07-12 23:44:31 +00:00
|
|
|
break;
|
|
|
|
default:
|
1999-07-22 01:34:31 +00:00
|
|
|
INSIST(0);
|
2018-11-07 15:00:07 +07:00
|
|
|
ISC_UNREACHABLE();
|
1999-07-12 23:44:31 +00:00
|
|
|
}
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2020-02-13 14:44:37 -08:00
|
|
|
allocate_udp_buffer(dns_dispatch_t *disp) {
|
2000-09-19 06:59:28 +00:00
|
|
|
LOCK(&disp->mgr->buffer_lock);
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
if (disp->mgr->buffers >= DNS_DISPATCH_MAXBUFFERS) {
|
2019-11-25 11:38:09 +11:00
|
|
|
UNLOCK(&disp->mgr->buffer_lock);
|
|
|
|
return (NULL);
|
|
|
|
}
|
2012-04-28 14:52:28 -07:00
|
|
|
disp->mgr->buffers++;
|
2000-09-19 06:59:28 +00:00
|
|
|
UNLOCK(&disp->mgr->buffer_lock);
|
1999-07-09 02:47:55 +00:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
return (isc_mem_get(disp->mgr->mctx, DNS_DISPATCH_UDPBUFSIZE));
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_sevent(isc_event_t *ev) {
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_t *pool = ev->ev_destroy_arg;
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_socketevent_t *sev = (isc_socketevent_t *)ev;
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_put(pool, sev, sizeof(*sev));
|
2012-04-28 14:52:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline isc_socketevent_t *
|
2020-02-12 13:59:18 +01:00
|
|
|
allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock, isc_eventtype_t type,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_taskaction_t action, const void *arg) {
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_socketevent_t *ev = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
void *deconst_arg;
|
2012-04-28 14:52:28 -07:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
ev = isc_mem_get(disp->sepool, sizeof(*ev));
|
2012-04-28 14:52:28 -07:00
|
|
|
DE_CONST(arg, deconst_arg);
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, action, deconst_arg,
|
|
|
|
sock, free_sevent, disp->sepool);
|
2012-04-28 14:52:28 -07:00
|
|
|
ev->result = ISC_R_UNSET;
|
|
|
|
ISC_LINK_INIT(ev, ev_link);
|
|
|
|
ev->region.base = NULL;
|
|
|
|
ev->n = 0;
|
|
|
|
ev->offset = 0;
|
|
|
|
ev->attributes = 0;
|
|
|
|
|
|
|
|
return (ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
1999-07-08 02:50:00 +00:00
|
|
|
if (disp->failsafe_ev == ev) {
|
|
|
|
INSIST(disp->shutdown_out == 1);
|
|
|
|
disp->shutdown_out = 0;
|
2000-04-29 00:45:26 +00:00
|
|
|
|
1999-07-08 02:50:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_decrement(&disp->mgr->irefs);
|
|
|
|
isc_mem_put(disp->mgr->mctx, ev, sizeof(*ev));
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline dns_dispatchevent_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
allocate_devent(dns_dispatch_t *disp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchevent_t *ev = NULL;
|
1999-07-08 02:50:00 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
ev = isc_mem_get(disp->mgr->mctx, sizeof(*ev));
|
|
|
|
isc_refcount_increment0(&disp->mgr->irefs);
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL,
|
|
|
|
NULL);
|
1999-07-08 02:50:00 +00:00
|
|
|
return (ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* General flow:
|
|
|
|
*
|
2001-05-14 23:10:19 +00:00
|
|
|
* If I/O result == CANCELED or error, free the buffer.
|
1999-07-08 02:50:00 +00:00
|
|
|
*
|
2002-09-04 02:26:13 +00:00
|
|
|
* If query, free the buffer, restart.
|
1999-07-08 02:50:00 +00:00
|
|
|
*
|
|
|
|
* If response:
|
|
|
|
* Allocate event, fill in details.
|
|
|
|
* If cannot allocate, free buffer, restart.
|
|
|
|
* find target. If not found, free buffer, restart.
|
|
|
|
* if event queue is not empty, queue. else, send.
|
|
|
|
* restart.
|
|
|
|
*/
|
1999-06-30 01:33:11 +00:00
|
|
|
static void
|
2020-12-16 01:32:06 -08:00
|
|
|
udp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
|
2020-12-16 01:32:06 -08:00
|
|
|
dispsocket_t *dispsock = NULL;
|
|
|
|
dns_dispatch_t *disp = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_messageid_t id;
|
|
|
|
isc_result_t dres;
|
|
|
|
isc_buffer_t source;
|
|
|
|
unsigned int flags;
|
|
|
|
dns_dispentry_t *resp = NULL;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchevent_t *rev = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool killit;
|
|
|
|
bool queue_response;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_netaddr_t netaddr;
|
|
|
|
int match;
|
|
|
|
int result;
|
2020-12-16 01:32:06 -08:00
|
|
|
|
|
|
|
UNUSED(task);
|
|
|
|
|
|
|
|
REQUIRE(ev->ev_type == ISC_SOCKEVENT_RECVDONE);
|
|
|
|
|
|
|
|
dispsock = ev_in->ev_arg;
|
|
|
|
|
|
|
|
REQUIRE(VALID_DISPSOCK(dispsock));
|
|
|
|
|
|
|
|
disp = dispsock->disp;
|
1999-06-30 01:33:11 +00:00
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
mgr = disp->mgr;
|
|
|
|
|
2019-11-22 11:55:47 +11:00
|
|
|
LOCK(&disp->mgr->buffer_lock);
|
2000-04-29 00:45:26 +00:00
|
|
|
dispatch_log(disp, LVL(90),
|
2000-06-16 15:51:58 +00:00
|
|
|
"got packet: requests %d, buffers %d, recvs %d",
|
2001-01-13 01:33:27 +00:00
|
|
|
disp->requests, disp->mgr->buffers, disp->recv_pending);
|
2019-11-22 11:55:47 +11:00
|
|
|
UNLOCK(&disp->mgr->buffer_lock);
|
1999-07-22 01:34:31 +00:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (ev->result == ISC_R_CANCELED || dispsock->resp == NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
/*
|
|
|
|
* dispsock->resp can be NULL if this transaction was canceled
|
|
|
|
* just after receiving a response. Since this socket is
|
|
|
|
* exclusively used and there should be at most one receive
|
2020-12-16 01:32:06 -08:00
|
|
|
* event the canceled event should have no effect. So
|
2008-06-23 19:41:20 +00:00
|
|
|
* we can (and should) deactivate the socket right now.
|
|
|
|
*/
|
|
|
|
deactivate_dispsocket(disp, dispsock);
|
|
|
|
dispsock = NULL;
|
|
|
|
}
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
if (disp->shutting_down) {
|
2000-02-02 23:29:47 +00:00
|
|
|
/*
|
|
|
|
* This dispatcher is shutting down.
|
|
|
|
*/
|
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_event_free(&ev_in);
|
|
|
|
ev = NULL;
|
2000-02-02 23:29:47 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
killit = destroy_disp_ok(disp);
|
2000-02-02 23:29:47 +00:00
|
|
|
UNLOCK(&disp->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killit) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_send(disp->task[0], &disp->ctlevent);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-02 23:29:47 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (dispsock == NULL) {
|
2000-02-02 23:29:47 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2001-05-14 23:10:19 +00:00
|
|
|
isc_event_free(&ev_in);
|
2014-08-06 18:49:53 +10:00
|
|
|
UNLOCK(&disp->lock);
|
2001-05-14 23:10:19 +00:00
|
|
|
return;
|
1999-06-30 01:33:11 +00:00
|
|
|
}
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
resp = dispsock->resp;
|
|
|
|
id = resp->id;
|
|
|
|
|
|
|
|
if (ev->result != ISC_R_SUCCESS) {
|
|
|
|
/*
|
|
|
|
* This is most likely a network error on a
|
|
|
|
* connected socket. It makes no sense to
|
|
|
|
* check the address or parse the packet, but it
|
|
|
|
* will help to return the error to the caller.
|
|
|
|
*/
|
|
|
|
goto sendresponse;
|
|
|
|
}
|
|
|
|
|
2000-11-03 02:45:55 +00:00
|
|
|
/*
|
|
|
|
* If this is from a blackholed address, drop it.
|
|
|
|
*/
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, &ev->address);
|
2001-02-08 18:25:09 +00:00
|
|
|
if (disp->mgr->blackhole != NULL &&
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_acl_match(&netaddr, NULL, disp->mgr->blackhole, NULL, &match,
|
|
|
|
NULL) == ISC_R_SUCCESS &&
|
2020-02-13 14:44:37 -08:00
|
|
|
match > 0)
|
|
|
|
{
|
2000-11-03 02:45:55 +00:00
|
|
|
if (isc_log_wouldlog(dns_lctx, LVL(10))) {
|
|
|
|
char netaddrstr[ISC_NETADDR_FORMATSIZE];
|
|
|
|
isc_netaddr_format(&netaddr, netaddrstr,
|
|
|
|
sizeof(netaddrstr));
|
2020-02-12 13:59:18 +01:00
|
|
|
dispatch_log(disp, LVL(10), "blackholed packet from %s",
|
2000-11-03 02:45:55 +00:00
|
|
|
netaddrstr);
|
|
|
|
}
|
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
|
|
|
* Peek into the buffer to see what we can see.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&source, ev->region.base, ev->region.length);
|
1999-07-08 22:12:37 +00:00
|
|
|
isc_buffer_add(&source, ev->n);
|
1999-06-30 01:33:11 +00:00
|
|
|
dres = dns_message_peekheader(&source, &id, &flags);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (dres != ISC_R_SUCCESS) {
|
1999-07-08 02:50:00 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2000-06-16 15:51:58 +00:00
|
|
|
dispatch_log(disp, LVL(10), "got garbage packet");
|
1999-06-30 01:33:11 +00:00
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
dispatch_log(disp, LVL(92),
|
2000-06-16 15:51:58 +00:00
|
|
|
"got valid DNS message header, /QR %c, id %u",
|
2018-10-11 11:57:57 +02:00
|
|
|
(((flags & DNS_MESSAGEFLAG_QR) != 0) ? '1' : '0'), id);
|
1999-07-08 22:12:37 +00:00
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
2001-02-07 05:11:58 +00:00
|
|
|
* Look at flags. If query, drop it. If response,
|
|
|
|
* look to see where it goes.
|
1999-06-30 01:33:11 +00:00
|
|
|
*/
|
1999-07-06 19:32:40 +00:00
|
|
|
if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
|
1999-07-08 02:50:00 +00:00
|
|
|
/* query */
|
2001-02-07 05:11:58 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
|
|
|
goto restart;
|
2004-07-21 00:48:19 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
/*
|
2020-12-16 01:32:06 -08:00
|
|
|
* The QID and the address must match the expected ones.
|
2008-06-23 19:41:20 +00:00
|
|
|
*/
|
2020-12-16 01:32:06 -08:00
|
|
|
if (resp->id != id || !isc_sockaddr_equal(&ev->address, &resp->host)) {
|
|
|
|
dispatch_log(disp, LVL(90), "response doesn't match");
|
2020-11-25 12:45:47 +01:00
|
|
|
inc_stats(mgr, dns_resstatscounter_mismatch);
|
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2020-12-16 01:32:06 -08:00
|
|
|
goto restart;
|
2020-11-25 12:45:47 +01:00
|
|
|
}
|
|
|
|
|
2006-01-05 03:26:01 +00:00
|
|
|
/*
|
|
|
|
* Now that we have the original dispatch the query was sent
|
|
|
|
* from check that the address and port the response was
|
|
|
|
* sent to make sense.
|
|
|
|
*/
|
|
|
|
if (disp != resp->disp) {
|
|
|
|
isc_sockaddr_t a1;
|
|
|
|
isc_sockaddr_t a2;
|
2008-04-03 02:01:08 +00:00
|
|
|
|
2006-01-05 03:26:01 +00:00
|
|
|
/*
|
|
|
|
* Check that the socket types and ports match.
|
|
|
|
*/
|
|
|
|
if (disp->socktype != resp->disp->socktype ||
|
|
|
|
isc_sockaddr_getport(&disp->local) !=
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_sockaddr_getport(&resp->disp->local))
|
|
|
|
{
|
2006-01-05 03:26:01 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2020-12-16 01:32:06 -08:00
|
|
|
goto restart;
|
2006-01-05 03:26:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-12-12 22:38:11 -08:00
|
|
|
* If each dispatch is bound to a different address
|
|
|
|
* then fail.
|
2006-01-05 03:26:01 +00:00
|
|
|
*
|
|
|
|
* Note under Linux a packet can be sent out via IPv4 socket
|
|
|
|
* and the response be received via a IPv6 socket.
|
2008-04-03 02:01:08 +00:00
|
|
|
*
|
2006-01-05 03:26:01 +00:00
|
|
|
* Requests sent out via IPv6 should always come back in
|
|
|
|
* via IPv6.
|
|
|
|
*/
|
|
|
|
if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 &&
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_sockaddr_pf(&disp->local) != PF_INET6)
|
|
|
|
{
|
2006-01-05 03:26:01 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2020-12-16 01:32:06 -08:00
|
|
|
goto restart;
|
2006-01-05 03:26:01 +00:00
|
|
|
}
|
|
|
|
isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local));
|
|
|
|
isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local));
|
2013-12-12 22:38:11 -08:00
|
|
|
if (!isc_sockaddr_eqaddr(&disp->local, &resp->disp->local) &&
|
|
|
|
!isc_sockaddr_eqaddr(&a1, &resp->disp->local) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
!isc_sockaddr_eqaddr(&a2, &disp->local))
|
|
|
|
{
|
2006-01-05 03:26:01 +00:00
|
|
|
free_buffer(disp, ev->region.base, ev->region.length);
|
2020-12-16 01:32:06 -08:00
|
|
|
goto restart;
|
2006-01-05 03:26:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
sendresponse:
|
2004-07-21 00:48:19 +00:00
|
|
|
queue_response = resp->item_out;
|
2012-04-28 14:52:28 -07:00
|
|
|
rev = allocate_devent(resp->disp);
|
1999-06-30 01:33:11 +00:00
|
|
|
|
1999-07-08 22:12:37 +00:00
|
|
|
/*
|
|
|
|
* At this point, rev contains the event we want to fill in, and
|
|
|
|
* resp contains the information on the place to send it to.
|
|
|
|
* Send the event off.
|
|
|
|
*/
|
2000-09-19 06:59:28 +00:00
|
|
|
isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length);
|
|
|
|
isc_buffer_add(&rev->buffer, ev->n);
|
2008-06-23 19:41:20 +00:00
|
|
|
rev->result = ev->result;
|
1999-07-09 00:51:08 +00:00
|
|
|
rev->id = id;
|
|
|
|
rev->addr = ev->address;
|
2000-04-17 19:22:44 +00:00
|
|
|
rev->pktinfo = ev->pktinfo;
|
|
|
|
rev->attributes = ev->attributes;
|
2001-02-07 05:11:58 +00:00
|
|
|
if (queue_response) {
|
2000-04-17 19:22:44 +00:00
|
|
|
ISC_LIST_APPEND(resp->items, rev, ev_link);
|
1999-07-09 01:57:55 +00:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
|
1999-07-09 01:57:55 +00:00
|
|
|
resp->action, resp->arg, resp, NULL, NULL);
|
2000-04-29 00:45:26 +00:00
|
|
|
request_log(disp, resp, LVL(90),
|
|
|
|
"[a] Sent event %p buffer %p len %d to task %p",
|
|
|
|
rev, rev->buffer.base, rev->buffer.length,
|
|
|
|
resp->task);
|
2018-04-17 08:29:14 -07:00
|
|
|
resp->item_out = true;
|
2004-04-15 01:58:25 +00:00
|
|
|
isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
|
1999-07-09 01:57:55 +00:00
|
|
|
}
|
1999-07-08 22:12:37 +00:00
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
1999-07-06 19:32:40 +00:00
|
|
|
* Restart recv() to get the next packet.
|
1999-06-30 01:33:11 +00:00
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
restart:
|
2008-06-23 19:41:20 +00:00
|
|
|
result = startrecv(disp, dispsock);
|
2020-12-16 01:32:06 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-06-23 19:41:20 +00:00
|
|
|
deactivate_dispsocket(disp, dispsock);
|
|
|
|
}
|
1999-06-30 01:33:11 +00:00
|
|
|
isc_event_free(&ev_in);
|
2014-08-06 18:49:53 +10:00
|
|
|
UNLOCK(&disp->lock);
|
1999-06-30 01:33:11 +00:00
|
|
|
}
|
|
|
|
|
1999-07-12 23:44:31 +00:00
|
|
|
/*
|
|
|
|
* General flow:
|
|
|
|
*
|
2002-09-04 02:26:13 +00:00
|
|
|
* If I/O result == CANCELED, EOF, or error, notify everyone as the
|
|
|
|
* various queues drain.
|
1999-07-12 23:44:31 +00:00
|
|
|
*
|
2002-09-04 02:26:13 +00:00
|
|
|
* If query, restart.
|
1999-07-12 23:44:31 +00:00
|
|
|
*
|
|
|
|
* If response:
|
|
|
|
* Allocate event, fill in details.
|
2002-09-04 02:26:13 +00:00
|
|
|
* If cannot allocate, restart.
|
|
|
|
* find target. If not found, restart.
|
1999-07-12 23:44:31 +00:00
|
|
|
* if event queue is not empty, queue. else, send.
|
|
|
|
* restart.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
|
|
|
dns_dispatch_t *disp = ev_in->ev_arg;
|
2020-12-18 17:21:00 -08:00
|
|
|
tcpmsg_t *tcpmsg = &disp->tcpmsg;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_messageid_t id;
|
|
|
|
isc_result_t dres;
|
|
|
|
unsigned int flags;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *resp = NULL;
|
|
|
|
dns_dispatchevent_t *rev = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int bucket;
|
|
|
|
bool killit;
|
|
|
|
bool queue_response;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_qid_t *qid = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
int level;
|
|
|
|
char buf[ISC_SOCKADDR_FORMATSIZE];
|
1999-07-12 23:44:31 +00:00
|
|
|
|
2000-04-17 19:22:44 +00:00
|
|
|
UNUSED(task);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
1999-11-16 21:05:09 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
qid = disp->mgr->qid;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2019-11-22 10:49:40 +11:00
|
|
|
LOCK(&disp->lock);
|
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
dispatch_log(disp, LVL(90),
|
2000-06-16 15:51:58 +00:00
|
|
|
"got TCP packet: requests %d, buffers %d, recvs %d",
|
2001-01-13 01:33:27 +00:00
|
|
|
disp->requests, disp->tcpbuffers, disp->recv_pending);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
2001-01-13 01:33:27 +00:00
|
|
|
INSIST(disp->recv_pending != 0);
|
|
|
|
disp->recv_pending = 0;
|
1999-07-12 23:44:31 +00:00
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
if (isc_refcount_current(&disp->refcount) == 0) {
|
2000-02-02 23:29:47 +00:00
|
|
|
/*
|
2020-02-20 14:49:36 -08:00
|
|
|
* This dispatcher is shutting down. Force cancellation.
|
2000-02-02 23:29:47 +00:00
|
|
|
*/
|
|
|
|
tcpmsg->result = ISC_R_CANCELED;
|
|
|
|
}
|
|
|
|
|
2000-09-08 22:02:21 +00:00
|
|
|
if (tcpmsg->result != ISC_R_SUCCESS) {
|
|
|
|
switch (tcpmsg->result) {
|
|
|
|
case ISC_R_CANCELED:
|
|
|
|
break;
|
2008-04-03 02:01:08 +00:00
|
|
|
|
2000-09-08 22:02:21 +00:00
|
|
|
case ISC_R_EOF:
|
|
|
|
dispatch_log(disp, LVL(90), "shutting down on EOF");
|
2004-07-21 00:48:19 +00:00
|
|
|
do_cancel(disp);
|
2000-09-08 22:02:21 +00:00
|
|
|
break;
|
|
|
|
|
2001-12-27 05:07:26 +00:00
|
|
|
case ISC_R_CONNECTIONRESET:
|
|
|
|
level = ISC_LOG_INFO;
|
|
|
|
goto logit;
|
|
|
|
|
2000-09-08 22:02:21 +00:00
|
|
|
default:
|
2001-12-27 05:07:26 +00:00
|
|
|
level = ISC_LOG_ERROR;
|
|
|
|
logit:
|
2002-07-29 01:03:24 +00:00
|
|
|
isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf));
|
2020-02-12 13:59:18 +01:00
|
|
|
dispatch_log(disp, level,
|
|
|
|
"shutting down due to TCP "
|
|
|
|
"receive error: %s: %s",
|
|
|
|
buf, isc_result_totext(tcpmsg->result));
|
2004-07-21 00:48:19 +00:00
|
|
|
do_cancel(disp);
|
2000-09-08 22:02:21 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-04-29 00:45:26 +00:00
|
|
|
|
1999-11-16 21:05:09 +00:00
|
|
|
/*
|
2000-08-01 01:33:37 +00:00
|
|
|
* The event is statically allocated in the tcpmsg
|
2000-05-10 21:34:50 +00:00
|
|
|
* structure, and destroy_disp() frees the tcpmsg, so we must
|
|
|
|
* free the event *before* calling destroy_disp().
|
1999-11-16 21:05:09 +00:00
|
|
|
*/
|
|
|
|
isc_event_free(&ev_in);
|
2002-09-04 02:26:13 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->shutting_down = 1;
|
2001-05-14 22:07:40 +00:00
|
|
|
disp->shutdown_why = tcpmsg->result;
|
1999-11-16 21:05:09 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
/*
|
|
|
|
* If the recv() was canceled pass the word on.
|
|
|
|
*/
|
|
|
|
killit = destroy_disp_ok(disp);
|
|
|
|
UNLOCK(&disp->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killit) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_send(disp->task[0], &disp->ctlevent);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-12 23:44:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",
|
2020-12-18 17:21:00 -08:00
|
|
|
tcpmsg->result, disp->tcpmsg.buffer.length,
|
|
|
|
disp->tcpmsg.buffer.base);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Peek into the buffer to see what we can see.
|
|
|
|
*/
|
2020-12-18 17:21:00 -08:00
|
|
|
dres = dns_message_peekheader(&disp->tcpmsg.buffer, &id, &flags);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (dres != ISC_R_SUCCESS) {
|
2000-06-16 15:51:58 +00:00
|
|
|
dispatch_log(disp, LVL(10), "got garbage packet");
|
1999-07-12 23:44:31 +00:00
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
dispatch_log(disp, LVL(92),
|
2000-06-16 15:51:58 +00:00
|
|
|
"got valid DNS message header, /QR %c, id %u",
|
2018-10-11 11:57:57 +02:00
|
|
|
(((flags & DNS_MESSAGEFLAG_QR) != 0) ? '1' : '0'), id);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate an event to send to the query or response client, and
|
|
|
|
* allocate a new buffer for our use.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2001-02-07 05:11:58 +00:00
|
|
|
* Look at flags. If query, drop it. If response,
|
|
|
|
* look to see where it goes.
|
1999-07-12 23:44:31 +00:00
|
|
|
*/
|
|
|
|
if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
|
2000-07-04 01:48:13 +00:00
|
|
|
/*
|
|
|
|
* Query.
|
|
|
|
*/
|
2001-02-07 05:11:58 +00:00
|
|
|
goto restart;
|
1999-07-12 23:44:31 +00:00
|
|
|
}
|
|
|
|
|
2004-07-21 00:48:19 +00:00
|
|
|
/*
|
|
|
|
* Response.
|
|
|
|
*/
|
2008-06-23 19:41:20 +00:00
|
|
|
bucket = dns_hash(qid, &tcpmsg->address, id, disp->localport);
|
2004-07-21 00:48:19 +00:00
|
|
|
LOCK(&qid->lock);
|
2008-08-15 17:29:52 +00:00
|
|
|
resp = entry_search(qid, &tcpmsg->address, id, disp->localport, bucket);
|
2020-02-12 13:59:18 +01:00
|
|
|
dispatch_log(disp, LVL(90), "search for response in bucket %d: %s",
|
2004-07-21 00:48:19 +00:00
|
|
|
bucket, (resp == NULL ? "not found" : "found"));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (resp == NULL) {
|
2004-07-21 00:48:19 +00:00
|
|
|
goto unlock;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-12-09 19:44:41 -08:00
|
|
|
|
2004-07-21 00:48:19 +00:00
|
|
|
queue_response = resp->item_out;
|
2012-04-28 14:52:28 -07:00
|
|
|
rev = allocate_devent(disp);
|
2004-07-21 00:48:19 +00:00
|
|
|
|
1999-07-12 23:44:31 +00:00
|
|
|
/*
|
|
|
|
* At this point, rev contains the event we want to fill in, and
|
|
|
|
* resp contains the information on the place to send it to.
|
|
|
|
* Send the event off.
|
|
|
|
*/
|
2020-12-18 17:21:00 -08:00
|
|
|
rev->buffer = disp->tcpmsg.buffer;
|
|
|
|
disp->tcpmsg.buffer.base = NULL;
|
|
|
|
disp->tcpmsg.buffer.length = 0;
|
|
|
|
|
2000-09-19 06:59:28 +00:00
|
|
|
disp->tcpbuffers++;
|
2000-04-06 22:03:35 +00:00
|
|
|
rev->result = ISC_R_SUCCESS;
|
1999-07-12 23:44:31 +00:00
|
|
|
rev->id = id;
|
|
|
|
rev->addr = tcpmsg->address;
|
2001-02-07 05:11:58 +00:00
|
|
|
if (queue_response) {
|
2000-04-17 19:22:44 +00:00
|
|
|
ISC_LIST_APPEND(resp->items, rev, ev_link);
|
1999-07-12 23:44:31 +00:00
|
|
|
} else {
|
|
|
|
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
|
|
|
|
resp->action, resp->arg, resp, NULL, NULL);
|
2000-04-29 00:45:26 +00:00
|
|
|
request_log(disp, resp, LVL(90),
|
|
|
|
"[b] Sent event %p buffer %p len %d to task %p",
|
|
|
|
rev, rev->buffer.base, rev->buffer.length,
|
|
|
|
resp->task);
|
2018-04-17 08:29:14 -07:00
|
|
|
resp->item_out = true;
|
2004-04-15 01:58:25 +00:00
|
|
|
isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
|
1999-07-12 23:44:31 +00:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
unlock:
|
2004-07-21 00:48:19 +00:00
|
|
|
UNLOCK(&qid->lock);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Restart recv() to get the next packet.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
restart:
|
2008-06-23 19:41:20 +00:00
|
|
|
(void)startrecv(disp, NULL);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
|
|
|
isc_event_free(&ev_in);
|
2014-08-06 18:49:53 +10:00
|
|
|
UNLOCK(&disp->lock);
|
1999-07-12 23:44:31 +00:00
|
|
|
}
|
|
|
|
|
2020-12-18 17:21:00 -08:00
|
|
|
static void
|
|
|
|
recv_tcpmsg(isc_task_t *task, isc_event_t *ev_in) {
|
|
|
|
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
|
|
|
|
tcpmsg_t *tcpmsg = ev_in->ev_arg;
|
|
|
|
isc_event_t *dev = &tcpmsg->event;
|
|
|
|
|
|
|
|
UNUSED(task);
|
|
|
|
|
|
|
|
tcpmsg->address = ev->address;
|
|
|
|
|
|
|
|
if (ev->result != ISC_R_SUCCESS) {
|
|
|
|
tcpmsg->result = ev->result;
|
|
|
|
goto send_and_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
tcpmsg->result = ISC_R_SUCCESS;
|
|
|
|
isc_buffer_add(&tcpmsg->buffer, ev->n);
|
|
|
|
|
|
|
|
send_and_free:
|
|
|
|
isc_task_send(tcpmsg->task, &dev);
|
|
|
|
tcpmsg->task = NULL;
|
|
|
|
isc_event_free(&ev_in);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
recv_tcplen(isc_task_t *task, isc_event_t *ev_in) {
|
|
|
|
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
|
|
|
|
tcpmsg_t *tcpmsg = ev_in->ev_arg;
|
|
|
|
isc_event_t *dev = &tcpmsg->event;
|
|
|
|
isc_region_t region;
|
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
tcpmsg->address = ev->address;
|
|
|
|
|
|
|
|
if (ev->result != ISC_R_SUCCESS) {
|
|
|
|
tcpmsg->result = ev->result;
|
|
|
|
goto send_and_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Success.
|
|
|
|
*/
|
|
|
|
tcpmsg->size = ntohs(tcpmsg->size);
|
|
|
|
if (tcpmsg->size == 0) {
|
|
|
|
tcpmsg->result = ISC_R_UNEXPECTEDEND;
|
|
|
|
goto send_and_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
region.base = isc_mem_get(tcpmsg->disp->mgr->mctx, tcpmsg->size);
|
|
|
|
region.length = tcpmsg->size;
|
|
|
|
if (region.base == NULL) {
|
|
|
|
tcpmsg->result = ISC_R_NOMEMORY;
|
|
|
|
goto send_and_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_buffer_init(&tcpmsg->buffer, region.base, region.length);
|
|
|
|
result = isc_socket_recv(tcpmsg->disp->socket, ®ion, 0, task,
|
|
|
|
recv_tcpmsg, tcpmsg);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
tcpmsg->result = result;
|
|
|
|
goto send_and_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_event_free(&ev_in);
|
|
|
|
return;
|
|
|
|
|
|
|
|
send_and_free:
|
|
|
|
isc_task_send(tcpmsg->task, &dev);
|
|
|
|
tcpmsg->task = NULL;
|
|
|
|
isc_event_free(&ev_in);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
tcp_readmessage(tcpmsg_t *tcpmsg, isc_task_t *task, isc_taskaction_t action,
|
|
|
|
void *arg) {
|
|
|
|
isc_result_t result;
|
|
|
|
isc_region_t region;
|
|
|
|
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(tcpmsg->task == NULL); /* not currently in use */
|
|
|
|
|
|
|
|
if (tcpmsg->buffer.base != NULL) {
|
|
|
|
isc_mem_put(tcpmsg->disp->mgr->mctx, tcpmsg->buffer.base,
|
|
|
|
tcpmsg->buffer.length);
|
|
|
|
tcpmsg->buffer.base = NULL;
|
|
|
|
tcpmsg->buffer.length = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tcpmsg->task = task;
|
|
|
|
tcpmsg->action = action;
|
|
|
|
tcpmsg->arg = arg;
|
|
|
|
tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */
|
|
|
|
|
|
|
|
ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0,
|
|
|
|
DNS_EVENT_TCPMSG, action, arg, tcpmsg, NULL, NULL);
|
|
|
|
|
|
|
|
region.base = (unsigned char *)&tcpmsg->size;
|
|
|
|
region.length = 2; /* uint16_t */
|
|
|
|
result = isc_socket_recv(tcpmsg->disp->socket, ®ion, 0, tcpmsg->task,
|
|
|
|
recv_tcplen, tcpmsg);
|
|
|
|
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
tcpmsg->task = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
2000-05-08 14:38:29 +00:00
|
|
|
* disp must be locked.
|
1999-06-30 01:33:11 +00:00
|
|
|
*/
|
2008-06-23 19:41:20 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
|
|
|
isc_result_t res;
|
|
|
|
isc_region_t region;
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_socket_t *sock = NULL;
|
2020-12-16 01:32:06 -08:00
|
|
|
isc_socketevent_t *sev = NULL;
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->shutting_down == 1) {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-08 02:50:00 +00:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (dispsock == NULL) {
|
|
|
|
if (disp->socktype == isc_sockettype_udp ||
|
|
|
|
disp->recv_pending != 0) {
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = disp->socket;
|
2020-12-16 01:32:06 -08:00
|
|
|
} else {
|
|
|
|
sock = dispsock->socket;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-08 22:12:37 +00:00
|
|
|
|
2001-01-13 01:33:27 +00:00
|
|
|
switch (disp->socktype) {
|
2020-02-13 21:48:23 +01:00
|
|
|
/*
|
|
|
|
* UDP reads are always maximal.
|
|
|
|
*/
|
2001-01-13 01:33:27 +00:00
|
|
|
case isc_sockettype_udp:
|
2020-12-09 15:45:13 -08:00
|
|
|
region.length = DNS_DISPATCH_UDPBUFSIZE;
|
2001-01-13 01:33:27 +00:00
|
|
|
region.base = allocate_udp_buffer(disp);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (region.base == NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-12-16 01:32:06 -08:00
|
|
|
sev = allocate_sevent(disp, sock, ISC_SOCKEVENT_RECVDONE,
|
|
|
|
udp_recv, dispsock);
|
|
|
|
res = isc_socket_recv2(sock, ®ion, 1, dispsock->task, sev,
|
|
|
|
0);
|
|
|
|
if (res != ISC_R_SUCCESS) {
|
|
|
|
free_buffer(disp, region.base, region.length);
|
|
|
|
return (res);
|
2001-01-13 01:33:27 +00:00
|
|
|
}
|
|
|
|
break;
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2001-01-13 01:33:27 +00:00
|
|
|
case isc_sockettype_tcp:
|
2020-12-18 17:21:00 -08:00
|
|
|
res = tcp_readmessage(&disp->tcpmsg, disp->task[0], tcp_recv,
|
|
|
|
disp);
|
2001-01-13 01:33:27 +00:00
|
|
|
if (res != ISC_R_SUCCESS) {
|
|
|
|
disp->shutdown_why = res;
|
|
|
|
disp->shutting_down = 1;
|
2004-07-21 00:48:19 +00:00
|
|
|
do_cancel(disp);
|
2008-06-23 19:41:20 +00:00
|
|
|
return (ISC_R_SUCCESS); /* recover by cancel */
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
2001-09-20 16:48:20 +00:00
|
|
|
INSIST(disp->recv_pending == 0);
|
2001-01-13 01:33:27 +00:00
|
|
|
disp->recv_pending = 1;
|
|
|
|
break;
|
2005-02-23 01:09:23 +00:00
|
|
|
default:
|
|
|
|
INSIST(0);
|
2018-11-07 15:00:07 +07:00
|
|
|
ISC_UNREACHABLE();
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
1999-06-30 01:33:11 +00:00
|
|
|
}
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
/*
|
|
|
|
* Mgr must be locked when calling this function.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy_mgr_ok(dns_dispatchmgr_t *mgr) {
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
mgr_log(mgr, LVL(90),
|
2021-05-12 21:16:17 +02:00
|
|
|
"destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, ",
|
|
|
|
MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!MGR_IS_SHUTTINGDOWN(mgr)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (!ISC_LIST_EMPTY(mgr->list)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2021-05-12 21:16:17 +02:00
|
|
|
if (isc_refcount_current(&mgr->irefs) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-10 21:34:50 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2000-05-10 21:34:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mgr must be unlocked when calling this function.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy_mgr(dns_dispatchmgr_t **mgrp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2000-05-10 21:34:50 +00:00
|
|
|
|
|
|
|
mgr = *mgrp;
|
|
|
|
*mgrp = NULL;
|
|
|
|
|
|
|
|
mgr->magic = 0;
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&mgr->lock);
|
2000-05-10 21:34:50 +00:00
|
|
|
mgr->state = 0;
|
|
|
|
|
2019-07-23 17:16:57 -04:00
|
|
|
if (mgr->qid != NULL) {
|
|
|
|
qid_destroy(mgr->mctx, &mgr->qid);
|
|
|
|
}
|
2000-09-19 06:59:28 +00:00
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&mgr->buffer_lock);
|
2000-06-21 21:34:43 +00:00
|
|
|
|
2019-07-23 17:16:57 -04:00
|
|
|
if (mgr->blackhole != NULL) {
|
2000-11-03 02:45:55 +00:00
|
|
|
dns_acl_detach(&mgr->blackhole);
|
2019-07-23 17:16:57 -04:00
|
|
|
}
|
2000-11-03 02:45:55 +00:00
|
|
|
|
2019-07-23 17:16:57 -04:00
|
|
|
if (mgr->stats != NULL) {
|
2009-01-27 22:30:00 +00:00
|
|
|
isc_stats_detach(&mgr->stats);
|
2019-07-23 17:16:57 -04:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
if (mgr->v4ports != NULL) {
|
2019-07-23 17:16:57 -04:00
|
|
|
isc_mem_put(mgr->mctx, mgr->v4ports,
|
2008-06-23 19:41:20 +00:00
|
|
|
mgr->nv4ports * sizeof(in_port_t));
|
|
|
|
}
|
|
|
|
if (mgr->v6ports != NULL) {
|
2019-07-23 17:16:57 -04:00
|
|
|
isc_mem_put(mgr->mctx, mgr->v6ports,
|
2008-06-23 19:41:20 +00:00
|
|
|
mgr->nv6ports * sizeof(in_port_t));
|
|
|
|
}
|
2019-07-23 17:16:57 -04:00
|
|
|
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(dns_dispatchmgr_t));
|
2000-05-10 21:34:50 +00:00
|
|
|
}
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
static isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
unsigned int options, isc_socket_t **sockp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_socket_t *sock = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
sock = *sockp;
|
2011-07-28 04:04:37 +00:00
|
|
|
if (sock != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
result = isc_socket_open(sock);
|
2018-11-08 19:34:51 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (result);
|
2018-11-08 19:34:51 -08:00
|
|
|
}
|
2011-07-28 04:04:37 +00:00
|
|
|
} else {
|
|
|
|
result = isc_socket_create(mgr, isc_sockaddr_pf(local),
|
2016-07-11 13:36:16 +10:00
|
|
|
isc_sockettype_udp, &sock);
|
2018-11-08 19:34:51 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-07-28 04:04:37 +00:00
|
|
|
return (result);
|
2018-11-08 19:34:51 -08:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2011-07-28 04:04:37 +00:00
|
|
|
isc_socket_setname(sock, "dispatcher", NULL);
|
|
|
|
|
2001-11-29 13:14:33 +00:00
|
|
|
#ifndef ISC_ALLOW_MAPPED
|
2018-04-17 08:29:14 -07:00
|
|
|
isc_socket_ipv6only(sock, true);
|
2020-02-13 21:48:23 +01:00
|
|
|
#endif /* ifndef ISC_ALLOW_MAPPED */
|
2008-07-23 23:27:54 +00:00
|
|
|
result = isc_socket_bind(sock, local, options);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2018-11-08 19:34:51 -08:00
|
|
|
if (*sockp == NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_detach(&sock);
|
2018-11-08 19:34:51 -08:00
|
|
|
} else {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_close(sock);
|
2009-09-01 00:22:28 +00:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
*sockp = sock;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
/*%
|
|
|
|
* Create a temporary port list to set the initial default set of dispatch
|
|
|
|
* ports: [1024, 65535]. This is almost meaningless as the application will
|
|
|
|
* normally set the ports explicitly, but is provided to fill some minor corner
|
|
|
|
* cases.
|
|
|
|
*/
|
2020-12-09 15:45:13 -08:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) {
|
2020-12-09 15:45:13 -08:00
|
|
|
isc_portset_create(mctx, portsetp);
|
|
|
|
isc_portset_addrange(*portsetp, 1024, 65535);
|
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
static isc_result_t
|
|
|
|
setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
|
|
|
|
isc_portset_t *v6portset) {
|
|
|
|
in_port_t *v4ports, *v6ports, p = 0;
|
|
|
|
unsigned int nv4ports, nv6ports, i4 = 0, i6 = 0;
|
|
|
|
|
|
|
|
nv4ports = isc_portset_nports(v4portset);
|
|
|
|
nv6ports = isc_portset_nports(v6portset);
|
|
|
|
|
|
|
|
v4ports = NULL;
|
|
|
|
if (nv4ports != 0) {
|
|
|
|
v4ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv4ports);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-12-09 15:45:13 -08:00
|
|
|
v6ports = NULL;
|
|
|
|
if (nv6ports != 0) {
|
|
|
|
v6ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv6ports);
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (isc_portset_isset(v4portset, p)) {
|
|
|
|
INSIST(i4 < nv4ports);
|
|
|
|
v4ports[i4++] = p;
|
|
|
|
}
|
|
|
|
if (isc_portset_isset(v6portset, p)) {
|
|
|
|
INSIST(i6 < nv6ports);
|
|
|
|
v6ports[i6++] = p;
|
|
|
|
}
|
|
|
|
} while (p++ < 65535);
|
|
|
|
INSIST(i4 == nv4ports && i6 == nv6ports);
|
|
|
|
|
|
|
|
if (mgr->v4ports != NULL) {
|
|
|
|
isc_mem_put(mgr->mctx, mgr->v4ports,
|
|
|
|
mgr->nv4ports * sizeof(in_port_t));
|
|
|
|
}
|
|
|
|
mgr->v4ports = v4ports;
|
|
|
|
mgr->nv4ports = nv4ports;
|
|
|
|
|
|
|
|
if (mgr->v6ports != NULL) {
|
|
|
|
isc_mem_put(mgr->mctx, mgr->v6ports,
|
|
|
|
mgr->nv6ports * sizeof(in_port_t));
|
|
|
|
}
|
|
|
|
mgr->v6ports = v6ports;
|
|
|
|
mgr->nv6ports = nv6ports;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
1999-06-30 01:33:11 +00:00
|
|
|
/*
|
|
|
|
* Publics.
|
|
|
|
*/
|
|
|
|
|
1999-07-22 01:34:31 +00:00
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) {
|
2020-12-09 15:45:13 -08:00
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_portset_t *v4portset = NULL;
|
|
|
|
isc_portset_t *v6portset = NULL;
|
2000-05-10 21:34:50 +00:00
|
|
|
|
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
REQUIRE(mgrp != NULL && *mgrp == NULL);
|
|
|
|
|
|
|
|
mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
*mgr = (dns_dispatchmgr_t){ 0 };
|
2000-05-10 21:34:50 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_mem_attach(mctx, &mgr->mctx);
|
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&mgr->lock);
|
|
|
|
isc_mutex_init(&mgr->buffer_lock);
|
2021-05-12 21:16:17 +02:00
|
|
|
|
|
|
|
isc_refcount_init(&mgr->irefs, 0);
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
ISC_LIST_INIT(mgr->list);
|
2021-05-12 21:16:17 +02:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
create_default_portset(mctx, &v4portset);
|
|
|
|
create_default_portset(mctx, &v6portset);
|
2000-05-10 21:34:50 +00:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
setavailports(mgr, v4portset, v6portset);
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
isc_portset_destroy(mctx, &v4portset);
|
|
|
|
isc_portset_destroy(mctx, &v6portset);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
qid_allocate(mgr, &mgr->qid);
|
2020-12-09 15:45:13 -08:00
|
|
|
mgr->magic = DNS_DISPATCHMGR_MAGIC;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2020-12-09 15:45:13 -08:00
|
|
|
*mgrp = mgr;
|
|
|
|
return (ISC_R_SUCCESS);
|
2000-05-10 21:34:50 +00:00
|
|
|
}
|
|
|
|
|
2000-11-03 02:45:55 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) {
|
2000-11-03 02:45:55 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (mgr->blackhole != NULL) {
|
2000-12-26 09:48:41 +00:00
|
|
|
dns_acl_detach(&mgr->blackhole);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-03 02:45:55 +00:00
|
|
|
dns_acl_attach(blackhole, &mgr->blackhole);
|
|
|
|
}
|
|
|
|
|
2001-02-09 00:23:16 +00:00
|
|
|
dns_acl_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
|
2000-11-03 02:45:55 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
2001-02-09 00:23:16 +00:00
|
|
|
return (mgr->blackhole);
|
2000-11-03 02:45:55 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_portset_t *v6portset) {
|
2008-06-23 19:41:20 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
2020-12-09 15:45:13 -08:00
|
|
|
return (setavailports(mgr, v4portset, v6portset));
|
2003-02-26 05:05:16 +00:00
|
|
|
}
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool killit;
|
2000-05-10 21:34:50 +00:00
|
|
|
|
|
|
|
REQUIRE(mgrp != NULL);
|
|
|
|
REQUIRE(VALID_DISPATCHMGR(*mgrp));
|
|
|
|
|
|
|
|
mgr = *mgrp;
|
|
|
|
*mgrp = NULL;
|
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
mgr->state |= MGR_SHUTTINGDOWN;
|
|
|
|
killit = destroy_mgr_ok(mgr);
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
mgr_log(mgr, LVL(90), "destroy: killit=%d", killit);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killit) {
|
2000-05-10 21:34:50 +00:00
|
|
|
destroy_mgr(&mgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-10 21:34:50 +00:00
|
|
|
}
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) {
|
2008-04-03 05:55:52 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
|
|
|
REQUIRE(ISC_LIST_EMPTY(mgr->list));
|
|
|
|
REQUIRE(mgr->stats == NULL);
|
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
isc_stats_attach(stats, &mgr->stats);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
static void
|
|
|
|
qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_qid_t *qid = NULL;
|
2000-09-18 04:50:05 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
REQUIRE(qidp != NULL && *qidp == NULL);
|
2000-09-19 06:59:28 +00:00
|
|
|
|
|
|
|
qid = isc_mem_get(mgr->mctx, sizeof(*qid));
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
*qid = (dns_qid_t){ .qid_nbuckets = DNS_QID_BUCKETS,
|
|
|
|
.qid_increment = DNS_QID_INCREMENT };
|
2000-09-18 04:50:05 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
qid->qid_table = isc_mem_get(mgr->mctx,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
DNS_QID_BUCKETS * sizeof(dns_displist_t));
|
|
|
|
qid->sock_table = isc_mem_get(
|
|
|
|
mgr->mctx, DNS_QID_BUCKETS * sizeof(dispsocketlist_t));
|
2007-06-26 02:52:15 +00:00
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&qid->lock);
|
2000-09-18 04:50:05 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
for (i = 0; i < qid->qid_nbuckets; i++) {
|
2000-09-18 04:50:05 +00:00
|
|
|
ISC_LIST_INIT(qid->qid_table[i]);
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
ISC_LIST_INIT(qid->sock_table[i]);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
2000-09-18 04:50:05 +00:00
|
|
|
|
|
|
|
qid->magic = QID_MAGIC;
|
|
|
|
*qidp = qid;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_qid_t *qid = NULL;
|
2000-09-18 04:50:05 +00:00
|
|
|
|
|
|
|
REQUIRE(qidp != NULL);
|
|
|
|
qid = *qidp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*qidp = NULL;
|
2000-09-18 04:50:05 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_QID(qid));
|
|
|
|
|
|
|
|
qid->magic = 0;
|
2000-09-19 06:59:28 +00:00
|
|
|
isc_mem_put(mctx, qid->qid_table,
|
2000-09-18 04:50:05 +00:00
|
|
|
qid->qid_nbuckets * sizeof(dns_displist_t));
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
isc_mem_put(mctx, qid->sock_table,
|
|
|
|
qid->qid_nbuckets * sizeof(dispsocketlist_t));
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&qid->lock);
|
2000-09-19 06:59:28 +00:00
|
|
|
isc_mem_put(mctx, qid, sizeof(*qid));
|
2000-09-18 04:50:05 +00:00
|
|
|
}
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
/*
|
|
|
|
* Allocate and set important limits.
|
|
|
|
*/
|
2020-12-18 14:59:50 -08:00
|
|
|
static void
|
|
|
|
dispatch_allocate(dns_dispatchmgr_t *mgr, isc_sockettype_t type, int pf,
|
|
|
|
unsigned int attributes, dns_dispatch_t **dispp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
1999-06-18 23:54:59 +00:00
|
|
|
REQUIRE(dispp != NULL && *dispp == NULL);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
/*
|
|
|
|
* Set up the dispatcher, mostly. Don't bother setting some of
|
|
|
|
* the options that are controlled by tcp vs. udp, etc.
|
|
|
|
*/
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
disp = isc_mem_get(mgr->mctx, sizeof(*disp));
|
|
|
|
isc_refcount_increment0(&mgr->irefs);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
*disp = (dns_dispatch_t){ .mgr = mgr,
|
2020-12-18 14:59:50 -08:00
|
|
|
.socktype = type,
|
2020-12-09 19:44:41 -08:00
|
|
|
.shutdown_why = ISC_R_UNEXPECTED };
|
|
|
|
isc_refcount_init(&disp->refcount, 1);
|
2000-05-10 21:34:50 +00:00
|
|
|
ISC_LINK_INIT(disp, link);
|
2008-06-23 19:41:20 +00:00
|
|
|
ISC_LIST_INIT(disp->activesockets);
|
|
|
|
ISC_LIST_INIT(disp->inactivesockets);
|
1999-06-18 23:54:59 +00:00
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
switch (type) {
|
|
|
|
case isc_sockettype_tcp:
|
|
|
|
disp->attributes |= DNS_DISPATCHATTR_TCP;
|
|
|
|
break;
|
|
|
|
case isc_sockettype_udp:
|
|
|
|
disp->attributes |= DNS_DISPATCHATTR_UDP;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
INSIST(0);
|
|
|
|
ISC_UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (pf) {
|
|
|
|
case PF_INET:
|
|
|
|
disp->attributes |= DNS_DISPATCHATTR_IPV4;
|
|
|
|
break;
|
|
|
|
case PF_INET6:
|
|
|
|
disp->attributes |= DNS_DISPATCHATTR_IPV6;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
INSIST(0);
|
|
|
|
ISC_UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set whatever attributes were passed in that haven't been
|
|
|
|
* reset automatically by the code above.
|
|
|
|
*/
|
|
|
|
attributes &= ~(DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP |
|
|
|
|
DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6);
|
|
|
|
disp->attributes |= attributes;
|
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&disp->lock);
|
2012-04-28 14:52:28 -07:00
|
|
|
disp->failsafe_ev = allocate_devent(disp);
|
1999-06-18 23:54:59 +00:00
|
|
|
disp->magic = DISPATCH_MAGIC;
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
*dispp = disp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-01-17 14:18:27 +00:00
|
|
|
* MUST be unlocked, and not used by anything.
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dispatch_free(dns_dispatch_t **dispp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_DISPATCH(*dispp));
|
|
|
|
disp = *dispp;
|
|
|
|
*dispp = NULL;
|
|
|
|
|
|
|
|
mgr = disp->mgr;
|
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
|
|
|
|
|
|
|
if (disp->tcpmsg_valid) {
|
2020-12-18 17:21:00 -08:00
|
|
|
if (disp->tcpmsg.buffer.base != NULL) {
|
|
|
|
isc_mem_put(disp->mgr->mctx, disp->tcpmsg.buffer.base,
|
|
|
|
disp->tcpmsg.buffer.length);
|
|
|
|
disp->tcpmsg.buffer.base = NULL;
|
|
|
|
disp->tcpmsg.buffer.length = 0;
|
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->tcpmsg_valid = 0;
|
|
|
|
}
|
|
|
|
|
2000-09-19 06:59:28 +00:00
|
|
|
INSIST(disp->tcpbuffers == 0);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
INSIST(disp->requests == 0);
|
2001-01-13 01:33:27 +00:00
|
|
|
INSIST(disp->recv_pending == 0);
|
2008-06-23 19:41:20 +00:00
|
|
|
INSIST(ISC_LIST_EMPTY(disp->activesockets));
|
|
|
|
INSIST(ISC_LIST_EMPTY(disp->inactivesockets));
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_decrement(&mgr->irefs);
|
|
|
|
isc_mem_put(mgr->mctx, disp->failsafe_ev, sizeof(*disp->failsafe_ev));
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->failsafe_ev = NULL;
|
|
|
|
|
|
|
|
disp->mgr = NULL;
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&disp->lock);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->magic = 0;
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_decrement(&mgr->irefs);
|
|
|
|
isc_mem_put(mgr->mctx, disp, sizeof(*disp));
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2020-12-18 14:59:50 -08:00
|
|
|
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
2018-04-03 14:35:07 +02:00
|
|
|
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
const isc_sockaddr_t *destaddr, unsigned int attributes,
|
2020-12-18 14:59:50 -08:00
|
|
|
isc_dscp_t dscp, dns_dispatch_t **dispp) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
2020-12-18 14:59:50 -08:00
|
|
|
isc_sockaddr_t src;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
int pf;
|
2000-09-19 06:59:28 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
2020-12-18 14:59:50 -08:00
|
|
|
REQUIRE(sockmgr != NULL);
|
|
|
|
REQUIRE(destaddr != NULL);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
pf = isc_sockaddr_pf(destaddr);
|
|
|
|
dispatch_allocate(mgr, isc_sockettype_tcp, pf, attributes, &disp);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
disp->peer = *destaddr;
|
|
|
|
|
|
|
|
if (localaddr != NULL) {
|
|
|
|
disp->local = *localaddr;
|
|
|
|
} else {
|
|
|
|
switch (pf) {
|
|
|
|
case AF_INET:
|
|
|
|
isc_sockaddr_any(&disp->local);
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
isc_sockaddr_any6(&disp->local);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
disp->ntasks = 1;
|
|
|
|
disp->task[0] = NULL;
|
2018-10-30 15:07:25 +00:00
|
|
|
result = isc_task_create(taskmgr, 50, &disp->task[0]);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-06-18 23:54:59 +00:00
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
result = isc_socket_create(sockmgr, isc_sockaddr_pf(destaddr),
|
|
|
|
isc_sockettype_tcp, &disp->socket);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto cleanup;
|
2020-12-16 01:32:06 -08:00
|
|
|
}
|
|
|
|
|
2014-09-04 10:37:45 +10:00
|
|
|
if (localaddr == NULL) {
|
2020-12-18 14:59:50 -08:00
|
|
|
isc_sockaddr_anyofpf(&src, pf);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2020-12-18 14:59:50 -08:00
|
|
|
src = *localaddr;
|
|
|
|
isc_sockaddr_setport(&src, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-09-04 10:37:45 +10:00
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
result = isc_socket_bind(disp->socket, &src, 0);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2020-12-18 14:59:50 -08:00
|
|
|
isc_socket_dscp(disp->socket, dscp);
|
|
|
|
|
|
|
|
disp->ctlevent =
|
|
|
|
isc_event_allocate(mgr->mctx, disp, DNS_EVENT_DISPATCHCONTROL,
|
|
|
|
destroy_disp, disp, sizeof(isc_event_t));
|
|
|
|
|
|
|
|
isc_task_setname(disp->task[0], "tcpdispatch", disp);
|
|
|
|
|
2020-12-18 17:21:00 -08:00
|
|
|
disp->tcpmsg = (tcpmsg_t){ .disp = disp, .result = ISC_R_UNEXPECTED };
|
2020-12-18 14:59:50 -08:00
|
|
|
disp->tcpmsg_valid = 1;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
/*
|
|
|
|
* Append it to the dispatcher list.
|
|
|
|
*/
|
|
|
|
ISC_LIST_APPEND(mgr->list, disp, link);
|
|
|
|
UNLOCK(&mgr->lock);
|
1999-07-12 23:44:31 +00:00
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
if (isc_log_wouldlog(dns_lctx, 90)) {
|
|
|
|
mgr_log(mgr, LVL(90),
|
|
|
|
"dns_dispatch_createtcp: created TCP dispatch %p",
|
|
|
|
disp);
|
|
|
|
dispatch_log(disp, LVL(90), "created task %p", disp->task[0]);
|
|
|
|
}
|
1999-06-18 23:54:59 +00:00
|
|
|
*dispp = disp;
|
1999-06-30 01:33:11 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-06-18 23:54:59 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
cleanup:
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_socket_detach(&disp->socket);
|
|
|
|
dispatch_free(&disp);
|
1999-06-18 23:54:59 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
|
|
|
|
|
2014-09-04 10:37:45 +10:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
|
2018-04-17 08:29:14 -07:00
|
|
|
const isc_sockaddr_t *localaddr, bool *connected,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_t **dispp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
isc_sockaddr_t peeraddr;
|
|
|
|
isc_sockaddr_t sockname;
|
|
|
|
unsigned int attributes, mask;
|
|
|
|
bool match = false;
|
2015-01-20 17:22:31 -08:00
|
|
|
|
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
|
|
|
REQUIRE(destaddr != NULL);
|
|
|
|
REQUIRE(dispp != NULL && *dispp == NULL);
|
|
|
|
|
2018-04-03 14:35:07 +02:00
|
|
|
/* First pass */
|
2015-01-20 17:22:31 -08:00
|
|
|
attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED;
|
|
|
|
mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE |
|
2020-12-16 01:32:06 -08:00
|
|
|
DNS_DISPATCHATTR_CONNECTED;
|
2015-01-20 17:22:31 -08:00
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
disp = ISC_LIST_HEAD(mgr->list);
|
|
|
|
while (disp != NULL && !match) {
|
|
|
|
LOCK(&disp->lock);
|
|
|
|
if ((disp->shutting_down == 0) &&
|
|
|
|
ATTRMATCH(disp->attributes, attributes, mask) &&
|
|
|
|
(localaddr == NULL ||
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_sockaddr_eqaddr(localaddr, &disp->local)))
|
|
|
|
{
|
|
|
|
result = isc_socket_getsockname(disp->socket,
|
|
|
|
&sockname);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2015-01-20 17:22:31 -08:00
|
|
|
result = isc_socket_getpeername(disp->socket,
|
|
|
|
&peeraddr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-01-20 17:22:31 -08:00
|
|
|
if (result == ISC_R_SUCCESS &&
|
|
|
|
isc_sockaddr_equal(destaddr, &peeraddr) &&
|
|
|
|
(localaddr == NULL ||
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_sockaddr_eqaddr(localaddr, &sockname)))
|
|
|
|
{
|
2015-01-20 17:22:31 -08:00
|
|
|
/* attach */
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_increment(&disp->refcount);
|
2015-01-20 17:22:31 -08:00
|
|
|
*dispp = disp;
|
2018-04-17 08:29:14 -07:00
|
|
|
match = true;
|
2018-04-03 14:35:07 +02:00
|
|
|
if (connected != NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
*connected = true;
|
2018-04-03 14:35:07 +02:00
|
|
|
}
|
2015-01-20 17:22:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
disp = ISC_LIST_NEXT(disp, link);
|
|
|
|
}
|
2018-04-03 14:35:07 +02:00
|
|
|
if (match || connected == NULL) {
|
2015-01-20 17:22:31 -08:00
|
|
|
UNLOCK(&mgr->lock);
|
2018-04-03 14:35:07 +02:00
|
|
|
return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
|
2015-01-20 17:22:31 -08:00
|
|
|
}
|
|
|
|
|
2018-04-03 14:35:07 +02:00
|
|
|
/* Second pass, only if connected != NULL */
|
2015-01-20 17:22:31 -08:00
|
|
|
attributes = DNS_DISPATCHATTR_TCP;
|
|
|
|
|
|
|
|
disp = ISC_LIST_HEAD(mgr->list);
|
|
|
|
while (disp != NULL && !match) {
|
|
|
|
LOCK(&disp->lock);
|
|
|
|
if ((disp->shutting_down == 0) &&
|
|
|
|
ATTRMATCH(disp->attributes, attributes, mask) &&
|
|
|
|
(localaddr == NULL ||
|
|
|
|
isc_sockaddr_eqaddr(localaddr, &disp->local)) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_sockaddr_equal(destaddr, &disp->peer))
|
|
|
|
{
|
2015-01-20 17:22:31 -08:00
|
|
|
/* attach */
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_increment(&disp->refcount);
|
2015-01-20 17:22:31 -08:00
|
|
|
*dispp = disp;
|
2018-04-17 08:29:14 -07:00
|
|
|
match = true;
|
2015-01-20 17:22:31 -08:00
|
|
|
}
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
disp = ISC_LIST_NEXT(disp, link);
|
|
|
|
}
|
|
|
|
UNLOCK(&mgr->lock);
|
2020-12-18 14:59:50 -08:00
|
|
|
|
2015-01-20 17:22:31 -08:00
|
|
|
return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
|
|
|
|
}
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
isc_result_t
|
2020-12-16 01:32:06 -08:00
|
|
|
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|
|
|
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
|
|
|
|
unsigned int attributes, dns_dispatch_t **dispp) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2007-02-02 02:18:06 +00:00
|
|
|
dns_dispatch_t *disp = NULL;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
|
|
|
REQUIRE(sockmgr != NULL);
|
|
|
|
REQUIRE(localaddr != NULL);
|
|
|
|
REQUIRE(taskmgr != NULL);
|
|
|
|
REQUIRE(dispp != NULL && *dispp == NULL);
|
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
2021-05-12 23:27:15 +02:00
|
|
|
result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
attributes, &disp);
|
2020-12-16 01:32:06 -08:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
*dispp = disp;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
}
|
|
|
|
UNLOCK(&mgr->lock);
|
2020-12-18 14:59:50 -08:00
|
|
|
|
|
|
|
return (result);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
unsigned int attributes, dns_dispatch_t **dispp) {
|
2020-12-18 14:59:50 -08:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_socket_t *sock = NULL;
|
2020-12-16 01:32:06 -08:00
|
|
|
isc_sockaddr_t sa_any;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
int pf, i = 0;
|
2018-11-08 19:34:51 -08:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
pf = isc_sockaddr_pf(localaddr);
|
2020-12-18 14:59:50 -08:00
|
|
|
dispatch_allocate(mgr, isc_sockettype_udp, pf, attributes, &disp);
|
2015-02-10 13:54:03 -08:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
/*
|
|
|
|
* For dispatches with a specified source address, we open a
|
|
|
|
* socket to make sure that address is available on the system,
|
|
|
|
* but we don't keep it open; sockets used for sending requests
|
|
|
|
* will be created later on demand.
|
|
|
|
*/
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
isc_sockaddr_anyofpf(&sa_any, pf);
|
2020-12-16 01:32:06 -08:00
|
|
|
if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) {
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
result = open_socket(sockmgr, localaddr, 0, &sock);
|
2020-12-16 01:32:06 -08:00
|
|
|
if (sock != NULL) {
|
|
|
|
isc_socket_detach(&sock);
|
|
|
|
}
|
2018-11-08 19:34:51 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2006-07-19 00:42:13 +00:00
|
|
|
goto deallocate_dispatch;
|
2018-11-08 19:34:51 -08:00
|
|
|
}
|
2020-12-16 01:32:06 -08:00
|
|
|
}
|
2011-07-28 04:04:37 +00:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (isc_log_wouldlog(dns_lctx, 90)) {
|
|
|
|
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
2008-11-12 23:10:57 +00:00
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
isc_sockaddr_format(localaddr, addrbuf,
|
|
|
|
ISC_SOCKADDR_FORMATSIZE);
|
|
|
|
mgr_log(mgr, LVL(90),
|
|
|
|
"dispatch_createudp: created UDP dispatch for %s",
|
|
|
|
addrbuf);
|
2003-02-26 05:05:16 +00:00
|
|
|
}
|
2020-12-16 01:32:06 -08:00
|
|
|
|
2001-01-07 22:02:48 +00:00
|
|
|
disp->socket = sock;
|
|
|
|
disp->local = *localaddr;
|
2020-12-16 01:32:06 -08:00
|
|
|
disp->ntasks = MAX_INTERNAL_TASKS;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
for (i = 0; i < disp->ntasks; i++) {
|
|
|
|
disp->task[i] = NULL;
|
2018-11-21 09:50:50 +00:00
|
|
|
result = isc_task_create(taskmgr, 0, &disp->task[i]);
|
2008-06-23 19:41:20 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2009-09-01 00:22:28 +00:00
|
|
|
while (--i >= 0) {
|
|
|
|
isc_task_shutdown(disp->task[i]);
|
|
|
|
isc_task_detach(&disp->task[i]);
|
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
goto kill_socket;
|
|
|
|
}
|
|
|
|
isc_task_setname(disp->task[i], "udpdispatch", disp);
|
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
disp->ctlevent =
|
|
|
|
isc_event_allocate(mgr->mctx, disp, DNS_EVENT_DISPATCHCONTROL,
|
|
|
|
destroy_disp, disp, sizeof(isc_event_t));
|
2001-01-27 02:08:07 +00:00
|
|
|
|
2012-04-28 14:52:28 -07:00
|
|
|
disp->sepool = NULL;
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_create(&disp->sepool);
|
|
|
|
isc_mem_setname(disp->sepool, "disp_sepool");
|
2012-04-28 14:52:28 -07:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
/*
|
|
|
|
* Append it to the dispatcher list.
|
|
|
|
*/
|
|
|
|
ISC_LIST_APPEND(mgr->list, disp, link);
|
|
|
|
|
|
|
|
mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
|
2008-06-23 19:41:20 +00:00
|
|
|
dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */
|
2018-11-08 19:34:51 -08:00
|
|
|
if (disp->socket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
dispatch_log(disp, LVL(90), "created socket %p", disp->socket);
|
2018-11-08 19:34:51 -08:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
*dispp = disp;
|
2011-07-28 04:04:37 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
return (result);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Error returns.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
kill_socket:
|
2018-11-08 19:34:51 -08:00
|
|
|
if (disp->socket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_detach(&disp->socket);
|
2018-11-08 19:34:51 -08:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
deallocate_dispatch:
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dispatch_free(&disp);
|
2008-06-23 19:41:20 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
return (result);
|
1999-06-16 01:32:31 +00:00
|
|
|
}
|
|
|
|
|
1999-06-18 23:54:59 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) {
|
1999-07-13 00:25:21 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
REQUIRE(dispp != NULL && *dispp == NULL);
|
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_increment(&disp->refcount);
|
1999-07-13 00:25:21 +00:00
|
|
|
*dispp = disp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_detach(dns_dispatch_t **dispp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
|
|
|
dispsocket_t *dispsock = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool killit;
|
1999-06-18 23:54:59 +00:00
|
|
|
|
|
|
|
REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
|
|
|
|
|
|
|
|
disp = *dispp;
|
|
|
|
*dispp = NULL;
|
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
2020-12-09 19:44:41 -08:00
|
|
|
if (isc_refcount_decrement(&disp->refcount) == 1) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->recv_pending > 0) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_cancel(disp->socket, disp->task[0],
|
|
|
|
ISC_SOCKCANCEL_RECV);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
for (dispsock = ISC_LIST_HEAD(disp->activesockets);
|
2020-02-13 14:44:37 -08:00
|
|
|
dispsock != NULL; dispsock = ISC_LIST_NEXT(dispsock, link))
|
|
|
|
{
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_cancel(dispsock->socket, dispsock->task,
|
1999-07-09 00:51:08 +00:00
|
|
|
ISC_SOCKCANCEL_RECV);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->shutting_down = 1;
|
1999-07-09 00:51:08 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
dispatch_log(disp, LVL(90), "detach: refcount %" PRIuFAST32,
|
|
|
|
isc_refcount_current(&disp->refcount));
|
1999-06-18 23:54:59 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
killit = destroy_disp_ok(disp);
|
1999-06-18 23:54:59 +00:00
|
|
|
UNLOCK(&disp->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killit) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_send(disp->task[0], &disp->ctlevent);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-06-16 01:32:31 +00:00
|
|
|
}
|
|
|
|
|
1999-07-22 01:34:31 +00:00
|
|
|
isc_result_t
|
2018-04-03 14:35:07 +02:00
|
|
|
dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
|
|
|
|
const isc_sockaddr_t *dest, isc_task_t *task,
|
|
|
|
isc_taskaction_t action, void *arg,
|
|
|
|
dns_messageid_t *idp, dns_dispentry_t **resp,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_socketmgr_t *sockmgr) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *res = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int bucket;
|
|
|
|
in_port_t localport = 0;
|
|
|
|
dns_messageid_t id;
|
2020-12-09 19:44:41 -08:00
|
|
|
int i = 0;
|
|
|
|
bool ok = false;
|
|
|
|
dns_qid_t *qid = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
dispsocket_t *dispsocket = NULL;
|
|
|
|
isc_result_t result;
|
1999-06-18 02:01:42 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(dest != NULL);
|
|
|
|
REQUIRE(resp != NULL && *resp == NULL);
|
|
|
|
REQUIRE(idp != NULL);
|
2020-12-16 01:32:06 -08:00
|
|
|
REQUIRE(disp->socktype == isc_sockettype_tcp || sockmgr != NULL);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
|
|
|
|
1999-07-14 22:16:19 +00:00
|
|
|
if (disp->shutting_down == 1) {
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
|
|
|
}
|
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
if (disp->requests >= DNS_DISPATCH_MAXREQUESTS) {
|
1999-07-09 02:47:55 +00:00
|
|
|
UNLOCK(&disp->lock);
|
1999-07-10 00:15:41 +00:00
|
|
|
return (ISC_R_QUOTA);
|
1999-07-09 02:47:55 +00:00
|
|
|
}
|
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
qid = disp->mgr->qid;
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (disp->socktype == isc_sockettype_udp &&
|
2020-02-13 14:44:37 -08:00
|
|
|
disp->nsockets > DNS_DISPATCH_SOCKSQUOTA)
|
|
|
|
{
|
2020-12-09 19:44:41 -08:00
|
|
|
dispsocket_t *oldestsocket = NULL;
|
|
|
|
dns_dispentry_t *oldestresp = NULL;
|
|
|
|
dns_dispatchevent_t *rev = NULL;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Kill oldest outstanding query if the number of sockets
|
|
|
|
* exceeds the quota to keep the room for new queries.
|
|
|
|
*/
|
|
|
|
oldestsocket = ISC_LIST_HEAD(disp->activesockets);
|
|
|
|
oldestresp = oldestsocket->resp;
|
|
|
|
if (oldestresp != NULL && !oldestresp->item_out) {
|
2012-04-28 14:52:28 -07:00
|
|
|
rev = allocate_devent(oldestresp->disp);
|
2020-12-09 19:44:41 -08:00
|
|
|
rev->buffer.base = NULL;
|
|
|
|
rev->result = ISC_R_CANCELED;
|
|
|
|
rev->id = oldestresp->id;
|
|
|
|
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,
|
|
|
|
DNS_EVENT_DISPATCH, oldestresp->action,
|
|
|
|
oldestresp->arg, oldestresp, NULL, NULL);
|
|
|
|
oldestresp->item_out = true;
|
|
|
|
isc_task_send(oldestresp->task, ISC_EVENT_PTR(&rev));
|
|
|
|
inc_stats(disp->mgr, dns_resstatscounter_dispabort);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Move this entry to the tail so that it won't (easily) be
|
|
|
|
* examined before actually being canceled.
|
|
|
|
*/
|
|
|
|
ISC_LIST_UNLINK(disp->activesockets, oldestsocket, link);
|
|
|
|
ISC_LIST_APPEND(disp->activesockets, oldestsocket, link);
|
|
|
|
}
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (disp->socktype == isc_sockettype_udp) {
|
2008-06-23 19:41:20 +00:00
|
|
|
/*
|
|
|
|
* Get a separate UDP socket with a random port number.
|
|
|
|
*/
|
2012-04-28 14:52:28 -07:00
|
|
|
result = get_dispsocket(disp, dest, sockmgr, &dispsocket,
|
2008-08-15 17:29:52 +00:00
|
|
|
&localport);
|
2008-06-23 19:41:20 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
UNLOCK(&disp->lock);
|
2009-01-31 00:10:24 +00:00
|
|
|
inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
|
2008-06-23 19:41:20 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
/*
|
2020-12-09 19:44:41 -08:00
|
|
|
* Try somewhat hard to find a unique ID. Start with
|
|
|
|
* a random number unless DNS_DISPATCHOPT_FIXEDID is set,
|
|
|
|
* in which case we start with the ID passed in via *idp.
|
1999-06-18 02:01:42 +00:00
|
|
|
*/
|
2018-04-22 14:56:28 +02:00
|
|
|
if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) {
|
2014-10-01 07:24:16 +10:00
|
|
|
id = *idp;
|
2018-04-22 14:56:28 +02:00
|
|
|
} else {
|
2018-05-28 15:22:23 +02:00
|
|
|
id = (dns_messageid_t)isc_random16();
|
2018-04-22 14:56:28 +02:00
|
|
|
}
|
2020-12-09 19:44:41 -08:00
|
|
|
|
|
|
|
LOCK(&qid->lock);
|
2014-01-09 15:57:59 +11:00
|
|
|
do {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispentry_t *entry = NULL;
|
2013-12-23 09:50:18 -08:00
|
|
|
bucket = dns_hash(qid, dest, id, localport);
|
2020-12-09 19:44:41 -08:00
|
|
|
entry = entry_search(qid, dest, id, localport, bucket);
|
|
|
|
if (entry == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
ok = true;
|
1999-06-18 02:01:42 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-09-18 04:50:05 +00:00
|
|
|
id += qid->qid_increment;
|
1999-12-15 17:14:52 +00:00
|
|
|
id &= 0x0000ffff;
|
2014-01-09 15:57:59 +11:00
|
|
|
} while (i++ < 64);
|
2012-04-28 14:52:28 -07:00
|
|
|
UNLOCK(&qid->lock);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
UNLOCK(&disp->lock);
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMORE);
|
1999-06-18 02:01:42 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
res = isc_mem_get(disp->mgr->mctx, sizeof(*res));
|
|
|
|
isc_refcount_increment0(&disp->mgr->irefs);
|
2020-12-09 19:44:41 -08:00
|
|
|
*res = (dns_dispentry_t){ .disp = disp,
|
|
|
|
.id = id,
|
|
|
|
.port = localport,
|
|
|
|
.bucket = bucket,
|
|
|
|
.host = *dest,
|
|
|
|
.action = action,
|
|
|
|
.arg = arg,
|
|
|
|
.dispsocket = dispsocket };
|
|
|
|
isc_task_attach(task, &res->task);
|
|
|
|
ISC_LIST_INIT(res->items);
|
|
|
|
ISC_LINK_INIT(res, link);
|
|
|
|
res->magic = RESPONSE_MAGIC;
|
1999-06-18 02:01:42 +00:00
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_increment(&disp->refcount);
|
1999-07-09 00:51:08 +00:00
|
|
|
disp->requests++;
|
2020-12-09 19:44:41 -08:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispsocket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
dispsocket->resp = res;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-28 14:52:28 -07:00
|
|
|
|
|
|
|
LOCK(&qid->lock);
|
2000-09-18 04:50:05 +00:00
|
|
|
ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
|
|
|
|
UNLOCK(&qid->lock);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
inc_stats(disp->mgr, (disp->socktype == isc_sockettype_udp)
|
2020-02-12 13:59:18 +01:00
|
|
|
? dns_resstatscounter_disprequdp
|
|
|
|
: dns_resstatscounter_dispreqtcp);
|
2012-05-14 10:06:05 -07:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
request_log(disp, res, LVL(90), "attached to task %p", res->task);
|
1999-07-09 20:32:12 +00:00
|
|
|
|
2000-06-20 23:52:54 +00:00
|
|
|
if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0))
|
|
|
|
{
|
2008-06-23 19:41:20 +00:00
|
|
|
result = startrecv(disp, dispsocket);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
LOCK(&qid->lock);
|
|
|
|
ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
|
|
|
|
UNLOCK(&qid->lock);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispsocket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
destroy_dispsocket(disp, &dispsocket);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-12-09 19:44:41 -08:00
|
|
|
isc_refcount_decrement(&disp->refcount);
|
2008-06-23 19:41:20 +00:00
|
|
|
disp->requests--;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
dec_stats(disp->mgr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
(disp->socktype == isc_sockettype_udp)
|
2020-02-12 13:59:18 +01:00
|
|
|
? dns_resstatscounter_disprequdp
|
|
|
|
: dns_resstatscounter_dispreqtcp);
|
2012-05-14 10:06:05 -07:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
isc_task_detach(&res->task);
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_decrement(&disp->mgr->irefs);
|
|
|
|
isc_mem_put(disp->mgr->mctx, res, sizeof(*res));
|
2008-06-23 19:41:20 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispsocket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
ISC_LIST_APPEND(disp->activesockets, dispsocket, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-09 00:51:08 +00:00
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
INSIST(disp->socktype == isc_sockettype_tcp || res->dispsocket != NULL);
|
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
*idp = id;
|
|
|
|
*resp = res;
|
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-06-16 01:32:31 +00:00
|
|
|
}
|
|
|
|
|
2000-06-20 23:52:54 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_starttcp(dns_dispatch_t *disp) {
|
2000-06-20 23:52:54 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]);
|
2000-06-20 23:52:54 +00:00
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
2015-01-20 17:22:31 -08:00
|
|
|
if ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) == 0) {
|
|
|
|
disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
|
|
|
|
(void)startrecv(disp, NULL);
|
|
|
|
}
|
2000-06-20 23:52:54 +00:00
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
}
|
|
|
|
|
2016-07-11 13:36:16 +10:00
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
|
|
|
dns_dispatchevent_t *ev = NULL;
|
2016-07-11 13:36:16 +10:00
|
|
|
|
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
REQUIRE(sockevent != NULL && *sockevent != NULL);
|
|
|
|
|
|
|
|
disp = resp->disp;
|
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
|
|
|
|
ev = *sockevent;
|
|
|
|
*sockevent = NULL;
|
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
2019-03-19 14:14:21 +11:00
|
|
|
|
2020-03-30 13:47:58 -07:00
|
|
|
REQUIRE(resp->item_out);
|
2019-03-19 14:14:21 +11:00
|
|
|
resp->item_out = false;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ev->buffer.base != NULL) {
|
2016-07-11 13:36:16 +10:00
|
|
|
free_buffer(disp, ev->buffer.base, ev->buffer.length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-07-11 13:36:16 +10:00
|
|
|
free_devent(disp, ev);
|
|
|
|
|
|
|
|
if (disp->shutting_down == 1) {
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
|
|
|
}
|
|
|
|
ev = ISC_LIST_HEAD(resp->items);
|
|
|
|
if (ev != NULL) {
|
|
|
|
ISC_LIST_UNLINK(resp->items, ev, ev_link);
|
|
|
|
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
|
|
|
|
resp->action, resp->arg, resp, NULL, NULL);
|
|
|
|
request_log(disp, resp, LVL(90),
|
2020-02-12 13:59:18 +01:00
|
|
|
"[c] Sent event %p buffer %p len %d to task %p", ev,
|
|
|
|
ev->buffer.base, ev->buffer.length, resp->task);
|
2018-04-17 08:29:14 -07:00
|
|
|
resp->item_out = true;
|
2016-07-11 13:36:16 +10:00
|
|
|
isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
|
|
|
|
}
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_removeresponse(dns_dispentry_t **resp,
|
|
|
|
dns_dispatchevent_t **sockevent) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
|
|
|
dns_dispatch_t *disp = NULL;
|
|
|
|
dns_dispentry_t *res = NULL;
|
|
|
|
dispsocket_t *dispsock = NULL;
|
|
|
|
dns_dispatchevent_t *ev = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int bucket;
|
|
|
|
bool killit;
|
|
|
|
unsigned int n;
|
|
|
|
isc_eventlist_t events;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_qid_t *qid = NULL;
|
1999-06-18 02:01:42 +00:00
|
|
|
|
|
|
|
REQUIRE(resp != NULL);
|
|
|
|
REQUIRE(VALID_RESPONSE(*resp));
|
|
|
|
|
|
|
|
res = *resp;
|
|
|
|
*resp = NULL;
|
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp = res->disp;
|
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
mgr = disp->mgr;
|
|
|
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
qid = mgr->qid;
|
2000-09-18 04:50:05 +00:00
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
if (sockevent != NULL) {
|
|
|
|
REQUIRE(*sockevent != NULL);
|
|
|
|
ev = *sockevent;
|
|
|
|
*sockevent = NULL;
|
|
|
|
} else {
|
|
|
|
ev = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOCK(&disp->lock);
|
|
|
|
|
1999-07-09 00:51:08 +00:00
|
|
|
INSIST(disp->requests > 0);
|
|
|
|
disp->requests--;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dec_stats(disp->mgr, (disp->socktype == isc_sockettype_udp)
|
2020-02-12 13:59:18 +01:00
|
|
|
? dns_resstatscounter_disprequdp
|
|
|
|
: dns_resstatscounter_dispreqtcp);
|
2020-12-09 19:44:41 -08:00
|
|
|
|
|
|
|
if (isc_refcount_decrement(&disp->refcount) == 1) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->recv_pending > 0) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_cancel(disp->socket, disp->task[0],
|
|
|
|
ISC_SOCKCANCEL_RECV);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
for (dispsock = ISC_LIST_HEAD(disp->activesockets);
|
2020-02-13 14:44:37 -08:00
|
|
|
dispsock != NULL; dispsock = ISC_LIST_NEXT(dispsock, link))
|
|
|
|
{
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_socket_cancel(dispsock->socket, dispsock->task,
|
1999-07-09 00:51:08 +00:00
|
|
|
ISC_SOCKCANCEL_RECV);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
disp->shutting_down = 1;
|
1999-07-09 00:51:08 +00:00
|
|
|
}
|
1999-06-18 23:54:59 +00:00
|
|
|
|
1999-06-18 02:01:42 +00:00
|
|
|
bucket = res->bucket;
|
|
|
|
|
2000-09-18 04:50:05 +00:00
|
|
|
LOCK(&qid->lock);
|
|
|
|
ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
|
|
|
|
UNLOCK(&qid->lock);
|
1999-06-18 02:01:42 +00:00
|
|
|
|
1999-10-07 19:38:39 +00:00
|
|
|
if (ev == NULL && res->item_out) {
|
|
|
|
/*
|
|
|
|
* We've posted our event, but the caller hasn't gotten it
|
|
|
|
* yet. Take it back.
|
|
|
|
*/
|
|
|
|
ISC_LIST_INIT(events);
|
2020-02-12 13:59:18 +01:00
|
|
|
n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH, NULL,
|
|
|
|
&events);
|
1999-10-07 19:38:39 +00:00
|
|
|
/*
|
|
|
|
* We had better have gotten it back.
|
|
|
|
*/
|
|
|
|
INSIST(n == 1);
|
|
|
|
ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events);
|
|
|
|
}
|
1999-07-09 00:51:08 +00:00
|
|
|
|
1999-07-08 02:50:00 +00:00
|
|
|
if (ev != NULL) {
|
2020-03-30 13:47:58 -07:00
|
|
|
REQUIRE(res->item_out);
|
2018-04-17 08:29:14 -07:00
|
|
|
res->item_out = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ev->buffer.base != NULL) {
|
1999-07-22 01:34:31 +00:00
|
|
|
free_buffer(disp, ev->buffer.base, ev->buffer.length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-28 14:52:28 -07:00
|
|
|
free_devent(disp, ev);
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
1999-07-22 01:34:31 +00:00
|
|
|
|
2000-04-29 00:45:26 +00:00
|
|
|
request_log(disp, res, LVL(90), "detaching from task %p", res->task);
|
1999-10-07 19:38:39 +00:00
|
|
|
isc_task_detach(&res->task);
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
if (res->dispsocket != NULL) {
|
|
|
|
isc_socket_cancel(res->dispsocket->socket,
|
|
|
|
res->dispsocket->task, ISC_SOCKCANCEL_RECV);
|
|
|
|
res->dispsocket->resp = NULL;
|
|
|
|
}
|
|
|
|
|
1999-07-22 01:34:31 +00:00
|
|
|
/*
|
2016-07-11 13:36:16 +10:00
|
|
|
* Free any buffered responses as well
|
1999-07-22 01:34:31 +00:00
|
|
|
*/
|
|
|
|
ev = ISC_LIST_HEAD(res->items);
|
|
|
|
while (ev != NULL) {
|
2000-04-17 19:22:44 +00:00
|
|
|
ISC_LIST_UNLINK(res->items, ev, ev_link);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ev->buffer.base != NULL) {
|
1999-07-22 01:34:31 +00:00
|
|
|
free_buffer(disp, ev->buffer.base, ev->buffer.length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-28 14:52:28 -07:00
|
|
|
free_devent(disp, ev);
|
1999-07-22 01:34:31 +00:00
|
|
|
ev = ISC_LIST_HEAD(res->items);
|
|
|
|
}
|
2000-04-29 00:45:26 +00:00
|
|
|
res->magic = 0;
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_refcount_decrement(&disp->mgr->irefs);
|
|
|
|
isc_mem_put(disp->mgr->mctx, res, sizeof(*res));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->shutting_down == 1) {
|
2004-07-21 00:48:19 +00:00
|
|
|
do_cancel(disp);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-06-23 19:41:20 +00:00
|
|
|
(void)startrecv(disp, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-06-18 02:01:42 +00:00
|
|
|
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
killit = destroy_disp_ok(disp);
|
1999-06-18 02:01:42 +00:00
|
|
|
UNLOCK(&disp->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (killit) {
|
2008-06-23 19:41:20 +00:00
|
|
|
isc_task_send(disp->task[0], &disp->ctlevent);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-06-16 01:32:31 +00:00
|
|
|
}
|
|
|
|
|
2020-12-19 01:34:41 -08:00
|
|
|
isc_result_t
|
|
|
|
dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp,
|
|
|
|
isc_task_t *task, isc_taskaction_t action, void *arg) {
|
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
isc_sockaddr_t *address = NULL;
|
|
|
|
|
|
|
|
if (resp != NULL) {
|
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
sock = resp->dispsocket->socket;
|
|
|
|
address = &resp->host;
|
|
|
|
} else if (disp != NULL) {
|
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
sock = disp->socket;
|
|
|
|
address = &disp->peer;
|
|
|
|
} else {
|
|
|
|
INSIST(0);
|
|
|
|
ISC_UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
|
|
|
return (isc_socket_connect(sock, address, task, action, arg));
|
|
|
|
}
|
|
|
|
|
2021-01-04 23:03:50 -08:00
|
|
|
isc_result_t
|
|
|
|
dns_dispatch_send(dns_dispentry_t *resp, bool tcp, isc_task_t *task,
|
|
|
|
isc_socketevent_t *sendevent, isc_region_t *r,
|
|
|
|
const isc_sockaddr_t *address, isc_dscp_t dscp,
|
|
|
|
isc_taskaction_t action, void *arg) {
|
|
|
|
isc_result_t result;
|
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
REQUIRE(sendevent != NULL);
|
|
|
|
|
|
|
|
memset(sendevent, 0, sizeof(isc_socketevent_t));
|
|
|
|
ISC_EVENT_INIT(sendevent, sizeof(isc_socketevent_t), 0, NULL,
|
|
|
|
ISC_SOCKEVENT_SENDDONE, action, arg, NULL, NULL, NULL);
|
|
|
|
|
2021-01-04 23:51:07 -08:00
|
|
|
sock = getentrysocket(resp);
|
2021-01-04 23:03:50 -08:00
|
|
|
|
|
|
|
if (dscp == -1) {
|
|
|
|
sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
|
|
|
|
sendevent->dscp = 0;
|
|
|
|
} else {
|
|
|
|
sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
|
|
|
|
sendevent->dscp = dscp;
|
|
|
|
if (tcp) {
|
|
|
|
isc_socket_dscp(sock, dscp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tcp) {
|
|
|
|
address = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = isc_socket_sendto2(sock, r, task, address, NULL, sendevent, 0);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2021-01-04 23:51:07 -08:00
|
|
|
void
|
|
|
|
dns_dispatch_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp, bool sending,
|
|
|
|
bool connecting) {
|
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(disp != NULL || resp != NULL);
|
|
|
|
|
|
|
|
if (resp != NULL) {
|
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
sock = getentrysocket(resp);
|
|
|
|
} else if (disp != NULL) {
|
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
sock = getsocket(disp);
|
|
|
|
} else {
|
|
|
|
INSIST(0);
|
|
|
|
ISC_UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sock == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (connecting) {
|
|
|
|
isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sending) {
|
|
|
|
isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-19 14:14:21 +11:00
|
|
|
/*
|
|
|
|
* disp must be locked.
|
|
|
|
*/
|
1999-07-08 02:50:00 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
do_cancel(dns_dispatch_t *disp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchevent_t *ev = NULL;
|
|
|
|
dns_dispentry_t *resp = NULL;
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
dns_qid_t *qid = disp->mgr->qid;
|
1999-07-09 00:51:08 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp->shutdown_out == 1) {
|
1999-07-08 02:50:00 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-04-29 00:45:26 +00:00
|
|
|
|
1999-07-08 02:50:00 +00:00
|
|
|
/*
|
2008-06-23 19:41:20 +00:00
|
|
|
* Search for the first response handler without packets outstanding
|
2020-02-20 14:49:36 -08:00
|
|
|
* unless a specific handler is given.
|
1999-07-08 02:50:00 +00:00
|
|
|
*/
|
2004-07-21 00:48:19 +00:00
|
|
|
LOCK(&qid->lock);
|
2020-02-12 13:59:18 +01:00
|
|
|
for (resp = linear_first(qid); resp != NULL && resp->item_out;
|
2020-02-13 14:44:37 -08:00
|
|
|
/* Empty. */)
|
|
|
|
{
|
2004-07-21 00:48:19 +00:00
|
|
|
resp = linear_next(qid, resp);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
1999-07-22 01:34:31 +00:00
|
|
|
/*
|
|
|
|
* No one to send the cancel event to, so nothing to do.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (resp == NULL) {
|
2004-07-21 00:48:19 +00:00
|
|
|
goto unlock;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-22 01:34:31 +00:00
|
|
|
|
1999-07-08 02:50:00 +00:00
|
|
|
/*
|
1999-07-09 00:51:08 +00:00
|
|
|
* Send the shutdown failsafe event to this resp.
|
1999-07-08 02:50:00 +00:00
|
|
|
*/
|
1999-07-09 00:51:08 +00:00
|
|
|
ev = disp->failsafe_ev;
|
2001-11-12 19:05:39 +00:00
|
|
|
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
|
1999-07-09 00:51:08 +00:00
|
|
|
resp->action, resp->arg, resp, NULL, NULL);
|
1999-07-12 23:44:31 +00:00
|
|
|
ev->result = disp->shutdown_why;
|
1999-07-09 00:51:08 +00:00
|
|
|
ev->buffer.base = NULL;
|
|
|
|
ev->buffer.length = 0;
|
1999-07-12 23:44:31 +00:00
|
|
|
disp->shutdown_out = 1;
|
2020-02-12 13:59:18 +01:00
|
|
|
request_log(disp, resp, LVL(10), "cancel: failsafe event %p -> task %p",
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
ev, resp->task);
|
2018-04-17 08:29:14 -07:00
|
|
|
resp->item_out = true;
|
2004-04-15 01:58:25 +00:00
|
|
|
isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
|
2020-02-12 13:59:18 +01:00
|
|
|
unlock:
|
2004-07-21 00:48:19 +00:00
|
|
|
UNLOCK(&qid->lock);
|
1999-07-08 02:50:00 +00:00
|
|
|
}
|
1999-07-09 20:32:12 +00:00
|
|
|
|
2021-01-04 23:51:07 -08:00
|
|
|
static isc_socket_t *
|
|
|
|
getsocket(dns_dispatch_t *disp) {
|
1999-07-09 20:32:12 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
|
|
|
|
return (disp->socket);
|
|
|
|
}
|
1999-07-22 01:34:31 +00:00
|
|
|
|
2021-01-04 23:51:07 -08:00
|
|
|
static isc_socket_t *
|
|
|
|
getentrysocket(dns_dispentry_t *resp) {
|
2008-06-23 19:41:20 +00:00
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
|
2020-12-16 01:32:06 -08:00
|
|
|
if (resp->disp->socktype == isc_sockettype_tcp) {
|
|
|
|
return (resp->disp->socket);
|
|
|
|
} else if (resp->dispsocket != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (resp->dispsocket->socket);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-06-23 19:41:20 +00:00
|
|
|
return (NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
2001-03-13 05:48:41 +00:00
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) {
|
2001-03-13 05:48:41 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
REQUIRE(addrp != NULL);
|
|
|
|
|
|
|
|
if (disp->socktype == isc_sockettype_udp) {
|
|
|
|
*addrp = disp->local;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2021-01-04 14:38:35 -08:00
|
|
|
isc_result_t
|
|
|
|
dns_dispentry_getlocaladdress(dns_dispentry_t *resp, isc_sockaddr_t *addrp) {
|
|
|
|
REQUIRE(VALID_RESPONSE(resp));
|
|
|
|
REQUIRE(addrp != NULL);
|
|
|
|
|
|
|
|
if (resp->disp->socktype == isc_sockettype_tcp) {
|
|
|
|
return (isc_socket_getsockname(resp->disp->socket, addrp));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resp->dispsocket != NULL) {
|
|
|
|
return (isc_socket_getsockname(resp->dispsocket->socket,
|
|
|
|
addrp));
|
|
|
|
}
|
|
|
|
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
unsigned int
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_getattributes(dns_dispatch_t *disp) {
|
2008-06-23 19:41:20 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We don't bother locking disp here; it's the caller's responsibility
|
|
|
|
* to use only non volatile flags.
|
|
|
|
*/
|
|
|
|
return (disp->attributes);
|
|
|
|
}
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
void
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_dispatch_changeattributes(dns_dispatch_t *disp, unsigned int attributes,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int mask) {
|
2000-09-01 07:16:06 +00:00
|
|
|
REQUIRE(VALID_DISPATCH(disp));
|
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
LOCK(&disp->lock);
|
2001-01-27 02:08:07 +00:00
|
|
|
|
2000-05-10 21:34:50 +00:00
|
|
|
disp->attributes &= ~mask;
|
|
|
|
disp->attributes |= (attributes & mask);
|
|
|
|
UNLOCK(&disp->lock);
|
|
|
|
}
|
2000-05-11 07:33:17 +00:00
|
|
|
|
2012-04-27 16:07:24 -07:00
|
|
|
dns_dispatch_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchset_get(dns_dispatchset_t *dset) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatch_t *disp = NULL;
|
2012-04-27 16:07:24 -07:00
|
|
|
|
|
|
|
/* check that dispatch set is configured */
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dset == NULL || dset->ndisp == 0) {
|
2012-04-27 16:07:24 -07:00
|
|
|
return (NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
|
|
|
|
LOCK(&dset->lock);
|
|
|
|
disp = dset->dispatches[dset->cur];
|
|
|
|
dset->cur++;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dset->cur == dset->ndisp) {
|
2012-04-27 16:07:24 -07:00
|
|
|
dset->cur = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
UNLOCK(&dset->lock);
|
|
|
|
|
|
|
|
return (disp);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
|
|
|
|
isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchset_t **dsetp, int n) {
|
|
|
|
isc_result_t result;
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchset_t *dset = NULL;
|
|
|
|
dns_dispatchmgr_t *mgr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
int i, j;
|
2012-04-27 16:07:24 -07:00
|
|
|
|
|
|
|
REQUIRE(VALID_DISPATCH(source));
|
|
|
|
REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0);
|
|
|
|
REQUIRE(dsetp != NULL && *dsetp == NULL);
|
|
|
|
|
|
|
|
mgr = source->mgr;
|
|
|
|
|
|
|
|
dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
|
2020-12-09 19:44:41 -08:00
|
|
|
*dset = (dns_dispatchset_t){ .ndisp = n };
|
2012-04-27 16:07:24 -07:00
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&dset->lock);
|
2012-04-27 16:07:24 -07:00
|
|
|
|
|
|
|
dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n);
|
|
|
|
|
|
|
|
isc_mem_attach(mctx, &dset->mctx);
|
|
|
|
|
|
|
|
dset->dispatches[0] = NULL;
|
|
|
|
dns_dispatch_attach(source, &dset->dispatches[0]);
|
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
for (i = 1; i < n; i++) {
|
|
|
|
dset->dispatches[i] = NULL;
|
2020-12-16 01:32:06 -08:00
|
|
|
result = dispatch_createudp(mgr, sockmgr, taskmgr,
|
Dispatch API simplification
- Many dispatch attributes can be set implicitly instead of being passed
in. we can infer whether to set DNS_DISPATCHATTR_TCP or _UDP from
whether we're calling dns_dispatch_createtcp() or _createudp(). we
can also infer DNS_DISPATCHATTR_IPV4 or _IPV6 from the addresses or
the socket that were passed in.
- We no longer use dup'd sockets in UDP dispatches, so the 'dup_socket'
parameter has been removed from dns_dispatch_createudp(), along with
the code implementing it. also removed isc_socket_dup() since it no
longer has any callers.
- The 'buffersize' parameter was ignored and has now been removed;
buffersize is now fixed at 4096.
- Maxbuffers and maxrequests don't need to be passed in on every call to
dns_dispatch_createtcp() and _createudp().
In all current uses, the value for mgr->maxbuffers will either be
raised once from its default of 20000 to 32768, or else left
alone. (passing in a value lower than 20000 does not lower it.) there
isn't enough difference between these values for there to be any need
to configure this.
The value for disp->maxrequests controls both the quota of concurrent
requests for a dispatch and also the size of the dispatch socket
memory pool. it's not clear that this quota is necessary at all. the
memory pool size currently starts at 32768, but is sometimes lowered
to 4096, which is definitely unnecessary.
This commit sets both values permanently to 32768.
- Previously TCP dispatches allocated their own separate QID table,
which didn't incorporate a port table. this commit removes
per-dispatch QID tables and shares the same table between all
dispatches. since dispatches are created for each TCP socket, this may
speed up the dispatch allocation process. there may be a slight
increase in lock contention since all dispatches are sharing a single
QID table, but since TCP sockets are used less often than UDP
sockets (which were already sharing a QID table), it should not be a
substantial change.
- The dispatch port table was being used to determine whether a port was
already in use; if so, then a UDP socket would be bound with
REUSEADDR. this commit removes the port table, and always binds UDP
sockets that way.
2020-12-17 00:43:00 -08:00
|
|
|
&source->local, source->attributes,
|
2020-12-16 01:32:06 -08:00
|
|
|
&dset->dispatches[i]);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2012-04-27 16:07:24 -07:00
|
|
|
goto fail;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
*dsetp = dset;
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
fail:
|
2012-04-27 16:07:24 -07:00
|
|
|
UNLOCK(&mgr->lock);
|
2012-04-28 23:45:42 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
for (j = 0; j < i; j++) {
|
2012-04-27 16:07:24 -07:00
|
|
|
dns_dispatch_detach(&(dset->dispatches[j]));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dset->mctx == mctx) {
|
2012-04-27 16:07:24 -07:00
|
|
|
isc_mem_detach(&dset->mctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&dset->lock);
|
2012-04-27 16:07:24 -07:00
|
|
|
isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
|
2020-12-09 19:44:41 -08:00
|
|
|
dns_dispatchset_t *dset = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
int i;
|
2012-04-27 16:07:24 -07:00
|
|
|
|
|
|
|
REQUIRE(dsetp != NULL && *dsetp != NULL);
|
|
|
|
|
|
|
|
dset = *dsetp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*dsetp = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
for (i = 0; i < dset->ndisp; i++) {
|
2012-04-27 16:07:24 -07:00
|
|
|
dns_dispatch_detach(&(dset->dispatches[i]));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-04-27 16:07:24 -07:00
|
|
|
isc_mem_put(dset->mctx, dset->dispatches,
|
|
|
|
sizeof(dns_dispatch_t *) * dset->ndisp);
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&dset->lock);
|
2012-04-27 16:07:24 -07:00
|
|
|
isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
|
|
|
|
}
|