dispatch.c revision 970aa7d783b004d0f665d7107260a823a0d2a645
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff/*
ee980d3fc4c23b7f87fed96d3ba5e928937c9ed4Tinderbox User * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff * purpose with or without fee is hereby granted, provided that the above
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff */
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
23daf8948b2e5462ccea082a441e9759dffa50cdMark Andrews/* $Id: dispatch.c,v 1.175 2011/11/29 01:03:47 marka Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff#include <config.h>
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff#include <stdlib.h>
07072c9456f1112705db701bb35f12dbdcb217b0Mark Andrews#include <sys/types.h>
07072c9456f1112705db701bb35f12dbdcb217b0Mark Andrews#include <unistd.h>
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#include <stdlib.h>
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff#include <isc/entropy.h>
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff#include <isc/mem.h>
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#include <isc/mutex.h>
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#include <isc/portset.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/print.h>
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#include <isc/random.h>
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt#include <isc/socket.h>
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉#include <isc/stats.h>
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrence#include <isc/string.h>
32eddfc189108fa93e31761e13150594c7a79d2bDavid Lawrence#include <isc/task.h>
a095cd0ef599eb04d74fb9f9bc46ae13081c5bcbMark Andrews#include <isc/time.h>
440be4c866f6935ac069db79a414304507a664c2Michael Graff#include <isc/util.h>
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington#include <dns/acl.h>
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff#include <dns/dispatch.h>
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff#include <dns/events.h>
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff#include <dns/log.h>
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff#include <dns/message.h>
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews#include <dns/portlist.h>
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews#include <dns/stats.h>
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff#include <dns/tcpmsg.h>
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#include <dns/types.h>
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewstypedef ISC_LIST(dns_dispentry_t) dns_displist_t;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewstypedef struct dispsocket dispsocket_t;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉typedef ISC_LIST(dispsocket_t) dispsocketlist_t;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewstypedef struct dispportentry dispportentry_t;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewstypedef ISC_LIST(dispportentry_t) dispportlist_t;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/* ARC4 Random generator state */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉typedef struct arc4ctx {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint8_t i;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint8_t j;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint8_t s[256];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int count;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_entropy_t *entropy; /*%< entropy source for ARC4 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mutex_t *lock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉} arc4ctx_t;
07072c9456f1112705db701bb35f12dbdcb217b0Mark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewstypedef struct dns_qid {
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews unsigned int magic;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int qid_nbuckets; /*%< hash table size */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int qid_increment; /*%< id increment on collision */
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews isc_mutex_t lock;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_displist_t *qid_table; /*%< the table itself */
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsocketlist_t *sock_table; /*%< socket table */
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews} dns_qid_t;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffstruct dns_dispatchmgr {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff /* Unlocked. */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff unsigned int magic;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_t *mctx;
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington dns_acl_t *blackhole;
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews dns_portlist_t *portlist;
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 isc_stats_t *stats;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_entropy_t *entropy; /*%< entropy source */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff /* Locked by "lock". */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mutex_t lock;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff unsigned int state;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LIST(dns_dispatch_t) list;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* Locked by arc4_lock. */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mutex_t arc4_lock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 arc4ctx_t arc4ctx; /*%< ARC4 context for QID */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews /* locked by buffer lock */
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mutex_t buffer_lock;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int buffers; /*%< allocated buffers */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int buffersize; /*%< size of each buffer */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int maxbuffers; /*%< max buffers */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /* Locked internally. */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t depool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *depool; /*%< pool for dispatch events */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t rpool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *rpool; /*%< pool for replies */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t dpool_lock;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_mempool_t *dpool; /*%< dispatch allocations */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t bpool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *bpool; /*%< pool for buffers */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t spool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *spool; /*%< pool for dispsocks */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Locked by qid->lock if qid exists; otherwise, can be used without
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * being locked.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Memory footprint considerations: this is a simple implementation of
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * available ports, i.e., an ordered array of the actual port numbers.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * This will require about 256KB of memory in the worst case (128KB for
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * each of IPv4 and IPv6). We could reduce it by representing it as a
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * more sophisticated way such as a list (or array) of ranges that are
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * searched to identify a specific port. Our decision here is the saved
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * memory isn't worth the implementation complexity, considering the
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * fact that the whole BIND9 process (which is mainly named) already
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * requires a pretty large memory footprint. We may, however, have to
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * revisit the decision when we want to use it as a separate module for
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * an environment where memory requirement is severer.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *v4ports; /*%< available ports for IPv4 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nv4ports; /*%< # of available ports for IPv4 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *v6ports; /*%< available ports for IPv4 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nv6ports; /*%< # of available ports for IPv4 */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff};
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define MGR_SHUTTINGDOWN 0x00000001U
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0)
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graffstruct dns_dispentry {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff unsigned int magic;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
038a3e6bfe6e15479b0469bd87de3a7139ad1109Brian Wellington dns_messageid_t id;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t port;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff unsigned int bucket;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff isc_sockaddr_t host;
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff isc_task_t *task;
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff isc_taskaction_t action;
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff void *arg;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff isc_boolean_t item_out;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsocket;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff ISC_LIST(dns_dispatchevent_t) items;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff ISC_LINK(dns_dispentry_t) link;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉};
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Maximum number of dispatch sockets that can be pooled for reuse. The
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * appropriate value may vary, but experiments have shown a busy caching server
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * may need more than 1000 sockets concurrently opened. The maximum allowable
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * number of dispatch sockets (per manager) will be set to the double of this
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * value.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#ifndef DNS_DISPATCH_POOLSOCKS
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define DNS_DISPATCH_POOLSOCKS 2048
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#endif
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Quota to control the number of dispatch sockets. If a dispatch has more
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * than the quota of sockets, new queries will purge oldest ones, so that
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * a massive number of outstanding queries won't prevent subsequent queries
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * (especially if the older ones take longer time and result in timeout).
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#ifndef DNS_DISPATCH_SOCKSQUOTA
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define DNS_DISPATCH_SOCKSQUOTA 3072
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#endif
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉struct dispsocket {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int magic;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_t *socket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispatch_t *disp;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 isc_sockaddr_t host;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews in_port_t localport; /* XXX: should be removed later */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportentry_t *portentry;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispentry_t *resp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_t *task;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LINK(dispsocket_t) link;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 unsigned int bucket;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LINK(dispsocket_t) blink;
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff};
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews/*%
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews * A port table entry. We remember every port we first open in a table with a
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews * reference counter so that we can 'reuse' the same port (with different
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews * destination addresses) using the SO_REUSEADDR socket option.
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsstruct dispportentry {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews in_port_t port;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews unsigned int refs;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews ISC_LINK(struct dispportentry) link;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews};
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews#ifndef DNS_DISPATCH_PORTTABLESIZE
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews#define DNS_DISPATCH_PORTTABLESIZE 1024
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews#endif
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
607dc8013a8cb34cd03b59292aa1ac01e008c9c1Michael Graff#define INVALID_BUCKET (0xffffdead)
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Number of tasks for each dispatch that use separate sockets for different
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * transactions. This must be a power of 2 as it will divide 32 bit numbers
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * to get an uniformly random tasks selection. See get_dispsocket().
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define MAX_INTERNAL_TASKS 64
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graffstruct dns_dispatch {
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff /* Unlocked. */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int magic; /*%< magic */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_dispatchmgr_t *mgr; /*%< dispatch manager */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int ntasks;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * internal task buckets. We use multiple tasks to distribute various
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * socket events well when using separate dispatch sockets. We use the
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * 1st task (task[0]) for internal control events.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_t *task[MAX_INTERNAL_TASKS];
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_socket_t *socket; /*%< isc socket attached to */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_sockaddr_t local; /*%< local address */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t localport; /*%< local UDP port */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int maxrequests; /*%< max requests */
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington isc_event_t *ctlevent;
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_t sepool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *sepool; /*%< pool for socket events */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein /*% Locked by mgr->lock. */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LINK(dns_dispatch_t) link;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff /* Locked by "lock". */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_mutex_t lock; /*%< locks all below */
ce5bd92088923d1c76e26d313d1d8c0b8bbe38feMichael Graff isc_sockettype_t socktype;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int attributes;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int refcount; /*%< number of users */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff unsigned int shutting_down : 1,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff shutdown_out : 1,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff connected : 1,
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington tcpmsg_valid : 1,
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein recv_pending : 1; /*%< is a recv() pending? */
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff isc_result_t shutdown_why;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST(dispsocket_t) activesockets;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST(dispsocket_t) inactivesockets;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nsockets;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int requests; /*%< how many requests we have */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int tcpbuffers; /*%< allocated buffers */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_tcpmsg_t tcpmsg; /*%< for tcp streams */
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 arc4ctx_t arc4ctx; /*%< for QID/UDP port num */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportlist_t *port_table; /*%< hold ports 'owned' by us */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mempool_t *portpool; /*%< port table entries */
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff};
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews#define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC)
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p')
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC)
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define DISPSOCK_MAGIC ISC_MAGIC('D', 's', 'o', 'c')
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define VALID_DISPSOCK(e) ISC_MAGIC_VALID((e), DISPSOCK_MAGIC)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p')
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC)
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r')
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC)
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews#define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews (disp)->qid : (disp)->mgr->qid
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define DISP_ARC4CTX(disp) ((disp)->socktype == isc_sockettype_udp) ? \
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (&(disp)->arc4ctx) : (&(disp)->mgr->arc4ctx)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Locking a query port buffer is a bit tricky. We access the buffer without
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * locking until qid is created. Technically, there is a possibility of race
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * between the creation of qid and access to the port buffer; in practice,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * however, this should be safe because qid isn't created until the first
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * dispatch is created and there should be no contending situation until then.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define PORTBUFLOCK(mgr) if ((mgr)->qid != NULL) LOCK(&((mgr)->qid->lock))
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉#define PORTBUFUNLOCK(mgr) if ((mgr)->qid != NULL) UNLOCK((&(mgr)->qid->lock))
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff/*
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrence * Statics.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉static dns_dispentry_t *entry_search(dns_qid_t *, isc_sockaddr_t *,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dns_messageid_t, in_port_t, unsigned int);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_boolean_t destroy_disp_ok(dns_dispatch_t *);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellingtonstatic void destroy_disp(isc_task_t *task, isc_event_t *event);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void destroy_dispsocket(dns_dispatch_t *, dispsocket_t **);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void udp_exrecv(isc_task_t *, isc_event_t *);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void udp_shrecv(isc_task_t *, isc_event_t *);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void udp_recv(isc_event_t *, dns_dispatch_t *, dispsocket_t *);
0a9fedafec59fd3ec2eeadc3f123db163e71c0fbMichael Graffstatic void tcp_recv(isc_task_t *, isc_event_t *);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t startrecv(dns_dispatch_t *, dispsocket_t *);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t);
0a9fedafec59fd3ec2eeadc3f123db163e71c0fbMichael Graffstatic void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
8470db5b12c18cfb32a757e265ce4e7789052c92Michael Graffstatic void *allocate_udp_buffer(dns_dispatch_t *disp);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntstatic inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntstatic inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrewsstatic void do_cancel(dns_dispatch_t *disp);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewsstatic dns_dispentry_t *linear_first(dns_qid_t *disp);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewsstatic dns_dispentry_t *linear_next(dns_qid_t *disp,
0a9fedafec59fd3ec2eeadc3f123db163e71c0fbMichael Graff dns_dispentry_t *resp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic void dispatch_free(dns_dispatch_t **dispp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispatch_t *disp,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socketmgr_t *sockmgr,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_t *localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t **sockp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t *dup_socket);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_socketmgr_t *sockmgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_sockaddr_t *localaddr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int maxrequests,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int attributes,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dns_dispatch_t **dispp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t *dup_socket);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic void destroy_mgr(dns_dispatchmgr_t **mgrp);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsstatic isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int increment, dns_qid_t **qidp,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_boolean_t needaddrtable);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsstatic void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int options, isc_socket_t **sockp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t *dup_socket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_boolean_t portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_t *sockaddrp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff#define LVL(x) ISC_LOG_DEBUG(x)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonstatic void
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonmgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...)
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson ISC_FORMAT_PRINTF(3, 4);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graffstatic void
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffmgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) {
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff char msgbuf[2048];
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_list ap;
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington if (! isc_log_wouldlog(dns_lctx, level))
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington return;
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_start(ap, fmt);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_end(ap);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_log_write(dns_lctx,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff level, "dispatchmgr %p: %s", mgr, msgbuf);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrewsstatic inline void
870a748bae74b9c4b264da96cfbcb4e90d7a2c1dMark Andrewsinc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews if (mgr->stats != NULL)
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews isc_stats_increment(mgr->stats, counter);
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews}
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonstatic void
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssondispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...)
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson ISC_FORMAT_PRINTF(3, 4);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic void
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff char msgbuf[2048];
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff va_list ap;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
9317787889b6d2437b2f8e77583b49246f7511feAndreas Gustafsson if (! isc_log_wouldlog(dns_lctx, level))
9317787889b6d2437b2f8e77583b49246f7511feAndreas Gustafsson return;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff va_start(ap, fmt);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff va_end(ap);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_log_write(dns_lctx,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff level, "dispatch %p: %s", disp, msgbuf);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff}
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonstatic void
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonrequest_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson int level, const char *fmt, ...)
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson ISC_FORMAT_PRINTF(4, 5);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graffstatic void
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graffrequest_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff int level, const char *fmt, ...)
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff{
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff char msgbuf[2048];
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff char peerbuf[256];
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_list ap;
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington if (! isc_log_wouldlog(dns_lctx, level))
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington return;
f6579931b38b357013736ce3efc79a34480af5ceBrian Wellington
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_start(ap, fmt);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff va_end(ap);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff if (VALID_RESPONSE(resp)) {
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff DNS_LOGMODULE_DISPATCH, level,
ec46482ef3c0c3e9747f0074cb9263adb8aef961Andreas Gustafsson "dispatch %p response %p %s: %s", disp, resp,
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff peerbuf, msgbuf);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff } else {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff DNS_LOGMODULE_DISPATCH, level,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff "dispatch %p req/resp %p: %s", disp, resp,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff msgbuf);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff }
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff}
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * ARC4 random number generator derived from OpenBSD.
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 * Only dispatch_random() and dispatch_uniformrandom() are expected
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * to be called from general dispatch routines; the rest of them are subroutines
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * for these two.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * The original copyright follows:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Copyright (c) 1996, David Mazieres <dm@uun.org>
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Permission to use, copy, modify, and distribute this software for any
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * purpose with or without fee is hereby granted, provided that the above
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * copyright notice and this permission notice appear in all copies.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews */
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_mutex_t *lock)
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉{
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int n;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (n = 0; n < 256; n++)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->s[n] = n;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->i = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->j = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->count = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->entropy = entropy; /* don't have to attach */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->lock = lock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dispatch_arc4addrandom(arc4ctx_t *actx, unsigned char *dat, int datlen) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int n;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint8_t si;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->i--;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (n = 0; n < 256; n++) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->i = (actx->i + 1);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 si = actx->s[actx->i];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->j = (actx->j + si + dat[n % datlen]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->s[actx->i] = actx->s[actx->j];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->s[actx->j] = si;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->j = actx->i;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static inline isc_uint8_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dispatch_arc4get8(arc4ctx_t *actx) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint8_t si, sj;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->i = (actx->i + 1);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 si = actx->s[actx->i];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->j = (actx->j + si);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sj = actx->s[actx->j];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->s[actx->i] = sj;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->s[actx->j] = si;
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (actx->s[(si + sj) & 0xff]);
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews}
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static inline isc_uint16_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dispatch_arc4get16(arc4ctx_t *actx) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint16_t val;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 val = dispatch_arc4get8(actx) << 8;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 val |= dispatch_arc4get8(actx);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (val);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dispatch_arc4stir(arc4ctx_t *actx) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int i;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 union {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned char rnd[128];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint32_t rnd32[32];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } rnd;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_result_t result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (actx->entropy != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * We accept any quality of random data to avoid blocking.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_entropy_getdata(actx->entropy, rnd.rnd,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sizeof(rnd), NULL, 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 RUNTIME_CHECK(result == ISC_R_SUCCESS);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < 32; i++)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_random_get(&rnd.rnd32[i]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_arc4addrandom(actx, rnd.rnd, sizeof(rnd.rnd));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Discard early keystream, as per recommendations in:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < 256; i++)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (void)dispatch_arc4get8(actx);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Derived from OpenBSD's implementation. The rationale is not clear,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * but should be conservative enough in safety, and reasonably large
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * for efficiency.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->count = 1600000;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_uint16_t
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉dispatch_random(arc4ctx_t *actx) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint16_t result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (actx->lock != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 LOCK(actx->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 actx->count -= sizeof(isc_uint16_t);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (actx->count <= 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_arc4stir(actx);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = dispatch_arc4get16(actx);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (actx->lock != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(actx->lock);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#else
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉/*
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 * For general purpose library, we don't have to be too strict about the
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 * quality of random values. Performance doesn't matter much, either.
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 * So we simply use the isc_random module to keep the library as small as
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 * possible.
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 */
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉static void
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_mutex_t *lock)
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉{
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(actx);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(entropy);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(lock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 return;
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉}
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉static isc_uint16_t
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉dispatch_random(arc4ctx_t *actx) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_uint32_t r;
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(actx);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_random_get(&r);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 return (r & 0xffff);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉}
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif /* BIND9 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_uint16_t
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉dispatch_uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint16_t min, r;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (upper_bound < 2)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Ensure the range of random numbers [min, 0xffff] be a multiple of
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * upper_bound and contain at least a half of the 16 bit range.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (upper_bound > 0x8000)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 min = 1 + ~upper_bound; /* 0x8000 - upper_bound */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 min = (isc_uint16_t)(0x10000 % (isc_uint32_t)upper_bound);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * This could theoretically loop forever but each retry has
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * p > 0.5 (worst case, usually far better) of selecting a
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * number inside the range we need, so it should rarely need
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * to re-roll.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (;;) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 r = dispatch_random(actx);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (r >= min)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 break;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (r % upper_bound);
0a9fedafec59fd3ec2eeadc3f123db163e71c0fbMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff/*
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff * Return a hash of the destination and message id.
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff */
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graffstatic isc_uint32_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t port)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉{
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff unsigned int ret;
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff ret = isc_sockaddr_hash(dest, ISC_TRUE);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ret ^= (id << 16) | port;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ret %= qid->qid_nbuckets;
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews INSIST(ret < qid->qid_nbuckets);
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff return (ret);
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff}
0941f35ad9b4f48a5324af405a730c3cb3e0aad8Michael Graff
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson/*
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson * Find the first entry in 'qid'. Returns NULL if there are no entries.
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson */
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic dns_dispentry_t *
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewslinear_first(dns_qid_t *qid) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff dns_dispentry_t *ret;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff unsigned int bucket;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff bucket = 0;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews while (bucket < qid->qid_nbuckets) {
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (ret != NULL)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (ret);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff bucket++;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (NULL);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson/*
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson * Find the next entry after 'resp' in 'qid'. Return NULL if there are
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson * no more entries.
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson */
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic dns_dispentry_t *
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewslinear_next(dns_qid_t *qid, dns_dispentry_t *resp) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff dns_dispentry_t *ret;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff unsigned int bucket;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff ret = ISC_LIST_NEXT(resp, link);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (ret != NULL)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (ret);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff bucket = resp->bucket;
c17c59662f0969a5e52e8b7529cbde1a7c746095Andreas Gustafsson bucket++;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews while (bucket < qid->qid_nbuckets) {
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (ret != NULL)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (ret);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff bucket++;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (NULL);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * The dispatch must be locked.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_boolean_t
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdestroy_disp_ok(dns_dispatch_t *disp)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (disp->refcount != 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington if (disp->recv_pending != 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (!ISC_LIST_EMPTY(disp->activesockets))
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_FALSE);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (disp->shutting_down == 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_TRUE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff/*
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * Called when refcount reaches 0 (and safe to destroy).
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff *
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * The dispatcher must not be locked.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * The manager must be locked.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graffstatic void
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellingtondestroy_disp(isc_task_t *task, isc_event_t *event) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington dns_dispatchmgr_t *mgr;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington isc_boolean_t killmgr;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsocket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int i;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington UNUSED(task);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington disp = event->ev_arg;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr = disp->mgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington LOCK(&mgr->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LIST_UNLINK(mgr->list, disp, link);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(90),
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff "shutting down; detaching from sock %p, task %p",
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->socket, disp->task[0]); /* XXXX */
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (disp->sepool != NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_destroy(&disp->sepool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mutex_destroy(&disp->sepool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (disp->socket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&disp->socket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(disp->inactivesockets, dispsocket, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsocket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < disp->ntasks; i++)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_detach(&disp->task[i]);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington isc_event_free(&event);
04458c8b5da001294e820289b34bf3aee6258f27Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dispatch_free(&disp);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington killmgr = destroy_mgr_ok(mgr);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington UNLOCK(&mgr->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (killmgr)
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington destroy_mgr(&mgr);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews/*%
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews * Manipulate port table per dispatch: find an entry for a given port number,
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews * create a new entry, and decrement a given entry with possible clean-up.
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsstatic dispportentry_t *
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsport_search(dns_dispatch_t *disp, in_port_t port) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportentry_t *portentry;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews REQUIRE(disp->port_table != NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry = ISC_LIST_HEAD(disp->port_table[port %
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews DNS_DISPATCH_PORTTABLESIZE]);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews while (portentry != NULL) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (portentry->port == port)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews return (portentry);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry = ISC_LIST_NEXT(portentry, link);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews return (NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews}
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsstatic dispportentry_t *
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsnew_portentry(dns_dispatch_t *disp, in_port_t port) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportentry_t *portentry;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews REQUIRE(disp->port_table != NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry = isc_mempool_get(disp->portpool);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (portentry == NULL)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews return (portentry);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry->port = port;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry->refs = 0;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews ISC_LINK_INIT(portentry, link);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE],
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry, link);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews return (portentry);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews}
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt/*%
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt * The caller must not hold the qid->lock.
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt */
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsstatic void
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrewsderef_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportentry_t *portentry = *portentryp;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_boolean_t unlink = ISC_FALSE;
536e36ac8d3c31cd9d61cfa12496177ce263145aMark Andrews dns_qid_t *qid;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews REQUIRE(disp->port_table != NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews REQUIRE(portentry != NULL && portentry->refs > 0);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt qid = DNS_QID(disp);
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt LOCK(&qid->lock);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry->refs--;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt unlink = ISC_TF(portentry->refs == 0);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&qid->lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (unlink) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews ISC_LIST_UNLINK(disp->port_table[portentry->port %
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews DNS_DISPATCH_PORTTABLESIZE],
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry, link);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mempool_put(disp->portpool, portentry);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews *portentryp = NULL;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews}
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉/*%
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 * Find a dispsocket for socket address 'dest', and port number 'port'.
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 * Return NULL if no such entry exists.
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 */
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉static dispsocket_t *
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 unsigned int bucket)
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉{
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsocket_t *dispsock;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 REQUIRE(bucket < qid->qid_nbuckets);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 while (dispsock != NULL) {
2b2fc9b4df2db5686126c9eb56973b0af0c109e5Automatic Updater if (dispsock->portentry != NULL &&
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt dispsock->portentry->port == port &&
cfc22e53a89ccac4eb04b4f41a93f73e629e80edEvan Hunt isc_sockaddr_equal(dest, &dispsock->host))
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 return (dispsock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsock = ISC_LIST_NEXT(dispsock, blink);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 }
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 return (NULL);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉}
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Make a new socket for a single dispatch with a random port number.
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt * The caller must hold the disp->lock
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt in_port_t *portp)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉{
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int i;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_uint32_t r;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispatchmgr_t *mgr = disp->mgr;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_t *sock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_result_t result = ISC_R_FAILURE;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t port;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_t localaddr;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 unsigned int bucket = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *ports;
089f456eb39d614cb6904107d4a9580ed4f3f296Tatuya JINMEI 神明達哉 unsigned int bindoptions;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispportentry_t *portentry = NULL;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt dns_qid_t *qid;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_sockaddr_pf(&disp->local) == AF_INET) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = disp->mgr->nv4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = disp->mgr->v4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = disp->mgr->nv6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = disp->mgr->v6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (nports == 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_ADDRNOTAVAIL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = ISC_LIST_HEAD(disp->inactivesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(disp->inactivesockets, dispsock, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sock = dispsock->socket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->socket = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = isc_mempool_get(mgr->spool);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->nsockets++;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->socket = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->disp = disp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->resp = NULL;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispsock->portentry = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_random_get(&r);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->task = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LINK_INIT(dispsock, link);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LINK_INIT(dispsock, blink);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->magic = DISPSOCK_MAGIC;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Pick up a random UDP port and open a new socket with it. Avoid
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * choosing ports that share the same destination because it will be
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * very likely to fail in bind(2) or connect(2).
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 localaddr = disp->local;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt qid = DNS_QID(disp);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < 64; i++) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp),
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports)];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_setport(&localaddr, port);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt LOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 bucket = dns_hash(qid, dest, 0, port);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (socket_search(qid, dest, port, bucket) != NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&qid->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 continue;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&qid->lock);
089f456eb39d614cb6904107d4a9580ed4f3f296Tatuya JINMEI 神明達哉 bindoptions = 0;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry = port_search(disp, port);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (portentry != NULL)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews bindoptions |= ISC_SOCKET_REUSEADDRESS;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = open_socket(sockmgr, &localaddr, bindoptions, &sock,
2f17ad4545ca552c92c88f7cb1e2525050c10c67Automatic Updater NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (result == ISC_R_SUCCESS) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (portentry == NULL) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry = new_portentry(disp, port);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (portentry == NULL) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews result = ISC_R_NOMEMORY;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews break;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews portentry->refs++;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews break;
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews } else if (result == ISC_R_NOPERM) {
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews char buf[ISC_SOCKADDR_FORMATSIZE];
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews isc_sockaddr_format(&localaddr, buf, sizeof(buf));
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews dispatch_log(disp, ISC_LOG_WARNING,
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews "open_socket(%s) -> %s: continuing",
9cf04a12ec5ea0ee64338feef76e885980a524dfMark Andrews buf, isc_result_totext(result));
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews } else if (result != ISC_R_ADDRINUSE)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 break;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result == ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->socket = sock;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsock->host = *dest;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews dispsock->portentry = portentry;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dispsock->bucket = bucket;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt LOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&qid->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *dispsockp = dispsock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *portp = port;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * We could keep it in the inactive list, but since this should
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * be an exceptional case and might be resource shortage, we'd
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * rather destroy it.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (sock != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&sock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Destroy a dedicated dispatch socket.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsock;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dns_qid_t *qid;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * The dispatch must be locked.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(dispsockp != NULL && *dispsockp != NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = *dispsockp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(!ISC_LINK_LINKED(dispsock, link));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->nsockets--;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->magic = 0;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (dispsock->portentry != NULL)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews deref_portentry(disp, &dispsock->portentry);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock->socket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&dispsock->socket);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (ISC_LINK_LINKED(dispsock, blink)) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 qid = DNS_QID(disp);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 LOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 blink);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 UNLOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock->task != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_detach(&dispsock->task);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_put(disp->mgr->spool, dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *dispsockp = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Deactivate a dedicated dispatch socket. Move it to the inactive list for
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * future reuse unless the total number of sockets are exceeding the maximum.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
34350037a886e7a16728335821da2bbff95683a9Evan Hunt isc_result_t result;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 dns_qid_t *qid;
34350037a886e7a16728335821da2bbff95683a9Evan Hunt
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * The dispatch must be locked.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(disp->activesockets, dispsock, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock->resp != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(dispsock->resp->dispsocket == dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock->resp->dispsocket = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews INSIST(dispsock->portentry != NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews deref_portentry(disp, &dispsock->portentry);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else {
34350037a886e7a16728335821da2bbff95683a9Evan Hunt result = isc_socket_close(dispsock->socket);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 qid = DNS_QID(disp);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 LOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 blink);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 UNLOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉
34350037a886e7a16728335821da2bbff95683a9Evan Hunt if (result == ISC_R_SUCCESS)
34350037a886e7a16728335821da2bbff95683a9Evan Hunt ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
34350037a886e7a16728335821da2bbff95683a9Evan Hunt else {
34350037a886e7a16728335821da2bbff95683a9Evan Hunt /*
34350037a886e7a16728335821da2bbff95683a9Evan Hunt * If the underlying system does not allow this
34350037a886e7a16728335821da2bbff95683a9Evan Hunt * optimization, destroy this temporary structure (and
34350037a886e7a16728335821da2bbff95683a9Evan Hunt * create a new one for a new transaction).
34350037a886e7a16728335821da2bbff95683a9Evan Hunt */
34350037a886e7a16728335821da2bbff95683a9Evan Hunt INSIST(result == ISC_R_NOTIMPLEMENTED);
34350037a886e7a16728335821da2bbff95683a9Evan Hunt destroy_dispsocket(disp, &dispsock);
34350037a886e7a16728335821da2bbff95683a9Evan Hunt }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#else
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 /* This kind of optimization isn't necessary for normal use */
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(qid);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(result);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson/*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Find an entry for query ID 'id', socket address 'dest', and port number
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 * 'port'.
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson * Return NULL if no such entry exists.
3530e10080e5a7d95c7d13abdc02c1d8bd12ec18Andreas Gustafsson */
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graffstatic dns_dispentry_t *
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 in_port_t port, unsigned int bucket)
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff{
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff dns_dispentry_t *res;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews REQUIRE(bucket < qid->qid_nbuckets);
bd7237e653e15bfb7f202a1c0914271912597ef4Michael Graff
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 res = ISC_LIST_HEAD(qid->qid_table[bucket]);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff while (res != NULL) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (res->id == id && isc_sockaddr_equal(dest, &res->host) &&
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res->port == port) {
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff return (res);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff res = ISC_LIST_NEXT(res, link);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff return (NULL);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic void
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencefree_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *bpool;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff INSIST(buf != NULL && len != 0);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff
ce5bd92088923d1c76e26d313d1d8c0b8bbe38feMichael Graff switch (disp->socktype) {
ef4b66d3557505af25fec8ce461f07ddd671ea1eBob Halley case isc_sockettype_tcp:
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews INSIST(disp->tcpbuffers > 0);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews disp->tcpbuffers--;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_put(disp->mgr->mctx, buf, len);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff break;
ef4b66d3557505af25fec8ce461f07ddd671ea1eBob Halley case isc_sockettype_udp:
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews LOCK(&disp->mgr->buffer_lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews INSIST(disp->mgr->buffers > 0);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews INSIST(len == disp->mgr->buffersize);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews disp->mgr->buffers--;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt bpool = disp->mgr->bpool;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNLOCK(&disp->mgr->buffer_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_put(bpool, buf);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff break;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff default:
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff INSIST(0);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff break;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff }
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic void *
8470db5b12c18cfb32a757e265ce4e7789052c92Michael Graffallocate_udp_buffer(dns_dispatch_t *disp) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *bpool;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff void *temp;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews LOCK(&disp->mgr->buffer_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt bpool = disp->mgr->bpool;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt disp->mgr->buffers++;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNLOCK(&disp->mgr->buffer_lock);
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt temp = isc_mempool_get(bpool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (temp == NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt LOCK(&disp->mgr->buffer_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt disp->mgr->buffers--;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&disp->mgr->buffer_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (temp);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic inline void
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntfree_sevent(isc_event_t *ev) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_t *pool = ev->ev_destroy_arg;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_socketevent_t *sev = (isc_socketevent_t *) ev;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_put(pool, sev);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt}
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntstatic inline isc_socketevent_t *
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntallocate_sevent(dns_dispatch_t *disp, isc_socket_t *socket,
ee980d3fc4c23b7f87fed96d3ba5e928937c9ed4Tinderbox User isc_eventtype_t type, isc_taskaction_t action, const void *arg)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt{
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_socketevent_t *ev;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt void *deconst_arg;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev = isc_mempool_get(disp->sepool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (ev == NULL)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt return (NULL);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DE_CONST(arg, deconst_arg);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt action, deconst_arg, socket,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt free_sevent, disp->sepool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev->result = ISC_R_UNSET;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ISC_LINK_INIT(ev, ev_link);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ISC_LIST_INIT(ev->bufferlist);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev->region.base = NULL;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev->n = 0;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev->offset = 0;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev->attributes = 0;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt return (ev);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt}
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntstatic inline void
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntfree_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (disp->failsafe_ev == ev) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff INSIST(disp->shutdown_out == 1);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff disp->shutdown_out = 0;
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_put(disp->mgr->depool, ev);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic inline dns_dispatchevent_t *
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Huntallocate_devent(dns_dispatch_t *disp) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff dns_dispatchevent_t *ev;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt ev = isc_mempool_get(disp->mgr->depool);
ce10da99834b806d5a92a6e5b4c8ff3990a4ae0fBrian Wellington if (ev == NULL)
ce10da99834b806d5a92a6e5b4c8ff3990a4ae0fBrian Wellington return (NULL);
5e589b5356a4125b5af32605dead82ab8b467c88Mark Andrews ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0,
5e589b5356a4125b5af32605dead82ab8b467c88Mark Andrews NULL, NULL, NULL, NULL, NULL);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return (ev);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉udp_exrecv(isc_task_t *task, isc_event_t *ev) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsock = ev->ev_arg;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNUSED(task);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(VALID_DISPSOCK(dispsock));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 udp_recv(ev, dispsock->disp, dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉udp_shrecv(isc_task_t *task, isc_event_t *ev) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispatch_t *disp = ev->ev_arg;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNUSED(task);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(VALID_DISPATCH(disp));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 udp_recv(ev, disp, NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff/*
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * General flow:
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff *
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson * If I/O result == CANCELED or error, free the buffer.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff *
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * If query, free the buffer, restart.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff *
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * If response:
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * Allocate event, fill in details.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * If cannot allocate, free buffer, restart.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * find target. If not found, free buffer, restart.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * if event queue is not empty, queue. else, send.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff * restart.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff */
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graffstatic void
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) {
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff dns_messageid_t id;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff isc_result_t dres;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff isc_buffer_t source;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff unsigned int flags;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispentry_t *resp = NULL;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff dns_dispatchevent_t *rev;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff unsigned int bucket;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff isc_boolean_t killit;
58efc48a9623797187726360efb57cbabd916f0dMichael Graff isc_boolean_t queue_response;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatchmgr_t *mgr;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington isc_netaddr_t netaddr;
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington int match;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_boolean_t qidlocked = ISC_FALSE;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff LOCK(&disp->lock);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr = disp->mgr;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid = mgr->qid;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(90),
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson "got packet: requests %d, buffers %d, recvs %d",
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->requests, disp->mgr->buffers, disp->recv_pending);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 /*
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * Unless the receive event was imported from a listening
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * interface, in which case the event type is
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending.
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 */
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington INSIST(disp->recv_pending != 0);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington disp->recv_pending = 0;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington }
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock != NULL &&
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (ev->result == ISC_R_CANCELED || dispsock->resp == NULL)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * dispsock->resp can be NULL if this transaction was canceled
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * just after receiving a response. Since this socket is
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * exclusively used and there should be at most one receive
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * event the canceled event should have been no effect. So
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * we can (and should) deactivate the socket right now.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 deactivate_dispsocket(disp, dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (disp->shutting_down) {
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley /*
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley * This dispatcher is shutting down.
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley */
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley free_buffer(disp, ev->region.base, ev->region.length);
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_event_free(&ev_in);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff ev = NULL;
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff killit = destroy_disp_ok(disp);
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley UNLOCK(&disp->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (killit)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(disp->task[0], &disp->ctlevent);
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley return;
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley }
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 if (dispsock != NULL) {
321b1c0501d6d97c852ae02e13bdfef6f0bbe776Automatic Updater resp = dispsock->resp;
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 id = resp->id;
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 if (ev->result != ISC_R_SUCCESS) {
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 /*
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 * This is most likely a network error on a
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 * connected socket. It makes no sense to
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 * check the address or parse the packet, but it
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 * will help to return the error to the caller.
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 */
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 goto sendresponse;
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 }
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 } else {
61facaae4eb15535e1b0cebf007500551874f133Mark Andrews free_buffer(disp, ev->region.base, ev->region.length);
61facaae4eb15535e1b0cebf007500551874f133Mark Andrews
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 UNLOCK(&disp->lock);
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 isc_event_free(&ev_in);
2f76108082f11d4979048f1c22602391c5733c88Tatuya JINMEI 神明達哉 return;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else if (ev->result != ISC_R_SUCCESS) {
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley free_buffer(disp, ev->region.base, ev->region.length);
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson if (ev->result != ISC_R_CANCELED)
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson dispatch_log(disp, ISC_LOG_ERROR,
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson "odd socket result in udp_recv(): %s",
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson isc_result_totext(ev->result));
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson UNLOCK(&disp->lock);
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson isc_event_free(&ev_in);
135b1206c96d03353ac59fde7be0053dacc6568eAndreas Gustafsson return;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington /*
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington * If this is from a blackholed address, drop it.
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington */
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington isc_netaddr_fromsockaddr(&netaddr, &ev->address);
8ed67113ec802546179294a682581faa75e890c9Andreas Gustafsson if (disp->mgr->blackhole != NULL &&
8ed67113ec802546179294a682581faa75e890c9Andreas Gustafsson dns_acl_match(&netaddr, NULL, disp->mgr->blackhole,
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews NULL, &match, NULL) == ISC_R_SUCCESS &&
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington match > 0)
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington {
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington if (isc_log_wouldlog(dns_lctx, LVL(10))) {
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington char netaddrstr[ISC_NETADDR_FORMATSIZE];
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington isc_netaddr_format(&netaddr, netaddrstr,
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington sizeof(netaddrstr));
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington dispatch_log(disp, LVL(10),
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington "blackholed packet from %s",
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington netaddrstr);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington }
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington free_buffer(disp, ev->region.base, ev->region.length);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington goto restart;
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington }
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff /*
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff * Peek into the buffer to see what we can see.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&source, ev->region.base, ev->region.length);
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff isc_buffer_add(&source, ev->n);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff dres = dns_message_peekheader(&source, &id, &flags);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (dres != ISC_R_SUCCESS) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff free_buffer(disp, ev->region.base, ev->region.length);
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson dispatch_log(disp, LVL(10), "got garbage packet");
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff goto restart;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(92),
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson "got valid DNS message header, /QR %c, id %u",
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff /*
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington * Look at flags. If query, drop it. If response,
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington * look to see where it goes.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff /* query */
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington free_buffer(disp, ev->region.base, ev->region.length);
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington goto restart;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews }
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Search for the corresponding response. If we are using an exclusive
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * socket, we've already identified it and we can skip the search; but
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * the ID and the address must match the expected ones.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews if (resp == NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 bucket = dns_hash(qid, &ev->address, id, disp->localport);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 LOCK(&qid->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 qidlocked = ISC_TRUE;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 resp = entry_search(qid, &ev->address, id, disp->localport,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 bucket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90),
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 "search for response in bucket %d: %s",
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 bucket, (resp == NULL ? "not found" : "found"));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (resp == NULL) {
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews inc_stats(mgr, dns_resstatscounter_mismatch);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 free_buffer(disp, ev->region.base, ev->region.length);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto unlock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else if (resp->id != id || !isc_sockaddr_equal(&ev->address,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 &resp->host)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90),
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 "response to an exclusive socket doesn't match");
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews inc_stats(mgr, dns_resstatscounter_mismatch);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews free_buffer(disp, ev->region.base, ev->region.length);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews goto unlock;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews }
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews /*
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * Now that we have the original dispatch the query was sent
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * from check that the address and port the response was
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * sent to make sense.
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews */
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews if (disp != resp->disp) {
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_t a1;
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_t a2;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews /*
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * Check that the socket types and ports match.
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews */
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews if (disp->socktype != resp->disp->socktype ||
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_getport(&disp->local) !=
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_getport(&resp->disp->local)) {
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews free_buffer(disp, ev->region.base, ev->region.length);
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews goto unlock;
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews }
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews /*
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * If both dispatches are bound to an address then fail as
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews * the addresses can't be equal (enforced by the IP stack).
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews *
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * Note under Linux a packet can be sent out via IPv4 socket
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * and the response be received via a IPv6 socket.
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews *
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * Requests sent out via IPv6 should always come back in
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews * via IPv6.
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews */
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 &&
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_pf(&disp->local) != PF_INET6) {
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews free_buffer(disp, ev->region.base, ev->region.length);
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews goto unlock;
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews }
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local));
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local));
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews if (!isc_sockaddr_eqaddr(&a1, &resp->disp->local) &&
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews !isc_sockaddr_eqaddr(&a2, &disp->local)) {
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews free_buffer(disp, ev->region.base, ev->region.length);
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews goto unlock;
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews }
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews }
a295fbb55cfed38bcf2853c60410cce52ab6cebbMark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sendresponse:
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews queue_response = resp->item_out;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt rev = allocate_devent(resp->disp);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews if (rev == NULL) {
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews free_buffer(disp, ev->region.base, ev->region.length);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews goto unlock;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff /*
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff * At this point, rev contains the event we want to fill in, and
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff * resp contains the information on the place to send it to.
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff * Send the event off.
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff */
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_buffer_add(&rev->buffer, ev->n);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 rev->result = ev->result;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff rev->id = id;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff rev->addr = ev->address;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff rev->pktinfo = ev->pktinfo;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff rev->attributes = ev->attributes;
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington if (queue_response) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ISC_LIST_APPEND(resp->items, rev, ev_link);
58efc48a9623797187726360efb57cbabd916f0dMichael Graff } else {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,
ae8d0aedd64a7580dc2fc4a9cd61934527552f3bMichael Graff DNS_EVENT_DISPATCH,
58efc48a9623797187726360efb57cbabd916f0dMichael Graff resp->action, resp->arg, resp, NULL, NULL);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff request_log(disp, resp, LVL(90),
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff "[a] Sent event %p buffer %p len %d to task %p",
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff rev, rev->buffer.base, rev->buffer.length,
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff resp->task);
58efc48a9623797187726360efb57cbabd916f0dMichael Graff resp->item_out = ISC_TRUE;
42b48d11ca7b296324d7a8a98cdbf0070b0deb1dMark Andrews isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
58efc48a9623797187726360efb57cbabd916f0dMichael Graff }
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews unlock:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (qidlocked)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(&qid->lock);
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff /*
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff * Restart recv() to get the next packet.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff restart:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = startrecv(disp, dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS && dispsock != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * XXX: wired. There seems to be no recovery process other than
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * deactivate this socket anyway (since we cannot start
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * receiving, we won't be able to receive a cancel event
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * from the user).
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 deactivate_dispsocket(disp, dispsock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff UNLOCK(&disp->lock);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff isc_event_free(&ev_in);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff/*
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * General flow:
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff *
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * If I/O result == CANCELED, EOF, or error, notify everyone as the
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * various queues drain.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff *
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * If query, restart.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff *
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * If response:
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * Allocate event, fill in details.
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * If cannot allocate, restart.
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 * find target. If not found, restart.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * if event queue is not empty, queue. else, send.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * restart.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graffstatic void
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencetcp_recv(isc_task_t *task, isc_event_t *ev_in) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff dns_dispatch_t *disp = ev_in->ev_arg;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dns_messageid_t id;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff isc_result_t dres;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff unsigned int flags;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dns_dispentry_t *resp;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dns_dispatchevent_t *rev;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff unsigned int bucket;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff isc_boolean_t killit;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff isc_boolean_t queue_response;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews int level;
3733c24efa7eaa65455153702c3fb71c9233eafbMark Andrews char buf[ISC_SOCKADDR_FORMATSIZE];
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff UNUSED(task);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley REQUIRE(VALID_DISPATCH(disp));
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid = disp->qid;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(90),
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson "got TCP packet: requests %d, buffers %d, recvs %d",
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->requests, disp->tcpbuffers, disp->recv_pending);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff LOCK(&disp->lock);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington INSIST(disp->recv_pending != 0);
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->recv_pending = 0;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley if (disp->refcount == 0) {
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley /*
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley * This dispatcher is shutting down. Force cancelation.
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley */
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley tcpmsg->result = ISC_R_CANCELED;
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley }
6da50be4364a17cdcd14095c0110aaa6a0566178Bob Halley
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson if (tcpmsg->result != ISC_R_SUCCESS) {
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson switch (tcpmsg->result) {
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson case ISC_R_CANCELED:
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson break;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson case ISC_R_EOF:
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson dispatch_log(disp, LVL(90), "shutting down on EOF");
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews do_cancel(disp);
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson break;
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews case ISC_R_CONNECTIONRESET:
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews level = ISC_LOG_INFO;
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews goto logit;
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson default:
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews level = ISC_LOG_ERROR;
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews logit:
3733c24efa7eaa65455153702c3fb71c9233eafbMark Andrews isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf));
0fa218cc7cf0e5aef35bb4f5228dfccc04444d90Mark Andrews dispatch_log(disp, level, "shutting down due to TCP "
3733c24efa7eaa65455153702c3fb71c9233eafbMark Andrews "receive error: %s: %s", buf,
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson isc_result_totext(tcpmsg->result));
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews do_cancel(disp);
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson break;
00010dc6a4c9591891bf565f15af17a7e06eaca2Andreas Gustafsson }
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley /*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * The event is statically allocated in the tcpmsg
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * structure, and destroy_disp() frees the tcpmsg, so we must
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * free the event *before* calling destroy_disp().
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley */
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley isc_event_free(&ev_in);
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->shutting_down = 1;
054777a694f3243f8403f54aa0907d79353ed38aAndreas Gustafsson disp->shutdown_why = tcpmsg->result;
3cd4668988c5bccd59cca899459df4cfa985be67Bob Halley
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * If the recv() was canceled pass the word on.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff killit = destroy_disp_ok(disp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&disp->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (killit)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(disp->task[0], &disp->ctlevent);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff return;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff }
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff tcpmsg->result,
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff tcpmsg->buffer.length, tcpmsg->buffer.base);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff /*
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * Peek into the buffer to see what we can see.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (dres != ISC_R_SUCCESS) {
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson dispatch_log(disp, LVL(10), "got garbage packet");
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff goto restart;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff }
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(92),
8ed2c82a73a6c0a9c04ad26a4ef39b5a738099f6Andreas Gustafsson "got valid DNS message header, /QR %c, id %u",
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff /*
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * Allocate an event to send to the query or response client, and
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * allocate a new buffer for our use.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff /*
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington * Look at flags. If query, drop it. If response,
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington * look to see where it goes.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
24675e8e132e068cbb5c6e13dc147dcba52919c4David Lawrence /*
24675e8e132e068cbb5c6e13dc147dcba52919c4David Lawrence * Query.
24675e8e132e068cbb5c6e13dc147dcba52919c4David Lawrence */
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington goto restart;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff }
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews /*
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews * Response.
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 bucket = dns_hash(qid, &tcpmsg->address, id, disp->localport);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews LOCK(&qid->lock);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 resp = entry_search(qid, &tcpmsg->address, id, disp->localport, bucket);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews dispatch_log(disp, LVL(90),
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews "search for response in bucket %d: %s",
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews bucket, (resp == NULL ? "not found" : "found"));
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews if (resp == NULL)
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews goto unlock;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews queue_response = resp->item_out;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt rev = allocate_devent(disp);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews if (rev == NULL)
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews goto unlock;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff /*
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * At this point, rev contains the event we want to fill in, and
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * resp contains the information on the place to send it to.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * Send the event off.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews disp->tcpbuffers++;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff rev->result = ISC_R_SUCCESS;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff rev->id = id;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff rev->addr = tcpmsg->address;
e618d503ba1a38fc407b071c43ded97ac59f0106Brian Wellington if (queue_response) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ISC_LIST_APPEND(resp->items, rev, ev_link);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff } else {
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff resp->action, resp->arg, resp, NULL, NULL);
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff request_log(disp, resp, LVL(90),
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff "[b] Sent event %p buffer %p len %d to task %p",
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff rev, rev->buffer.base, rev->buffer.length,
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff resp->task);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff resp->item_out = ISC_TRUE;
42b48d11ca7b296324d7a8a98cdbf0070b0deb1dMark Andrews isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff }
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews unlock:
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews UNLOCK(&qid->lock);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff /*
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff * Restart recv() to get the next packet.
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff */
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff restart:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (void)startrecv(disp, NULL);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff UNLOCK(&disp->lock);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff isc_event_free(&ev_in);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff}
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff/*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * disp must be locked.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff isc_result_t res;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff isc_region_t region;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_t *socket;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (disp->shutting_down == 1)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (disp->recv_pending != 0 && dispsock == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (disp->mgr->buffers >= disp->mgr->maxbuffers)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 socket = dispsock->socket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 socket = disp->socket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(socket != NULL);
0b14ebe3132846e91bea02992493e3d506233e76Michael Graff
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington switch (disp->socktype) {
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington /*
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington * UDP reads are always maximal.
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington */
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington case isc_sockettype_udp:
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington region.length = disp->mgr->buffersize;
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington region.base = allocate_udp_buffer(disp);
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington if (region.base == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsock != NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_task_t *dt = dispsock->task;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_socketevent_t *sev =
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt allocate_sevent(disp, socket,
ee980d3fc4c23b7f87fed96d3ba5e928937c9ed4Tinderbox User ISC_SOCKEVENT_RECVDONE,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt udp_exrecv, dispsock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (sev == NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt free_buffer(disp, region.base, region.length);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt return (ISC_R_NOMEMORY);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt res = isc_socket_recv2(socket, &region, 1, dt, sev, 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (res != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 free_buffer(disp, region.base, region.length);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (res);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_task_t *dt = disp->task[0];
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_socketevent_t *sev =
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt allocate_sevent(disp, socket,
ee980d3fc4c23b7f87fed96d3ba5e928937c9ed4Tinderbox User ISC_SOCKEVENT_RECVDONE,
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt udp_shrecv, disp);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (sev == NULL) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt free_buffer(disp, region.base, region.length);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt return (ISC_R_NOMEMORY);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt res = isc_socket_recv2(socket, &region, 1, dt, sev, 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (res != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 free_buffer(disp, region.base, region.length);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->shutdown_why = res;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->shutting_down = 1;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 do_cancel(disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS); /* recover by cancel */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(disp->recv_pending == 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->recv_pending = 1;
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington }
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington break;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington case isc_sockettype_tcp:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task[0],
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington tcp_recv, disp);
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington if (res != ISC_R_SUCCESS) {
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->shutdown_why = res;
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->shutting_down = 1;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews do_cancel(disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS); /* recover by cancel */
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
d6baaf3649ccea9c94f953f52689ae9354a07fefAndreas Gustafsson INSIST(disp->recv_pending == 0);
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->recv_pending = 1;
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews default:
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews INSIST(0);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews break;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff}
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff/*
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * Mgr must be locked when calling this function.
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffstatic isc_boolean_t
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedestroy_mgr_ok(dns_dispatchmgr_t *mgr) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr_log(mgr, LVL(90),
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, "
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt "depool=%d, rpool=%d, dpool=%d",
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_getallocated(mgr->depool),
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_getallocated(mgr->rpool),
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_getallocated(mgr->dpool));
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff if (!MGR_IS_SHUTTINGDOWN(mgr))
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (ISC_FALSE);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff if (!ISC_LIST_EMPTY(mgr->list))
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (ISC_FALSE);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (isc_mempool_getallocated(mgr->depool) != 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (isc_mempool_getallocated(mgr->rpool) != 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (isc_mempool_getallocated(mgr->dpool) != 0)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_FALSE);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (ISC_TRUE);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff/*
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * Mgr must be unlocked when calling this function.
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffstatic void
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedestroy_mgr(dns_dispatchmgr_t **mgrp) {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_t *mctx;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatchmgr_t *mgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr = *mgrp;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff *mgrp = NULL;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mctx = mgr->mctx;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr->magic = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->mctx = NULL;
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&mgr->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr->state = 0;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 DESTROYLOCK(&mgr->arc4_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_destroy(&mgr->depool);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_destroy(&mgr->rpool);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_destroy(&mgr->dpool);
000a8970f840a0c27c5cc404826853c4674362acMark Andrews if (mgr->bpool != NULL)
000a8970f840a0c27c5cc404826853c4674362acMark Andrews isc_mempool_destroy(&mgr->bpool);
000a8970f840a0c27c5cc404826853c4674362acMark Andrews if (mgr->spool != NULL)
000a8970f840a0c27c5cc404826853c4674362acMark Andrews isc_mempool_destroy(&mgr->spool);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->spool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->bpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->dpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->rpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->depool_lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff if (mgr->entropy != NULL)
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff isc_entropy_detach(&mgr->entropy);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif /* BIND9 */
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews if (mgr->qid != NULL)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews qid_destroy(mctx, &mgr->qid);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews DESTROYLOCK(&mgr->buffer_lock);
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington if (mgr->blackhole != NULL)
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington dns_acl_detach(&mgr->blackhole);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews if (mgr->stats != NULL)
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 isc_stats_detach(&mgr->stats);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->v4ports != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mctx, mgr->v4ports,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv4ports * sizeof(in_port_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->v6ports != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mctx, mgr->v6ports,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv6ports * sizeof(in_port_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_detach(&mctx);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_result_t
240e53b13217af266abb3dae8ba103614daf2bf7Mark Andrewsopen_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int options, isc_socket_t **sockp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t *dup_socket)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_socket_t *sock;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_result_t result;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sock = *sockp;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (sock != NULL) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_socket_open(sock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#else
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 INSIST(0);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt } else if (dup_socket != NULL) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = isc_socket_dup(dup_socket, &sock);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (result != ISC_R_SUCCESS)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt return (result);
23daf8948b2e5462ccea082a441e9759dffa50cdMark Andrews
23daf8948b2e5462ccea082a441e9759dffa50cdMark Andrews isc_socket_setname(sock, "dispatcher", NULL);
23daf8948b2e5462ccea082a441e9759dffa50cdMark Andrews *sockp = sock;
23daf8948b2e5462ccea082a441e9759dffa50cdMark Andrews return (ISC_R_SUCCESS);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt } else {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = isc_socket_create(mgr, isc_sockaddr_pf(local),
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_sockettype_udp, &sock);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (result != ISC_R_SUCCESS)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_setname(sock, "dispatcher", NULL);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
ef29912666cc6160f7165558bef017ab3849c5e1Mark Andrews#ifndef ISC_ALLOW_MAPPED
ef29912666cc6160f7165558bef017ab3849c5e1Mark Andrews isc_socket_ipv6only(sock, ISC_TRUE);
ef29912666cc6160f7165558bef017ab3849c5e1Mark Andrews#endif
240e53b13217af266abb3dae8ba103614daf2bf7Mark Andrews result = isc_socket_bind(sock, local, options);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (*sockp == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&sock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 else {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_close(sock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#else
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 INSIST(0);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *sockp = sock;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_R_SUCCESS);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉/*%
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Create a temporary port list to set the initial default set of dispatch
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * ports: [1024, 65535]. This is almost meaningless as the application will
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * normally set the ports explicitly, but is provided to fill some minor corner
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * cases.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_result_t result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_portset_create(mctx, portsetp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_addrange(*portsetp, 1024, 65535);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff/*
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff * Publics.
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff */
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graffisc_result_t
80617c8faa03b2c425e320597eb768073fd0b987Michael Graffdns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff dns_dispatchmgr_t **mgrp)
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff{
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatchmgr_t *mgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_result_t result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_t *v4portset = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_t *v6portset = NULL;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(mctx != NULL);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(mgrp != NULL && *mgrp == NULL);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff if (mgr == NULL)
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (ISC_R_NOMEMORY);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr->mctx = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mem_attach(mctx, &mgr->mctx);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington mgr->blackhole = NULL;
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews mgr->stats = NULL;
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff result = isc_mutex_init(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff goto deallocate;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_mutex_init(&mgr->arc4_lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff goto kill_lock;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_mutex_init(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto kill_arc4_lock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&mgr->depool_lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (result != ISC_R_SUCCESS)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews goto kill_buffer_lock;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&mgr->rpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (result != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_depool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&mgr->dpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (result != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_rpool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&mgr->bpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (result != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_dpool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&mgr->spool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (result != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_bpool_lock;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt mgr->depool = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt &mgr->depool) != ISC_R_SUCCESS) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff result = ISC_R_NOMEMORY;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_spool_lock;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr->rpool = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff &mgr->rpool) != ISC_R_SUCCESS) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff result = ISC_R_NOMEMORY;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_depool;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr->dpool = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t),
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff &mgr->dpool) != ISC_R_SUCCESS) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff result = ISC_R_NOMEMORY;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff goto kill_rpool;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff }
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setname(mgr->depool, "dispmgr_depool");
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setmaxalloc(mgr->depool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->depool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(mgr->depool, &mgr->depool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(mgr->depool, 32);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_setname(mgr->rpool, "dispmgr_rpool");
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setmaxalloc(mgr->rpool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->rpool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(mgr->rpool, 32);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_setname(mgr->dpool, "dispmgr_dpool");
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setmaxalloc(mgr->dpool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->dpool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(mgr->dpool, 32);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->buffers = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->buffersize = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->maxbuffers = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->bpool = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->spool = NULL;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->entropy = NULL;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->qid = NULL;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr->state = 0;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LIST_INIT(mgr->list);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->v4ports = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->v6ports = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv4ports = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv6ports = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->magic = DNS_DISPATCHMGR_MAGIC;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = create_default_portset(mctx, &v4portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result == ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = create_default_portset(mctx, &v6portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result == ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = dns_dispatchmgr_setavailports(mgr,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v4portset,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v6portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (v4portset != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_destroy(mctx, &v4portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (v6portset != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_destroy(mctx, &v6portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto kill_dpool;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#ifdef BIND9
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff if (entropy != NULL)
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff isc_entropy_attach(entropy, &mgr->entropy);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#else
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 UNUSED(entropy);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#endif
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff *mgrp = mgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (ISC_R_SUCCESS);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 kill_dpool:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_destroy(&mgr->dpool);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff kill_rpool:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_destroy(&mgr->rpool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_depool:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_destroy(&mgr->depool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_spool_lock:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->spool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_bpool_lock:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->bpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_dpool_lock:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->dpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_rpool_lock:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->rpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_depool_lock:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt DESTROYLOCK(&mgr->depool_lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews kill_buffer_lock:
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews DESTROYLOCK(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 kill_arc4_lock:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 DESTROYLOCK(&mgr->arc4_lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff kill_lock:
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff deallocate:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
ddc592d128cdde85ada64efbda95981c10c4c03cMark Andrews isc_mem_detach(&mctx);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellingtonvoid
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellingtondns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) {
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington REQUIRE(VALID_DISPATCHMGR(mgr));
02e38214502c3a946cdfe87e16525747617a1150Brian Wellington if (mgr->blackhole != NULL)
02e38214502c3a946cdfe87e16525747617a1150Brian Wellington dns_acl_detach(&mgr->blackhole);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington dns_acl_attach(blackhole, &mgr->blackhole);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington}
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
97f26b88f62b10a9c26a91ebe8387d2e498c2d00Andreas Gustafssondns_acl_t *
97f26b88f62b10a9c26a91ebe8387d2e498c2d00Andreas Gustafssondns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington REQUIRE(VALID_DISPATCHMGR(mgr));
97f26b88f62b10a9c26a91ebe8387d2e498c2d00Andreas Gustafsson return (mgr->blackhole);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington}
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrewsvoid
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrewsdns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews dns_portlist_t *portlist)
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews{
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews REQUIRE(VALID_DISPATCHMGR(mgr));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNUSED(portlist);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* This function is deprecated: use dns_dispatchmgr_setavailports(). */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return;
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews}
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrewsdns_portlist_t *
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrewsdns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) {
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews REQUIRE(VALID_DISPATCHMGR(mgr));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (NULL); /* this function is deprecated */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_t *v6portset)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉{
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *v4ports, *v6ports, p;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nv4ports, nv6ports, i4, i6;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(VALID_DISPATCHMGR(mgr));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nv4ports = isc_portset_nports(v4portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nv6ports = isc_portset_nports(v6portset);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v4ports = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (nv4ports != 0) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v4ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv4ports);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (v4ports == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v6ports = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (nv6ports != 0) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v6ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv6ports);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (v6ports == NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (v4ports != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mgr->mctx, v4ports,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sizeof(in_port_t) *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_portset_nports(v4portset));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 p = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 i4 = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 i6 = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 do {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_portset_isset(v4portset, p)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(i4 < nv4ports);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v4ports[i4++] = p;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_portset_isset(v6portset, p)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(i6 < nv6ports);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 v6ports[i6++] = p;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } while (p++ < 65535);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(i4 == nv4ports && i6 == nv6ports);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 PORTBUFLOCK(mgr);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->v4ports != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mgr->mctx, mgr->v4ports,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv4ports * sizeof(in_port_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->v4ports = v4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv4ports = nv4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->v6ports != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mgr->mctx, mgr->v6ports,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv6ports * sizeof(in_port_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->v6ports = v6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr->nv6ports = nv6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 PORTBUFUNLOCK(mgr);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_SUCCESS);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews}
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsstatic isc_result_t
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsdns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int buffersize, unsigned int maxbuffers,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int maxrequests, unsigned int buckets,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int increment)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews{
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_result_t result;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(VALID_DISPATCHMGR(mgr));
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(maxbuffers > 0);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(increment > buckets);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews /*
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * Keep some number of items around. This should be a config
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * option. For now, keep 8, but later keep at least two even
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * if the caller wants less. This allows us to ensure certain
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * things, like an event can be "freed" and the next allocation
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * will always succeed.
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews *
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * Note that if limits are placed on anything here, we use one
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * event internally, so the actual limit should be "wanted + 1."
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews *
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * XXXMLG
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews */
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (maxbuffers < 8)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews maxbuffers = 8;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews LOCK(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* Create or adjust buffer pool */
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (mgr->bpool != NULL) {
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews /*
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * We only increase the maxbuffers to avoid accidental buffer
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * shortage. Ideally we'd separate the manager-wide maximum
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * from per-dispatch limits and respect the latter within the
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * global limit. But at this moment that's deemed to be
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * overkilling and isn't worth additional implementation
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews * complexity.
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews */
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews if (maxbuffers > mgr->maxbuffers) {
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->bpool, maxbuffers);
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews mgr->maxbuffers = maxbuffers;
2a0d4c4d6ba5addb33cd1bccecc55ca4a095f191Mark Andrews }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_setname(mgr->bpool, "dispmgr_bpool");
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->bpool, maxbuffers);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(mgr->bpool, 32);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* Create or adjust socket pool */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->spool != NULL) {
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2) {
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt isc_mempool_setmaxalloc(mgr->spool,
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt DNS_DISPATCH_POOLSOCKS * 2);
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt isc_mempool_setfreemax(mgr->spool,
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt DNS_DISPATCH_POOLSOCKS * 2);
970aa7d783b004d0f665d7107260a823a0d2a645Evan Hunt }
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNLOCK(&mgr->buffer_lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews return (ISC_R_SUCCESS);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_mempool_create(mgr->mctx, sizeof(dispsocket_t),
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 &mgr->spool);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS) {
b11a1ea7d1bdf76e927d14c956d60939932185b4Mark Andrews UNLOCK(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto cleanup;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_setname(mgr->spool, "dispmgr_spool");
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_setmaxalloc(mgr->spool, maxrequests);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(mgr->spool, maxrequests);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(mgr->spool, &mgr->spool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(mgr->spool, 32);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = qid_allocate(mgr, buckets, increment, &mgr->qid, ISC_TRUE);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (result != ISC_R_SUCCESS)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews goto cleanup;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->buffersize = buffersize;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews mgr->maxbuffers = maxbuffers;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNLOCK(&mgr->buffer_lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews return (ISC_R_SUCCESS);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews cleanup:
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mempool_destroy(&mgr->bpool);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (mgr->spool != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_destroy(&mgr->spool);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNLOCK(&mgr->buffer_lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffvoid
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatchmgr_t *mgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_boolean_t killit;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(mgrp != NULL);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(VALID_DISPATCHMGR(*mgrp));
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr = *mgrp;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff *mgrp = NULL;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff LOCK(&mgr->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff mgr->state |= MGR_SHUTTINGDOWN;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff killit = destroy_mgr_ok(mgr);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff UNLOCK(&mgr->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr_log(mgr, LVL(90), "destroy: killit=%d", killit);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff if (killit)
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff destroy_mgr(&mgr);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrewsvoid
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) {
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews REQUIRE(VALID_DISPATCHMGR(mgr));
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews REQUIRE(ISC_LIST_EMPTY(mgr->list));
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews REQUIRE(mgr->stats == NULL);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 isc_stats_attach(stats, &mgr->stats);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews}
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static int
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉port_cmp(const void *key, const void *ent) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t p1 = *(const in_port_t *)key;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t p2 = *(const in_port_t *)ent;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (p1 < p2)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (-1);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else if (p1 == p2)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (1);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrewsstatic isc_boolean_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_t *sockaddrp)
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews{
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews isc_sockaddr_t sockaddr;
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews isc_result_t result;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *ports, port;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_boolean_t available = ISC_FALSE;
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews REQUIRE(sock != NULL || sockaddrp != NULL);
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 PORTBUFLOCK(mgr);
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews if (sock != NULL) {
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews sockaddrp = &sockaddr;
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews result = isc_socket_getsockname(sock, sockaddrp);
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto unlock;
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews }
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_sockaddr_pf(sockaddrp) == AF_INET) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = mgr->v4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = mgr->nv4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = mgr->v6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = mgr->nv6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (ports == NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto unlock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 port = isc_sockaddr_getport(sockaddrp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (bsearch(&port, ports, nports, sizeof(in_port_t), port_cmp) != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 available = ISC_TRUE;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉unlock:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 PORTBUFUNLOCK(mgr);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (available);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graffstatic isc_boolean_t
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencelocal_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews isc_sockaddr_t sockaddr;
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews isc_result_t result;
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉 REQUIRE(disp->socket != NULL);
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff if (addr == NULL)
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff return (ISC_TRUE);
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Don't match wildcard ports unless the port is available in the
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉 * current configuration.
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_sockaddr_getport(addr) == 0 &&
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews isc_sockaddr_getport(&disp->local) == 0 &&
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 !portavailable(disp->mgr, disp->socket, NULL)) {
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews return (ISC_FALSE);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews /*
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews * Check if we match the binding <address,port>.
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews * Wildcard ports match/fail here.
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews */
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews if (isc_sockaddr_equal(&disp->local, addr))
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews return (ISC_TRUE);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews if (isc_sockaddr_getport(addr) == 0)
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews return (ISC_FALSE);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews /*
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews * Check if we match a bound wildcard port <address,port>.
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews */
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews if (!isc_sockaddr_eqaddr(&disp->local, addr))
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews return (ISC_FALSE);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews result = isc_socket_getsockname(disp->socket, &sockaddr);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews if (result != ISC_R_SUCCESS)
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews return (ISC_FALSE);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews
455bb19b5dbf5dce6e625349acf5018fc4823adbTatuya JINMEI 神明達哉 return (isc_sockaddr_equal(&sockaddr, addr));
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff}
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Requires mgr be locked.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * No dispatcher can be locked by this thread when calling this function.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * NOTE:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * If a matching dispatcher is found, it is locked after this function
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * returns, and must be unlocked by the caller.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_result_t
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int attributes, unsigned int mask,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t **dispp)
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff{
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatch_t *disp;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_result_t result;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉 * Make certain that we will not match a private or exclusive dispatch.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉 attributes &= ~(DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE);
2a03c0af765860308edb715be012d4bc743c47f1Tatuya JINMEI 神明達哉 mask |= (DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff disp = ISC_LIST_HEAD(mgr->list);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff while (disp != NULL) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff LOCK(&disp->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if ((disp->shutting_down == 0)
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff && ATTRMATCH(disp->attributes, attributes, mask)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff && local_addr_match(disp, local))
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff break;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&disp->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff disp = ISC_LIST_NEXT(disp, link);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff }
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff if (disp == NULL) {
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff result = ISC_R_NOTFOUND;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff goto out;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff }
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *dispp = disp;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff result = ISC_R_SUCCESS;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff out:
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff return (result);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewsstatic isc_result_t
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsqid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int increment, dns_qid_t **qidp,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 isc_boolean_t needsocktable)
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews{
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews unsigned int i;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews isc_result_t result;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(VALID_DISPATCHMGR(mgr));
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews REQUIRE(increment > buckets);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews REQUIRE(qidp != NULL && *qidp == NULL);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews qid = isc_mem_get(mgr->mctx, sizeof(*qid));
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews if (qid == NULL)
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews return (ISC_R_NOMEMORY);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews qid->qid_table = isc_mem_get(mgr->mctx,
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews buckets * sizeof(dns_displist_t));
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews if (qid->qid_table == NULL) {
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mem_put(mgr->mctx, qid, sizeof(*qid));
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews return (ISC_R_NOMEMORY);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews }
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 qid->sock_table = NULL;
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (needsocktable) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 qid->sock_table = isc_mem_get(mgr->mctx, buckets *
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 sizeof(dispsocketlist_t));
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (qid->sock_table == NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mem_put(mgr->mctx, qid->qid_table,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 buckets * sizeof(dns_displist_t));
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews isc_mem_put(mgr->mctx, qid, sizeof(*qid));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_NOMEMORY);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
07072c9456f1112705db701bb35f12dbdcb217b0Mark Andrews }
07072c9456f1112705db701bb35f12dbdcb217b0Mark Andrews
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews result = isc_mutex_init(&qid->lock);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews if (result != ISC_R_SUCCESS) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (qid->sock_table != NULL) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 isc_mem_put(mgr->mctx, qid->sock_table,
b55dc7da2e2d1b92e92fdb5da8991d73dcfc6819Tatuya JINMEI 神明達哉 buckets * sizeof(dispsocketlist_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mem_put(mgr->mctx, qid->qid_table,
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews buckets * sizeof(dns_displist_t));
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mem_put(mgr->mctx, qid, sizeof(*qid));
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews return (result);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews }
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < buckets; i++) {
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ISC_LIST_INIT(qid->qid_table[i]);
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (qid->sock_table != NULL)
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 ISC_LIST_INIT(qid->sock_table[i]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid->qid_nbuckets = buckets;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid->qid_increment = increment;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid->magic = QID_MAGIC;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews *qidp = qid;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews return (ISC_R_SUCCESS);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews}
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrewsstatic void
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsqid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) {
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews REQUIRE(qidp != NULL);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid = *qidp;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews REQUIRE(VALID_QID(qid));
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews *qidp = NULL;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid->magic = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mem_put(mctx, qid->qid_table,
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid->qid_nbuckets * sizeof(dns_displist_t));
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (qid->sock_table != NULL) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 isc_mem_put(mctx, qid->sock_table,
b55dc7da2e2d1b92e92fdb5da8991d73dcfc6819Tatuya JINMEI 神明達哉 qid->qid_nbuckets * sizeof(dispsocketlist_t));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews DESTROYLOCK(&qid->lock);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_mem_put(mctx, qid, sizeof(*qid));
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews}
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Allocate and set important limits.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_result_t
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrewsdispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews dns_dispatch_t **dispp)
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff{
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff dns_dispatch_t *disp;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews isc_result_t result;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(VALID_DISPATCHMGR(mgr));
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff REQUIRE(dispp != NULL && *dispp == NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Set up the dispatcher, mostly. Don't bother setting some of
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * the options that are controlled by tcp vs. udp, etc.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp = isc_mempool_get(mgr->dpool);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff if (disp == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp->magic = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->mgr = mgr;
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff disp->maxrequests = maxrequests;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->attributes = 0;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LINK_INIT(disp, link);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp->refcount = 1;
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington disp->recv_pending = 0;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson memset(&disp->local, 0, sizeof(disp->local));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->localport = 0;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff disp->shutting_down = 0;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff disp->shutdown_out = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->connected = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->tcpmsg_valid = 0;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff disp->shutdown_why = ISC_R_UNEXPECTED;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff disp->requests = 0;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews disp->tcpbuffers = 0;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews disp->qid = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_INIT(disp->activesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_INIT(disp->inactivesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->nsockets = 0;
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews disp->port_table = NULL;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews disp->portpool = NULL;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews result = isc_mutex_init(&disp->lock);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews if (result != ISC_R_SUCCESS)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews goto deallocate;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt disp->failsafe_ev = allocate_devent(disp);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (disp->failsafe_ev == NULL) {
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews result = ISC_R_NOMEMORY;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews goto kill_lock;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp->magic = DISPATCH_MAGIC;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *dispp = disp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_R_SUCCESS);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * error returns
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff kill_lock:
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&disp->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff deallocate:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_put(mgr->dpool, disp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
584848087f7463c1f659ce4712dc047d8e7f2b07Francis Dupont * MUST be unlocked, and not used by anything.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic void
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdispatch_free(dns_dispatch_t **dispp)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatchmgr_t *mgr;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews int i;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCH(*dispp));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp = *dispp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *dispp = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr = disp->mgr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCHMGR(mgr));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (disp->tcpmsg_valid) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_tcpmsg_invalidate(&disp->tcpmsg);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->tcpmsg_valid = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews INSIST(disp->tcpbuffers == 0);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff INSIST(disp->requests == 0);
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington INSIST(disp->recv_pending == 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(ISC_LIST_EMPTY(disp->activesockets));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(ISC_LIST_EMPTY(disp->inactivesockets));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_put(mgr->depool, disp->failsafe_ev);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->failsafe_ev = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews if (disp->qid != NULL)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews qid_destroy(mgr->mctx, &disp->qid);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (disp->port_table != NULL) {
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews INSIST(ISC_LIST_EMPTY(disp->port_table[i]));
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mem_put(mgr->mctx, disp->port_table,
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews sizeof(disp->port_table[0]) *
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews DNS_DISPATCH_PORTTABLESIZE);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (disp->portpool != NULL)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mempool_destroy(&disp->portpool);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->mgr = NULL;
3a62e221b429920a3990a3ddb9eae276593a5708Brian Wellington DESTROYLOCK(&disp->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->magic = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_put(mgr->dpool, disp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffisc_result_t
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr, unsigned int buffersize,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int maxbuffers, unsigned int maxrequests,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int buckets, unsigned int increment,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int attributes, dns_dispatch_t **dispp)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_result_t result;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNUSED(maxbuffers);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews UNUSED(buffersize);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCHMGR(mgr));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0);
24675e8e132e068cbb5c6e13dc147dcba52919c4David Lawrence REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff LOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * dispatch_allocate() checks mgr for us.
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * qid_allocate() checks buckets and increment for us.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp = NULL;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews result = dispatch_allocate(mgr, maxrequests, &disp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = qid_allocate(mgr, buckets, increment, &disp->qid, ISC_FALSE);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (result != ISC_R_SUCCESS)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews goto deallocate_dispatch;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
ce5bd92088923d1c76e26d313d1d8c0b8bbe38feMichael Graff disp->socktype = isc_sockettype_tcp;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff disp->socket = NULL;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff isc_socket_attach(sock, &disp->socket);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt disp->sepool = NULL;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->ntasks = 1;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->task[0] = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_task_create(taskmgr, 0, &disp->task[0]);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff goto kill_socket;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington DNS_EVENT_DISPATCHCONTROL,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington destroy_disp, disp,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington sizeof(isc_event_t));
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews if (disp->ctlevent == NULL) {
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews result = ISC_R_NOMEMORY;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington goto kill_task;
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_setname(disp->task[0], "tcpdispatch", disp);
11a91ac55e118bfab7cacf3422fea474457b8542Andreas Gustafsson
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->tcpmsg_valid = 1;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->attributes = attributes;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff /*
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff * Append it to the dispatcher list.
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LIST_APPEND(mgr->list, disp, link);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff UNLOCK(&mgr->lock);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90), "created task %p", disp->task[0]);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff *dispp = disp;
8d1943e8ffa991d54c5406342e44d7134762e7eaMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Error returns.
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff */
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington kill_task:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_detach(&disp->task[0]);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff kill_socket:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_socket_detach(&disp->socket);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews deallocate_dispatch:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dispatch_free(&disp);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffisc_result_t
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Huntdns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int buffersize,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int maxbuffers, unsigned int maxrequests,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int buckets, unsigned int increment,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff unsigned int attributes, unsigned int mask,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dns_dispatch_t **dispp, dns_dispatch_t *dup_dispatch)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_result_t result;
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews dns_dispatch_t *disp = NULL;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCHMGR(mgr));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(sockmgr != NULL);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(localaddr != NULL);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(taskmgr != NULL);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(maxbuffers > 0);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(increment > buckets);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(dispp != NULL && *dispp == NULL);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 maxrequests, buckets, increment);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews if (result != ISC_R_SUCCESS)
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews return (result);
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff LOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews REQUIRE(isc_sockaddr_getport(localaddr) == 0);
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews goto createudp;
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews }
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews * See if we have a dispatcher that matches.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (dup_dispatch == NULL) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = dispatch_find(mgr, localaddr, attributes, mask, &disp);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (result == ISC_R_SUCCESS) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt disp->refcount++;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (disp->maxrequests < maxrequests)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt disp->maxrequests = maxrequests;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (disp->recv_pending != 0)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_cancel(disp->socket,
2f17ad4545ca552c92c88f7cb1e2525050c10c67Automatic Updater disp->task[0],
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt ISC_SOCKCANCEL_RECV);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt UNLOCK(&disp->lock);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt UNLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt *dispp = disp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt return (ISC_R_SUCCESS);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
281bab0f36eaedc56f859721fbdf45568b71cd60Mark Andrews createudp:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Nope, create one.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt maxrequests, attributes, &disp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dup_dispatch == NULL
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt ? NULL
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt : dup_dispatch->socket);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS) {
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff UNLOCK(&mgr->lock);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *dispp = disp;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (ISC_R_SUCCESS);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff}
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Huntisc_result_t
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Huntdns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int buffersize,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int maxbuffers, unsigned int maxrequests,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int buckets, unsigned int increment,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt unsigned int attributes, unsigned int mask,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dns_dispatch_t **dispp)
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt{
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt return dns_dispatch_getudp_dup(mgr, sockmgr, taskmgr, localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt buffersize, maxbuffers, maxrequests, buckets, increment,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt attributes, mask, dispp, NULL);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt}
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * mgr should be locked.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews#ifndef DNS_DISPATCH_HELD
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews#define DNS_DISPATCH_HELD 20U
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews#endif
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t **sockp, isc_socket_t *dup_socket)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉{
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int i, j;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_t *held[DNS_DISPATCH_HELD];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_t localaddr_bound;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_t *sock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_result_t result = ISC_R_SUCCESS;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_boolean_t anyport;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(sockp != NULL && *sockp == NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 localaddr_bound = *localaddr;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 anyport = ISC_TF(isc_sockaddr_getport(localaddr) == 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (anyport) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int nports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t *ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * If no port is specified, we first try to pick up a random
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * port by ourselves.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (isc_sockaddr_pf(&disp->local) == AF_INET) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = disp->mgr->nv4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = disp->mgr->v4ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports = disp->mgr->nv6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ports = disp->mgr->v6ports;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (nports == 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (ISC_R_ADDRNOTAVAIL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < 1024; i++) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t prt;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 prt = ports[dispatch_uniformrandom(
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 DISP_ARC4CTX(disp),
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 nports)];
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_setport(&localaddr_bound, prt);
9de0f9b0aed432ee357dbba8d1d807525f4b6d4aMark Andrews result = open_socket(sockmgr, &localaddr_bound,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt 0, &sock, NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result == ISC_R_SUCCESS ||
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result != ISC_R_ADDRINUSE) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->localport = prt;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *sockp = sock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * If this fails 1024 times, we then ask the kernel for
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * choosing one.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews } else {
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews /* Allow to reuse address for non-random ports. */
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews result = open_socket(sockmgr, localaddr,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt ISC_SOCKET_REUSEADDRESS, &sock,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dup_socket);
a8a8e73121d807438a90ec61eff1b72b55fc7bc8Automatic Updater
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews if (result == ISC_R_SUCCESS)
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews *sockp = sock;
a8a8e73121d807438a90ec61eff1b72b55fc7bc8Automatic Updater
92241b04f16e1095a53f2c75e7987381dd0773afMark Andrews return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 memset(held, 0, sizeof(held));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 i = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
a4037b279b13cc3f5b73d2f42e9c893cea2a6734Tatuya JINMEI 神明達哉 for (j = 0; j < 0xffffU; j++) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto end;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else if (!anyport)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 break;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else if (portavailable(mgr, sock, NULL))
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 break;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (held[i] != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&held[i]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 held[i++] = sock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 sock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (i == DNS_DISPATCH_HELD)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 i = 0;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
a4037b279b13cc3f5b73d2f42e9c893cea2a6734Tatuya JINMEI 神明達哉 if (j == 0xffffU) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 mgr_log(mgr, ISC_LOG_ERROR,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 "avoid-v%s-udp-ports: unable to allocate "
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 "an available port",
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_sockaddr_pf(localaddr) == AF_INET ? "4" : "6");
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = ISC_R_FAILURE;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto end;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 *sockp = sock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉end:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < DNS_DISPATCH_HELD; i++) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (held[i] != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&held[i]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffstatic isc_result_t
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr,
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews isc_sockaddr_t *localaddr,
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews unsigned int maxrequests,
80617c8faa03b2c425e320597eb768073fd0b987Michael Graff unsigned int attributes,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dns_dispatch_t **dispp,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_socket_t *dup_socket)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_result_t result;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews isc_socket_t *sock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 int i = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews * dispatch_allocate() checks mgr for us.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp = NULL;
8affb49a70de247206cb04aae87730f2b4c90dd0Mark Andrews result = dispatch_allocate(mgr, maxrequests, &disp);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (result != ISC_R_SUCCESS)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt dup_socket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
7076f000ea3487299a9da9318915d042aaba62c5Mark Andrews goto deallocate_dispatch;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt if (isc_log_wouldlog(dns_lctx, 90)) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt char addrbuf[ISC_SOCKADDR_FORMATSIZE];
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt isc_sockaddr_format(localaddr, addrbuf,
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt ISC_SOCKADDR_FORMATSIZE);
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt mgr_log(mgr, LVL(90), "dns_dispatch_createudp: Created"
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt " UDP dispatch for %s with socket fd %d\n",
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt addrbuf, isc_socket_getfd(sock));
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt }
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 } else {
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 isc_sockaddr_t sa_any;
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 /*
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 * For dispatches using exclusive sockets with a specific
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 * source address, we only check if the specified address is
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 * available on the system. Query sockets will be created later
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 * on demand.
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 */
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr));
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) {
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 if (sock != NULL)
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 isc_socket_detach(&sock);
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS)
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 goto deallocate_dispatch;
ebacb7908afe3d62fe341f7ef9efed63d0c651a2Tatuya JINMEI 神明達哉 }
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews disp->port_table = isc_mem_get(mgr->mctx,
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews sizeof(disp->port_table[0]) *
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews DNS_DISPATCH_PORTTABLESIZE);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (disp->port_table == NULL)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews goto deallocate_dispatch;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews ISC_LIST_INIT(disp->port_table[i]);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t),
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews &disp->portpool);
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews if (result != ISC_R_SUCCESS)
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews goto deallocate_dispatch;
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mempool_setname(disp->portpool, "disp_portpool");
96b3cb85d3b06d99323a6ea7ae04f4eb3d74e8bcMark Andrews isc_mempool_setfreemax(disp->portpool, 128);
b312748a11d27fe387984973ba79975a9d6863c4Mark Andrews }
ce5bd92088923d1c76e26d313d1d8c0b8bbe38feMichael Graff disp->socktype = isc_sockettype_udp;
13b53c29715e36e1b9318c956a8ba08cc90e3832Andreas Gustafsson disp->socket = sock;
13b53c29715e36e1b9318c956a8ba08cc90e3832Andreas Gustafsson disp->local = *localaddr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->ntasks = MAX_INTERNAL_TASKS;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->ntasks = 1;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < disp->ntasks; i++) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->task[i] = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = isc_task_create(taskmgr, 0, &disp->task[i]);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 while (--i >= 0) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_task_shutdown(disp->task[i]);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_task_detach(&disp->task[i]);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 goto kill_socket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_setname(disp->task[i], "udpdispatch", disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington DNS_EVENT_DISPATCHCONTROL,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington destroy_disp, disp,
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington sizeof(isc_event_t));
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews if (disp->ctlevent == NULL) {
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews result = ISC_R_NOMEMORY;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington goto kill_task;
25e2824175eb0c186df3ab0737c83d322410594cMark Andrews }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt disp->sepool = NULL;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t),
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt &disp->sepool) != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = ISC_R_NOMEMORY;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_ctlevent;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = isc_mutex_init(&disp->sepool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt if (result != ISC_R_SUCCESS)
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt goto kill_sepool;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setname(disp->sepool, "disp_sepool");
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setmaxalloc(disp->sepool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfreemax(disp->sepool, 32768);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_associatelock(disp->sepool, &disp->sepool_lock);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_setfillcount(disp->sepool, 16);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff attributes &= ~DNS_DISPATCHATTR_TCP;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff attributes |= DNS_DISPATCHATTR_UDP;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->attributes = attributes;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Append it to the dispatcher list.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff ISC_LIST_APPEND(mgr->list, disp, link);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (disp->socket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90), "created socket %p", disp->socket);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff *dispp = disp;
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff /*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * Error returns.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_sepool:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_mempool_destroy(&disp->sepool);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt kill_ctlevent:
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt isc_event_free(&disp->ctlevent);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington kill_task:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (i = 0; i < disp->ntasks; i++)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_detach(&disp->task[i]);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff kill_socket:
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (disp->socket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_detach(&disp->socket);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff deallocate_dispatch:
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dispatch_free(&disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff return (result);
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff}
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graffvoid
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) {
2743e0ce08d1decc963908f024007078d4a553acMichael Graff REQUIRE(VALID_DISPATCH(disp));
2743e0ce08d1decc963908f024007078d4a553acMichael Graff REQUIRE(dispp != NULL && *dispp == NULL);
2743e0ce08d1decc963908f024007078d4a553acMichael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff LOCK(&disp->lock);
2743e0ce08d1decc963908f024007078d4a553acMichael Graff disp->refcount++;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff UNLOCK(&disp->lock);
2743e0ce08d1decc963908f024007078d4a553acMichael Graff
2743e0ce08d1decc963908f024007078d4a553acMichael Graff *dispp = disp;
2743e0ce08d1decc963908f024007078d4a553acMichael Graff}
2743e0ce08d1decc963908f024007078d4a553acMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff/*
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * It is important to lock the manager while we are deleting the dispatch,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * since dns_dispatch_getudp will call dispatch_find, which returns to
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * the caller a dispatch but does not attach to it until later. _getudp
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * locks the manager, however, so locking it here will keep us from attaching
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff * to a dispatcher that is in the process of going away.
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff */
2743e0ce08d1decc963908f024007078d4a553acMichael Graffvoid
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatch_detach(dns_dispatch_t **dispp) {
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff dns_dispatch_t *disp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsock;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff isc_boolean_t killit;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp = *dispp;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff *dispp = NULL;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff LOCK(&disp->lock);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff INSIST(disp->refcount > 0);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp->refcount--;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff if (disp->refcount == 0) {
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington if (disp->recv_pending > 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(disp->socket, disp->task[0],
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_SOCKCANCEL_RECV);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (dispsock = ISC_LIST_HEAD(disp->activesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock != NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = ISC_LIST_NEXT(dispsock, link)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(dispsock->socket, dispsock->task,
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff ISC_SOCKCANCEL_RECV);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->shutting_down = 1;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff }
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff killit = destroy_disp_ok(disp);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff UNLOCK(&disp->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (killit)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(disp->task[0], &disp->ctlevent);
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff}
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graffisc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_t *task, isc_taskaction_t action, void *arg,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_messageid_t *idp, dns_dispentry_t **resp,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socketmgr_t *sockmgr)
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff{
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff dns_dispentry_t *res;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff unsigned int bucket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 in_port_t localport = 0;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff dns_messageid_t id;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff int i;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff isc_boolean_t ok;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsocket = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_result_t result;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(VALID_DISPATCH(disp));
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(task != NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(dest != NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(resp != NULL && *resp == NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(idp != NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(sockmgr != NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff LOCK(&disp->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
3446e5e9327ed3595f7a9403f9944666f4820f2aMichael Graff if (disp->shutting_down == 1) {
3446e5e9327ed3595f7a9403f9944666f4820f2aMichael Graff UNLOCK(&disp->lock);
3446e5e9327ed3595f7a9403f9944666f4820f2aMichael Graff return (ISC_R_SHUTTINGDOWN);
3446e5e9327ed3595f7a9403f9944666f4820f2aMichael Graff }
3446e5e9327ed3595f7a9403f9944666f4820f2aMichael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff if (disp->requests >= disp->maxrequests) {
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff UNLOCK(&disp->lock);
04135883be6700d7c9f489e4db9cb6c147b064caMichael Graff return (ISC_R_QUOTA);
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff }
6fe411037dafd168a9f65e6b254c50f3db616688Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *oldestsocket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispentry_t *oldestresp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_dispatchevent_t *rev;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Kill oldest outstanding query if the number of sockets
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * exceeds the quota to keep the room for new queries.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 oldestsocket = ISC_LIST_HEAD(disp->activesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 oldestresp = oldestsocket->resp;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (oldestresp != NULL && !oldestresp->item_out) {
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt rev = allocate_devent(oldestresp->disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (rev != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 rev->buffer.base = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 rev->result = ISC_R_CANCELED;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 rev->id = oldestresp->id;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_EVENT_INIT(rev, sizeof(*rev), 0,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 NULL, DNS_EVENT_DISPATCH,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 oldestresp->action,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 oldestresp->arg, oldestresp,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 NULL, NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 oldestresp->item_out = ISC_TRUE;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(oldestresp->task,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_EVENT_PTR(&rev));
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews inc_stats(disp->mgr,
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews dns_resstatscounter_dispabort);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Move this entry to the tail so that it won't (easily) be
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * examined before actually being canceled.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(disp->activesockets, oldestsocket, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_APPEND(disp->activesockets, oldestsocket, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 qid = DNS_QID(disp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Get a separate UDP socket with a random port number.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt result = get_dispsocket(disp, dest, sockmgr, &dispsocket,
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 &localport);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(&disp->lock);
f19e6ef1eb7d5abf547fc1af24e561bdc5d75b22Mark Andrews inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 localport = disp->localport;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff /*
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff * Try somewhat hard to find an unique ID.
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff */
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt LOCK(&qid->lock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 bucket = dns_hash(qid, dest, id, localport);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff ok = ISC_FALSE;
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (i = 0; i < 64; i++) {
e2fe1fda755f24f593406dc26fed87e8ea1bb502Tatuya JINMEI 神明達哉 if (entry_search(qid, dest, id, localport, bucket) == NULL) {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff ok = ISC_TRUE;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff break;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff }
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews id += qid->qid_increment;
607dc8013a8cb34cd03b59292aa1ac01e008c9c1Michael Graff id &= 0x0000ffff;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 bucket = dns_hash(qid, dest, id, localport);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff }
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt UNLOCK(&qid->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff if (!ok) {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff UNLOCK(&disp->lock);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMORE);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff }
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff res = isc_mempool_get(disp->mgr->rpool);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff if (res == NULL) {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff UNLOCK(&disp->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsocket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsocket);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff }
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff disp->refcount++;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff disp->requests++;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff res->task = NULL;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff isc_task_attach(task, &res->task);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff res->disp = disp;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff res->id = id;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res->port = localport;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff res->bucket = bucket;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff res->host = *dest;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff res->action = action;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff res->arg = arg;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res->dispsocket = dispsocket;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsocket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket->resp = res;
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff res->item_out = ISC_FALSE;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff ISC_LIST_INIT(res->items);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff ISC_LINK_INIT(res, link);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff res->magic = RESPONSE_MAGIC;
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt LOCK(&qid->lock);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews UNLOCK(&qid->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff request_log(disp, res, LVL(90),
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff "attached to task %p", res->task);
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) ||
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = startrecv(disp, dispsocket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (result != ISC_R_SUCCESS) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 LOCK(&qid->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(&qid->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsocket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 destroy_dispsocket(disp, &dispsocket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->refcount--;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 disp->requests--;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 UNLOCK(&disp->lock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_detach(&res->task);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_mempool_put(disp->mgr->rpool, res);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (result);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (dispsocket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_LIST_APPEND(disp->activesockets, dispsocket, link);
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff UNLOCK(&disp->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff *idp = id;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff *resp = res;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(res->dispsocket != NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff}
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉isc_result_t
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_t *task, isc_taskaction_t action, void *arg,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dns_messageid_t *idp, dns_dispentry_t **resp)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉{
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater REQUIRE(VALID_DISPATCH(disp));
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (dns_dispatch_addresponse2(disp, dest, task, action, arg,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 idp, resp, NULL));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrewsvoid
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrewsdns_dispatch_starttcp(dns_dispatch_t *disp) {
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews REQUIRE(VALID_DISPATCH(disp));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]);
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews LOCK(&disp->lock);
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (void)startrecv(disp, NULL);
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews UNLOCK(&disp->lock);
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews}
3c671ac666de8a7dcd7bd02afa20968da0b85bbdMark Andrews
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graffvoid
46993e1d9d18410a5852b7d990338b70b158855cMichael Graffdns_dispatch_removeresponse(dns_dispentry_t **resp,
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff dns_dispatchevent_t **sockevent)
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff{
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatchmgr_t *mgr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_t *disp;
ab0e5066083abcbec62513a3cc041d1f1eb9098aMichael Graff dns_dispentry_t *res;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsocket_t *dispsock;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff dns_dispatchevent_t *ev;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff unsigned int bucket;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff isc_boolean_t killit;
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley unsigned int n;
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley isc_eventlist_t events;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(resp != NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(VALID_RESPONSE(*resp));
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff res = *resp;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff *resp = NULL;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp = res->disp;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCH(disp));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff mgr = disp->mgr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(VALID_DISPATCHMGR(mgr));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid = DNS_QID(disp);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff if (sockevent != NULL) {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff REQUIRE(*sockevent != NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff ev = *sockevent;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff *sockevent = NULL;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff } else {
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff ev = NULL;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff }
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff LOCK(&disp->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff INSIST(disp->requests > 0);
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff disp->requests--;
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff INSIST(disp->refcount > 0);
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff disp->refcount--;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff if (disp->refcount == 0) {
f98d6edb191348477c9c5a156003df627d9bc42cBrian Wellington if (disp->recv_pending > 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(disp->socket, disp->task[0],
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 ISC_SOCKCANCEL_RECV);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 for (dispsock = ISC_LIST_HEAD(disp->activesockets);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock != NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispsock = ISC_LIST_NEXT(dispsock, link)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(dispsock->socket, dispsock->task,
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff ISC_SOCKCANCEL_RECV);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff disp->shutting_down = 1;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff }
54a64ec428cb9f783d62a044cbec3a72724a937cMichael Graff
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff bucket = res->bucket;
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews LOCK(&qid->lock);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews UNLOCK(&qid->lock);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley if (ev == NULL && res->item_out) {
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley /*
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley * We've posted our event, but the caller hasn't gotten it
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley * yet. Take it back.
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley */
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley ISC_LIST_INIT(events);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH,
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley NULL, &events);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley /*
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley * We had better have gotten it back.
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley */
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley INSIST(n == 1);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley }
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (ev != NULL) {
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff REQUIRE(res->item_out == ISC_TRUE);
58efc48a9623797187726360efb57cbabd916f0dMichael Graff res->item_out = ISC_FALSE;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff if (ev->buffer.base != NULL)
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff free_buffer(disp, ev->buffer.base, ev->buffer.length);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt free_devent(disp, ev);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff }
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff request_log(disp, res, LVL(90), "detaching from task %p", res->task);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley isc_task_detach(&res->task);
6d58c9b95ec40eb38533061eefab6cb256e870e6Bob Halley
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (res->dispsocket != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(res->dispsocket->socket,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res->dispsocket->task, ISC_SOCKCANCEL_RECV);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 res->dispsocket->resp = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff /*
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff * Free any buffered requests as well
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff */
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff ev = ISC_LIST_HEAD(res->items);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff while (ev != NULL) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ISC_LIST_UNLINK(res->items, ev, ev_link);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff if (ev->buffer.base != NULL)
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff free_buffer(disp, ev->buffer.base, ev->buffer.length);
54489ba1672458382e8dfb5490fcfc7230f8ea85Evan Hunt free_devent(disp, ev);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff ev = ISC_LIST_HEAD(res->items);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff }
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff res->magic = 0;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_mempool_put(disp->mgr->rpool, res);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff if (disp->shutting_down == 1)
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews do_cancel(disp);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (void)startrecv(disp, NULL);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff killit = destroy_disp_ok(disp);
a8dcebd0419f27234664e89b9cd48bc54cad08a7Michael Graff UNLOCK(&disp->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (killit)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(disp->task[0], &disp->ctlevent);
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff}
83f8c56f43852bf9a9c6964eae285284b23f9d8dMichael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graffstatic void
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrewsdo_cancel(dns_dispatch_t *disp) {
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff dns_dispatchevent_t *ev;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews dns_dispentry_t *resp;
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews dns_qid_t *qid;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff if (disp->shutdown_out == 1)
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff return;
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews qid = DNS_QID(disp);
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * Search for the first response handler without packets outstanding
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * unless a specific hander is given.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff */
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews LOCK(&qid->lock);
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews for (resp = linear_first(qid);
a9579d3386009446d7527ef52fa28251ab8c3c2cTatuya JINMEI 神明達哉 resp != NULL && resp->item_out;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews /* Empty. */)
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews resp = linear_next(qid, resp);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff /*
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff * No one to send the cancel event to, so nothing to do.
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff */
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff if (resp == NULL)
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews goto unlock;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff /*
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff * Send the shutdown failsafe event to this resp.
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff */
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff ev = disp->failsafe_ev;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff resp->action, resp->arg, resp, NULL, NULL);
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff ev->result = disp->shutdown_why;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff ev->buffer.base = NULL;
d1ba6e9180c7d7458656a6e53e52fde056fd244cMichael Graff ev->buffer.length = 0;
c6066a8e67f40c7c12925c5634485f55713c06d6Michael Graff disp->shutdown_out = 1;
20c266cbc999c724e03e6edd437fb4181b92f095Michael Graff request_log(disp, resp, LVL(10),
97a195d7ff64f78b32dbfde0edb8109fc800ee02Andreas Gustafsson "cancel: failsafe event %p -> task %p",
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff ev, resp->task);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff resp->item_out = ISC_TRUE;
42b48d11ca7b296324d7a8a98cdbf0070b0deb1dMark Andrews isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews unlock:
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews UNLOCK(&qid->lock);
1ec39fc7a8b6ad92de3363d4c50b75e24fcd6accMichael Graff}
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graffisc_socket_t *
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatch_getsocket(dns_dispatch_t *disp) {
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff REQUIRE(VALID_DISPATCH(disp));
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff return (disp->socket);
c16cc434ef385a870bea53eb7ecfea7da8eb562dMichael Graff}
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉isc_socket_t *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_dispatch_getentrysocket(dns_dispentry_t *resp) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(VALID_RESPONSE(resp));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (resp->dispsocket != NULL)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (resp->dispsocket->socket);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 else
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrewsisc_result_t
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrewsdns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) {
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews REQUIRE(VALID_DISPATCH(disp));
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews REQUIRE(addrp != NULL);
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews if (disp->socktype == isc_sockettype_udp) {
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews *addrp = disp->local;
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews return (ISC_R_SUCCESS);
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews }
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews return (ISC_R_NOTIMPLEMENTED);
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews}
a674e7ececfd787f0c3e7a6dc36f7f79ba1ddab9Mark Andrews
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graffvoid
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatch_cancel(dns_dispatch_t *disp) {
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff REQUIRE(VALID_DISPATCH(disp));
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff LOCK(&disp->lock);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff if (disp->shutting_down == 1) {
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff UNLOCK(&disp->lock);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff return;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff }
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff disp->shutdown_why = ISC_R_CANCELED;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff disp->shutting_down = 1;
d8c2b1787119de43dd6b7e3927ff193ed5df682fMark Andrews do_cancel(disp);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff UNLOCK(&disp->lock);
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff return;
6f1422b81ed2c5142092e2ced8e3faf0e61f3ba0Michael Graff}
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉unsigned int
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉dns_dispatch_getattributes(dns_dispatch_t *disp) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE(VALID_DISPATCH(disp));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * We don't bother locking disp here; it's the caller's responsibility
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * to use only non volatile flags.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 return (disp->attributes);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffvoid
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graffdns_dispatch_changeattributes(dns_dispatch_t *disp,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff unsigned int attributes, unsigned int mask)
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff{
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff REQUIRE(VALID_DISPATCH(disp));
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* Exclusive attribute can only be set on creation */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /* Also, a dispatch with randomport specified cannot start listening */
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0 ||
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0);
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff /* XXXMLG
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff * Should check for valid attributes here!
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff */
ca0db0cdc8ad7c771c4922b8220ebafde953904eMichael Graff
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff LOCK(&disp->lock);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) {
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 &&
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) {
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 (void)startrecv(disp, NULL);
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 } else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN)
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 == 0 &&
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) {
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 if (disp->recv_pending != 0)
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_socket_cancel(disp->socket, disp->task[0],
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 ISC_SOCKCANCEL_RECV);
e992af4209b737f511b6f2fad3ddb7bdfc17b9aeTatuya JINMEI 神明達哉 }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff disp->attributes &= ~mask;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff disp->attributes |= (attributes & mask);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff UNLOCK(&disp->lock);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff}
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellingtonvoid
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellingtondns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) {
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington void *buf;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington isc_socketevent_t *sevent, *newsevent;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington REQUIRE(VALID_DISPATCH(disp));
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0);
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington REQUIRE(event != NULL);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington sevent = (isc_socketevent_t *)event;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington INSIST(sevent->n <= disp->mgr->buffersize);
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent = (isc_socketevent_t *)
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington isc_event_allocate(disp->mgr->mctx, NULL,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 DNS_EVENT_IMPORTRECVDONE, udp_shrecv,
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington disp, sizeof(isc_socketevent_t));
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington if (newsevent == NULL)
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington return;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington buf = allocate_udp_buffer(disp);
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington if (buf == NULL) {
42b48d11ca7b296324d7a8a98cdbf0070b0deb1dMark Andrews isc_event_free(ISC_EVENT_PTR(&newsevent));
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington return;
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington }
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington memcpy(buf, sevent->region.base, sevent->n);
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->region.base = buf;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->region.length = disp->mgr->buffersize;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->n = sevent->n;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->result = sevent->result;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->address = sevent->address;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->timestamp = sevent->timestamp;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->pktinfo = sevent->pktinfo;
319d2971f1f10ded49e2325e2f8e7f24ea37a708Brian Wellington newsevent->attributes = sevent->attributes;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent));
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington}
35f06ab0e6d5ad26176b7584de7b4d405272ba68Brian Wellington
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntdns_dispatch_t *
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntdns_dispatchset_get(dns_dispatchset_t *dset) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatch_t *disp;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt /* check that dispatch set is configured */
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (dset == NULL || dset->ndisp == 0)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt return (NULL);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt LOCK(&dset->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt disp = dset->dispatches[dset->cur];
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->cur++;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (dset->cur == dset->ndisp)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->cur = 0;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt UNLOCK(&dset->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt return (disp);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt}
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntisc_result_t
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntdns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatchset_t **dsetp, int n)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt{
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_result_t result;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatchset_t *dset;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatchmgr_t *mgr;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt int i, j;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt REQUIRE(VALID_DISPATCH(source));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt REQUIRE(dsetp != NULL && *dsetp == NULL);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt mgr = source->mgr;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (dset == NULL)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt return (ISC_R_NOMEMORY);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt memset(dset, 0, sizeof(*dset));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt result = isc_mutex_init(&dset->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (result != ISC_R_SUCCESS)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt goto fail_alloc;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (dset == NULL) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt result = ISC_R_NOMEMORY;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt goto fail_lock;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt }
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_attach(mctx, &dset->mctx);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->ndisp = n;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->cur = 0;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->dispatches[0] = NULL;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatch_attach(source, &dset->dispatches[0]);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt LOCK(&mgr->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt for (i = 1; i < n; i++) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset->dispatches[i] = NULL;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt result = dispatch_createudp(mgr, sockmgr, taskmgr,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt &source->local,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt source->maxrequests,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt source->attributes,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt &dset->dispatches[i],
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt source->socket);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (result != ISC_R_SUCCESS)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt goto fail;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt }
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt UNLOCK(&mgr->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt *dsetp = dset;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt return (ISC_R_SUCCESS);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt fail:
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt UNLOCK(&mgr->lock);
ee980d3fc4c23b7f87fed96d3ba5e928937c9ed4Tinderbox User
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt for (j = 0; j < i; j++)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatch_detach(&(dset->dispatches[j]));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt if (dset->mctx == mctx)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_detach(&dset->mctx);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt fail_lock:
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt DESTROYLOCK(&dset->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt fail_alloc:
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt return (result);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt}
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntvoid
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntdns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt int i;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt REQUIRE(dset != NULL);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt for (i = 0; i < dset->ndisp; i++) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_socket_t *sock;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt sock = dns_dispatch_getsocket(dset->dispatches[i]);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt }
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt}
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntvoid
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Huntdns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatchset_t *dset;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt int i;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt REQUIRE(dsetp != NULL && *dsetp != NULL);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dset = *dsetp;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt for (i = 0; i < dset->ndisp; i++)
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt dns_dispatch_detach(&(dset->dispatches[i]));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_put(dset->mctx, dset->dispatches,
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt sizeof(dns_dispatch_t *) * dset->ndisp);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt DESTROYLOCK(&dset->lock);
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt *dsetp = NULL;
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt}
4e8fe357a619ae2b789b15df7e3d6abf782b4a71Evan Hunt
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff#if 0
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graffvoid
3d181bc9f12154a56bfbb536198a6c481cbcd525David Lawrencedns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) {
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff dns_dispatch_t *disp;
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff char foo[1024];
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff disp = ISC_LIST_HEAD(mgr->list);
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff while (disp != NULL) {
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_sockaddr_format(&disp->local, foo, sizeof(foo));
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff printf("\tdispatch %p, addr %s\n", disp, foo);
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff disp = ISC_LIST_NEXT(disp, link);
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff }
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff}
b9c8f4378ae98056ca4244b6d454baff85f4bc2aMichael Graff#endif