dispatch.c revision c6066a8e67f40c7c12925c5634485f55713c06d6
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*
9d5ed744c46ef241b9d3ba134bf3155e0b62ac9eAutomatic Updater * Copyright (C) 1999 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * copyright notice and this permission notice appear in all copies.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * SOFTWARE.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
e4d304b70b81ca9956c2eff7c24aacf4dd00266eEvan Hunt#include <config.h>
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <ctype.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <stdio.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <stdlib.h>
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <string.h>
519b239fc4ef1e070e2da182a4ea559ae0152151Mark Andrews
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/assertions.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/error.h>
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews#include <isc/mem.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley#include <isc/mutex.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/socket.h>
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
1c776a2909632bc755f3fddd3b53addd792ab4d0Brian Wellington#include <dns/events.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <dns/types.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/result.h>
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson#include <dns/dispatch.h>
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington#include <dns/message.h>
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#include <dns/tcpmsg.h>
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include "../isc/util.h"
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley/*
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence * If we cannot send to this task, the application is broken.
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington */
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#define ISC_TASK_SEND(a, b) do { \
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence RUNTIME_CHECK(isc_task_send(a, b) == ISC_R_SUCCESS); \
e419f613d8591885df608cb73065921be07dd12eBob Halley} while (0)
e419f613d8591885df608cb73065921be07dd12eBob Halley
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#ifdef DISPATCH_DEBUG
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define XDEBUG(x) printf x
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#else
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define XDEBUG(x)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#endif
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstruct dns_dispentry {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int magic;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_messageid_t id;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater unsigned int bucket;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_sockaddr_t host;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_task_t *task;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_taskaction_t action;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews void *arg;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_boolean_t item_out;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LIST(dns_dispatchevent_t) items;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LINK(dns_dispentry_t) link;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews};
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define INVALID_BUCKET (0xffffdead)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewstypedef ISC_LIST(dns_dispentry_t) dns_displist_t;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstruct dns_dispatch {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /* Unlocked. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int magic; /* magic */
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews isc_mem_t *mctx; /* memory context */
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews isc_task_t *task; /* internal task */
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews isc_socket_t *socket; /* isc socket attached to */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int buffersize; /* size of each buffer */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int maxrequests; /* max requests */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int maxbuffers; /* max buffers */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /* Locked. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_mutex_t lock; /* locks all below */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int refcount; /* number of users */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_mempool_t *epool; /* memory pool for events */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_mempool_t *bpool; /* memory pool for buffers */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_mempool_t *rpool; /* memory pool request/reply */
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence dns_dispatchevent_t *failsafe_ev; /* failsafe cancel event */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int recvs; /* recv() calls outstanding */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley unsigned int recvs_wanted; /* recv() calls wanted */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int shutting_down : 1,
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews shutdown_out : 1;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_result_t shutdown_why;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int requests; /* how many requests we have */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int buffers; /* allocated buffers */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LIST(dns_dispentry_t) rq_handlers; /* request handler list */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_LIST(dns_dispatchevent_t) rq_events; /* holder for rq events */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_tcpmsg_t tcpmsg; /* for tcp streams */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_int32_t qid_state; /* state generator info */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int qid_hashsize; /* hash table size */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int qid_mask; /* mask for hash table */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_displist_t *qid_table; /* the table itself */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews};
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define REQUEST_MAGIC 0x53912051 /* "random" value */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define VALID_REQUEST(e) ((e) != NULL && (e)->magic == REQUEST_MAGIC)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define RESPONSE_MAGIC 0x15021935 /* "random" value */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define VALID_RESPONSE(e) ((e) != NULL && (e)->magic == RESPONSE_MAGIC)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define DISPATCH_MAGIC 0x69385829 /* "random" value */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define VALID_DISPATCH(e) ((e) != NULL && (e)->magic == DISPATCH_MAGIC)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews/*
50105afc551903541608b11851d73278b23579a3Mark Andrews * statics.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic dns_dispentry_t *
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrewsbucket_search(dns_dispatch_t *, isc_sockaddr_t *,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_messageid_t, unsigned int);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencedestroy(dns_dispatch_t *);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsstatic void
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrenceudp_recv(isc_task_t *, isc_event_t *);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic void
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencetcp_recv(isc_task_t *, isc_event_t *);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
50105afc551903541608b11851d73278b23579a3Mark Andrewsstartrecv(dns_dispatch_t *);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic dns_messageid_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsrandomid(dns_dispatch_t *);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic unsigned int
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrewshash(dns_dispatch_t *, isc_sockaddr_t *, dns_messageid_t);
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencestatic void
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonfree_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic void *
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonallocate_buffer(dns_dispatch_t *disp, unsigned int len);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencestatic inline void
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonfree_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafssonstatic inline dns_dispatchevent_t *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsallocate_event(dns_dispatch_t *disp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdo_next_request(dns_dispatch_t *disp, dns_dispentry_t *resp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrewsstatic void
50105afc551903541608b11851d73278b23579a3Mark Andrewsdo_next_response(dns_dispatch_t *disp, dns_dispentry_t *resp);
50105afc551903541608b11851d73278b23579a3Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic void
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdo_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsstatic dns_dispentry_t *
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewslinear_first(dns_dispatch_t *disp);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic dns_dispentry_t *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewslinear_next(dns_dispatch_t *disp, dns_dispentry_t *resp);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic dns_dispentry_t *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewslinear_first(dns_dispatch_t *disp)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews{
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_dispentry_t *ret;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews unsigned int bucket;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews bucket = 0;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews while (bucket < disp->qid_hashsize) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews ret = ISC_LIST_HEAD(disp->qid_table[bucket]);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (ret != NULL)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ret);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley bucket++;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington}
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic dns_dispentry_t *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleylinear_next(dns_dispatch_t *disp, dns_dispentry_t *resp)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_dispentry_t *ret;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned int bucket;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ret = ISC_LIST_NEXT(resp, link);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff if (ret != NULL)
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff return (ret);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff bucket = resp->bucket;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley while (bucket < disp->qid_hashsize) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ret = ISC_LIST_HEAD(disp->qid_table[bucket]);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (ret != NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ret);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews bucket++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Return a hash of the destination and message id. For now, just return
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * the message id bits, and mask off the low order bits of that.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic unsigned int
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewshash(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t id)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int ret;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews (void)dest; /* shut up compiler warning. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ret = id;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ret &= disp->qid_mask;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews INSIST(ret < disp->qid_hashsize);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ret);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews/*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Return a random message ID. For now this isn't too clever...
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * XXXMLG
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic dns_messageid_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrandomid(dns_dispatch_t *disp)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews disp->qid_state += 7;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return ((dns_messageid_t)disp->qid_state);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews/*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Called when refcount reaches 0 (and safe to destroy)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsstatic void
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsdestroy(dns_dispatch_t *disp)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_dispatchevent_t *ev;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews disp->magic = 0;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_tcpmsg_invalidate(&disp->tcpmsg);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_socket_detach(&disp->socket);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_task_detach(&disp->task);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Final cleanup of packets on the request list.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ev = ISC_LIST_HEAD(disp->rq_events);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews while (ev != NULL) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ISC_LIST_UNLINK(disp->rq_events, ev, link);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington free_buffer(disp, ev->buffer.base, ev->buffer.length);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington free_event(disp, ev);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ev = ISC_LIST_HEAD(disp->rq_events);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington INSIST(disp->buffers == 0);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington INSIST(disp->requests == 0);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington INSIST(disp->recvs == 0);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff isc_mempool_put(disp->epool, disp->failsafe_ev);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington disp->failsafe_ev = NULL;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_mempool_destroy(&disp->rpool);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_mempool_destroy(&disp->bpool);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_mempool_destroy(&disp->epool);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews isc_mem_put(disp->mctx, disp->qid_table,
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews disp->qid_hashsize * sizeof(dns_displist_t));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews isc_mem_put(disp->mctx, disp, sizeof(dns_dispatch_t));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews}
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellingtonstatic dns_dispentry_t *
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellingtonbucket_search(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t id,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington unsigned int bucket)
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington{
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington dns_dispentry_t *res;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(bucket < disp->qid_hashsize);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews res = ISC_LIST_HEAD(disp->qid_table[bucket]);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson while (res != NULL) {
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington if ((res->id == id) && isc_sockaddr_equal(dest, &res->host))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (res);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington XDEBUG(("lengths (%d, %d), ids (%d, %d)\n",
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dest->length, res->host.length,
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington res->id, id));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington res = ISC_LIST_NEXT(res, link);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (NULL);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic void
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellingtonfree_buffer(dns_dispatch_t *disp, void *buf, unsigned int len)
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson{
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson isc_sockettype_t socktype;
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(disp->buffers > 0);
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington disp->buffers--;
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington socktype = isc_socket_gettype(disp->socket);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews switch (socktype) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington case isc_socket_tcp:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_mem_put(disp->mctx, buf, len);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case isc_socket_udp:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington XDEBUG(("Freeing buffer %p, length %d, into %s, %d remain\n",
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews buf, len,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews (len == disp->buffersize ? "mempool" : "mctx"),
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->buffers));
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (len == disp->buffersize)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_mempool_put(disp->bpool, buf);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_mem_put(disp->mctx, buf, len);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington break;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington default:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(1);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonstatic void *
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonallocate_buffer(dns_dispatch_t *disp, unsigned int len)
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington{
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington void *temp;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington INSIST(len > 0);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (len == disp->buffersize)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews temp = isc_mempool_get(disp->bpool);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews else
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews temp = isc_mem_get(disp->mctx, len);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (temp != NULL) {
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews disp->buffers++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington XDEBUG(("Allocated buffer %p, length %d, from %s, %d total\n",
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington temp, len,
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington (len == disp->buffersize ? "mempool" : "mctx"),
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington disp->buffers));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews return (temp);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews}
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsfree_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
50105afc551903541608b11851d73278b23579a3Mark Andrews if (disp->failsafe_ev == ev) {
50105afc551903541608b11851d73278b23579a3Mark Andrews INSIST(disp->shutdown_out == 1);
50105afc551903541608b11851d73278b23579a3Mark Andrews disp->shutdown_out = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return;
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews }
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington isc_mempool_put(disp->epool, ev);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews
a05f23d07e1b60a1d88119678111a47014480611Mark Andrewsstatic inline dns_dispatchevent_t *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsallocate_event(dns_dispatch_t *disp)
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews{
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington dns_dispatchevent_t *ev;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington ev = isc_mempool_get(disp->epool);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ev);
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington}
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington/*
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington * General flow:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington * If I/O result == CANCELED, free the buffer and notify everyone as
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * the various queues drain.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If I/O is error (not canceled and not success) log it, free the buffer,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * and restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If query:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * if no listeners: free the buffer, restart.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * if listener: allocate event, fill in details.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If cannot allocate, free buffer, restart.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * if rq event queue is not empty, queue. else, send.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * restart.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If response:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Allocate event, fill in details.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If cannot allocate, free buffer, restart.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * find target. If not found, free buffer, restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * if event queue is not empty, queue. else, send.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsudp_recv(isc_task_t *task, isc_event_t *ev_in)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_dispatch_t *disp = ev_in->arg;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_messageid_t id;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_result_t dres;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_t source;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int flags;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_dispentry_t *resp;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_dispatchevent_t *rev;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int bucket;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington isc_boolean_t killit;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews isc_boolean_t queue_request;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews isc_boolean_t queue_response;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews (void)task; /* shut up compiler */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews XDEBUG(("Got packet!\n"));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(disp->recvs > 0);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews disp->recvs--;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (ev->result != ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews * If the recv() was canceled pass the word on.
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews */
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (ev->result == ISC_R_CANCELED) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews free_buffer(disp, ev->region.base, ev->region.length);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews killit = ISC_FALSE;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (disp->recvs == 0 && disp->refcount == 0)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews killit = ISC_TRUE;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews UNLOCK(&disp->lock);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (killit)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews destroy(disp);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews isc_event_free(&ev_in);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews * otherwise, on strange error, log it and restart.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * XXXMLG
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews free_buffer(disp, ev->region.base, ev->region.length);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews goto restart;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews XDEBUG(("length == %d, buflen = %d, addr = %p\n",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ev->n, ev->region.length, ev->region.base));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * Peek into the buffer to see what we can see.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_buffer_init(&source, ev->region.base, ev->region.length,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_BUFFERTYPE_BINARY);
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews isc_buffer_add(&source, ev->n);
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews dres = dns_message_peekheader(&source, &id, &flags);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dres != DNS_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews free_buffer(disp, ev->region.base, ev->region.length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews XDEBUG(("dns_message_peekheader(): %s\n",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_totext(dres)));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* XXXMLG log something here... */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews goto restart;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews XDEBUG(("Got valid DNS message header, /QR %c, id %d\n",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Allocate an event to send to the query or response client, and
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington * allocate a new buffer for our use.
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Look at flags. If query, check to see if we have someone handling
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * them. If response, look to see where it goes.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington queue_request = ISC_FALSE;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington queue_response = ISC_FALSE;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington resp = ISC_LIST_HEAD(disp->rq_handlers);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (resp != NULL) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (resp->item_out == ISC_FALSE)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington break;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington resp = ISC_LIST_NEXT(resp, link);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington }
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff if (resp == NULL)
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington queue_request = ISC_TRUE;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington rev = allocate_event(disp);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington if (rev == NULL) {
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington free_buffer(disp, ev->region.base, ev->region.length);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington goto restart;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* query */
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington } else {
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington /* response */
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington bucket = hash(disp, &ev->address, id);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson resp = bucket_search(disp, &ev->address, id, bucket);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington XDEBUG(("Search for response in bucket %d: %s\n",
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews bucket, (resp == NULL ? "NOT FOUND" : "FOUND")));
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (resp == NULL) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson free_buffer(disp, ev->region.base, ev->region.length);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson goto restart;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington queue_response = resp->item_out;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington rev = allocate_event(disp);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (rev == NULL) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington free_buffer(disp, ev->region.base, ev->region.length);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington goto restart;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington }
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson /*
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson * At this point, rev contains the event we want to fill in, and
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington * resp contains the information on the place to send it to.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Send the event off.
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_BUFFERTYPE_BINARY);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_add(&rev->buffer, ev->n);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rev->result = DNS_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rev->id = id;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rev->addr = ev->address;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (queue_request) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LIST_APPEND(disp->rq_events, rev, link);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews } else if (queue_response) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LIST_APPEND(resp->items, rev, link);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews resp->action, resp->arg, resp, NULL, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews XDEBUG(("Sent event for buffer %p (len %d) to task %p\n",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rev->buffer.base, rev->buffer.length, resp->task));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews resp->item_out = ISC_TRUE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_TASK_SEND(resp->task, (isc_event_t **)&rev);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Restart recv() to get the next packet.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews restart:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews startrecv(disp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_event_free(&ev_in);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * General flow:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews * If I/O result == CANCELED, free the buffer and notify everyone as
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews * the various queues drain.
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If I/O is error (not canceled and not success) log it, free the buffer,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * and restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * If query:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * if no listeners: free the buffer, restart.
50105afc551903541608b11851d73278b23579a3Mark Andrews * if listener: allocate event, fill in details.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If cannot allocate, free buffer, restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * if rq event queue is not empty, queue. else, send.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If response:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Allocate event, fill in details.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If cannot allocate, free buffer, restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * find target. If not found, free buffer, restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * if event queue is not empty, queue. else, send.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * restart.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellingtontcp_recv(isc_task_t *task, isc_event_t *ev_in)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington{
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_dispatch_t *disp = ev_in->arg;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_messageid_t id;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_result_t dres;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int flags;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_dispentry_t *resp;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_dispatchevent_t *rev;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int bucket;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t killit;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t queue_request;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t queue_response;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington (void)task; /* shut up compiler */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington XDEBUG(("Got TCP packet!\n"));
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 LOCK(&disp->lock);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews INSIST(disp->recvs > 0);
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews disp->recvs--;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington switch (tcpmsg->result) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews case ISC_R_SUCCESS:
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews break;
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews case ISC_R_EOF:
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews XDEBUG(("Shutting down on EOF\n"));
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews disp->shutdown_why = ISC_R_EOF;
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington disp->shutting_down = 1;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson do_cancel(disp, NULL);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews /* FALLTHROUGH */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews case ISC_R_CANCELED:
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * If the recv() was canceled pass the word on.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews killit = ISC_FALSE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (disp->recvs == 0 && disp->refcount == 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews killit = ISC_TRUE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&disp->lock);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (killit)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews destroy(disp);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_event_free(&ev_in);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews default:
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * otherwise, on strange error, log it and restart.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * XXXMLG
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews goto restart;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews }
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews XDEBUG(("result %d, length == %d, addr = %p\n",
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews tcpmsg->result,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews tcpmsg->buffer.length, tcpmsg->buffer.base));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Peek into the buffer to see what we can see.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (dres != DNS_R_SUCCESS) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews XDEBUG(("dns_message_peekheader(): %s\n",
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews isc_result_totext(dres)));
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews /* XXXMLG log something here... */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews goto restart;
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews }
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews XDEBUG(("Got valid DNS message header, /QR %c, id %d\n",
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * Allocate an event to send to the query or response client, and
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * allocate a new buffer for our use.
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews */
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews /*
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * Look at flags. If query, check to see if we have someone handling
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * them. If response, look to see where it goes.
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews */
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews queue_request = ISC_FALSE;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews queue_response = ISC_FALSE;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews resp = ISC_LIST_HEAD(disp->rq_handlers);
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews while (resp != NULL) {
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews if (resp->item_out == ISC_FALSE)
676619a22fbc760875adb00b58aaef6a22ced18aMark Andrews break;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp = ISC_LIST_NEXT(resp, link);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (resp == NULL)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews queue_request = ISC_TRUE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev = allocate_event(disp);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (rev == NULL)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews goto restart;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /* query */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /* response */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews bucket = hash(disp, &tcpmsg->address, id);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp = bucket_search(disp, &tcpmsg->address, id, bucket);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews XDEBUG(("Search for response in bucket %d: %s\n",
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews bucket, (resp == NULL ? "NOT FOUND" : "FOUND")));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (resp == NULL)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews goto restart;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews queue_response = resp->item_out;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev = allocate_event(disp);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (rev == NULL)
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson goto restart;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * At this point, rev contains the event we want to fill in, and
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * resp contains the information on the place to send it to.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Send the event off.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews disp->buffers++;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev->result = DNS_R_SUCCESS;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev->id = id;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev->addr = tcpmsg->address;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (queue_request) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_LIST_APPEND(disp->rq_events, rev, link);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else if (queue_response) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_LIST_APPEND(resp->items, rev, link);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp->action, resp->arg, resp, NULL, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews XDEBUG(("Sent event for buffer %p (len %d) to task %p\n",
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rev->buffer.base, rev->buffer.length, resp->task));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp->item_out = ISC_TRUE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_TASK_SEND(resp->task, (isc_event_t **)&rev);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Restart recv() to get the next packet.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews restart:
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews startrecv(disp);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews UNLOCK(&disp->lock);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_event_free(&ev_in);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews/*
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * disp must be locked
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
95b484c9580d06eb2f9735a22e9841389c2859baMark Andrewsstatic void
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsstartrecv(dns_dispatch_t *disp)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews{
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_sockettype_t socktype;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_result_t res;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_region_t region;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int wanted;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (disp->shutting_down == 1)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews wanted = ISC_MIN(disp->recvs_wanted, disp->requests + 2);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (wanted == 0)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (disp->recvs >= wanted)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (disp->buffers >= disp->maxbuffers)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
216030f2849b0812910fbc1817ca17208a112663Mark Andrews socktype = isc_socket_gettype(disp->socket);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington while (disp->recvs < wanted) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews switch (socktype) {
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington /*
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington * UDP reads are always maximal.
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington */
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington case isc_socket_udp:
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington region.length = disp->buffersize;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington region.base = allocate_buffer(disp, disp->buffersize);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington if (region.base == NULL)
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews return;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews XDEBUG(("Recv into %p, length %d\n", region.base,
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington region.length));
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington res = isc_socket_recv(disp->socket, &region, ISC_TRUE,
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington disp->task, udp_recv, disp);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson if (res != ISC_R_SUCCESS) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington disp->shutdown_why = res;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews do_cancel(disp, NULL);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews return;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson disp->recvs++;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington break;
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case isc_socket_tcp:
f15af68028adc665d3bdddf955fc52bad83f0514Brian Wellington XDEBUG(("Starting tcp receive\n"));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews res = dns_tcpmsg_readmessage(&disp->tcpmsg,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews disp->task, tcp_recv,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews disp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (res != ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews disp->shutdown_why = res;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington do_cancel(disp, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews }
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater disp->recvs++;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews break;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews/*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Publics.
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_result_t
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrewsdns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int maxbuffersize,
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews unsigned int maxbuffers, unsigned int maxrequests,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int hashsize,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_dispatch_t **dispp)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews{
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_dispatch_t *disp;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int tablesize;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_result_t res;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_sockettype_t socktype;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int i;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(mctx != NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(sock != NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(task != NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(hashsize <= 24);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews REQUIRE(maxbuffersize >= 512 && maxbuffersize < (64 * 1024));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(maxbuffers > 0);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(dispp != NULL && *dispp == NULL);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews socktype = isc_socket_gettype(sock);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington REQUIRE(socktype == isc_socket_udp || socktype == isc_socket_tcp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews res = DNS_R_SUCCESS;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington disp = isc_mem_get(mctx, sizeof(dns_dispatch_t));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (disp == NULL)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return (DNS_R_NOMEMORY);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington disp->magic = 0;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington disp->mctx = mctx;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->buffersize = maxbuffersize;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->maxrequests = maxrequests;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->maxbuffers = maxbuffers;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->refcount = 1;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->recvs = 0;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (socktype == isc_socket_udp) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->recvs_wanted = 4; /* XXXMLG config option */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews } else {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->recvs_wanted = 1;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->shutting_down = 0;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->shutdown_out = 0;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->shutdown_why = ISC_R_UNEXPECTED;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->requests = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews disp->buffers = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_LIST_INIT(disp->rq_handlers);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ISC_LIST_INIT(disp->rq_events);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews tablesize = (1 << hashsize);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->qid_table = isc_mem_get(disp->mctx,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews tablesize * sizeof(dns_displist_t));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (disp->qid_table == NULL) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews res = DNS_R_NOMEMORY;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out1;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington for (i = 0 ; i < tablesize ; i++)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_LIST_INIT(disp->qid_table[i]);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington disp->qid_mask = tablesize - 1;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews disp->qid_hashsize = tablesize;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (isc_mutex_init(&disp->lock) != ISC_R_SUCCESS) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews res = DNS_R_UNEXPECTED;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init failed");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out2;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->epool = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (isc_mempool_create(mctx, sizeof(dns_dispatchevent_t),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews &disp->epool) != ISC_R_SUCCESS) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews res = DNS_R_NOMEMORY;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out3;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->bpool = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (isc_mempool_create(mctx, maxbuffersize,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews &disp->bpool) != ISC_R_SUCCESS) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews res = DNS_R_NOMEMORY;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out4;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_setmaxalloc(disp->bpool, maxbuffers);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->rpool = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (isc_mempool_create(mctx, sizeof(dns_dispentry_t),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews &disp->rpool) != ISC_R_SUCCESS) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews res = DNS_R_NOMEMORY;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out5;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Keep some number of items around. This should be a config
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * option. For now, keep 8, but later keep at least two even
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * if the caller wants less. This allows us to ensure certain
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * things, like an event can be "freed" and the next allocation
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * will always succeed.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Note that if limits are placed on anything here, we use one
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * event internally, so the actual limit should be "wanted + 1."
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * XXXMLG
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_setfreemax(disp->epool, 8);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_setfreemax(disp->bpool, 8);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_setfreemax(disp->rpool, 8);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->failsafe_ev = allocate_event(disp);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (disp->failsafe_ev == NULL) {
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater res = DNS_R_NOMEMORY;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto out6;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * should initialize qid_state here XXXMLG
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->qid_state = (unsigned int)disp;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->magic = DISPATCH_MAGIC;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->task = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_task_attach(task, &disp->task);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp->socket = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_socket_attach(sock, &disp->socket);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_tcpmsg_init(disp->mctx, disp->socket, &disp->tcpmsg);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *dispp = disp;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (DNS_R_SUCCESS);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * error returns
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out6:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_destroy(&disp->rpool);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out5:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_destroy(&disp->bpool);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out4:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mempool_destroy(&disp->epool);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out3:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mutex_destroy(&disp->lock);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out2:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mem_put(mctx, disp->mctx, disp->qid_hashsize * sizeof(void *));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews out1:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_mem_put(mctx, disp, sizeof(dns_dispatch_t));
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater return (res);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater}
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsvoid
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsdns_dispatch_destroy(dns_dispatch_t **dispp)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews{
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_dispatch_t *disp;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_boolean_t killit;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews disp = *dispp;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *dispp = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington LOCK(&disp->lock);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews INSIST(disp->refcount > 0);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews disp->refcount--;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews killit = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (disp->refcount == 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (disp->recvs > 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_socket_cancel(disp->socket, NULL,
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington ISC_SOCKCANCEL_RECV);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews killit = ISC_TRUE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews XDEBUG(("dns_dispatch_destory: refcount = %d\n", disp->refcount));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (killit)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(disp);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_result_t
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellingtondns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_task_t *task, isc_taskaction_t action, void *arg,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_messageid_t *idp, dns_dispentry_t **resp)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_dispentry_t *res;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int bucket;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_messageid_t id;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews int i;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_boolean_t ok;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(VALID_DISPATCH(disp));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(task != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(dest != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(resp != NULL && *resp == NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(idp != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (disp->requests == disp->maxrequests) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_QUOTA);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington * Try somewhat hard to find an unique ID.
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews id = randomid(disp);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews bucket = hash(disp, dest, id);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ok = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (i = 0 ; i < 64 ; i++) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (bucket_search(disp, dest, id, bucket) == NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ok = ISC_TRUE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington id = randomid(disp);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington bucket = hash(disp, dest, id);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!ok) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOMORE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews res = isc_mempool_get(disp->rpool);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (res == NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (DNS_R_NOMEMORY);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington disp->refcount++;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington disp->requests++;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews res->task = NULL;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson isc_task_attach(task, &res->task);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson res->magic = RESPONSE_MAGIC;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson res->id = id;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington res->bucket = bucket;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson res->host = *dest;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington res->action = action;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews res->arg = arg;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res->item_out = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ISC_LIST_INIT(res->items);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ISC_LINK_INIT(res, link);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ISC_LIST_APPEND(disp->qid_table[bucket], res, link);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington XDEBUG(("Inserted response into bucket %d\n", bucket));
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington startrecv(disp);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington UNLOCK(&disp->lock);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington *idp = id;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington *resp = res;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (DNS_R_SUCCESS);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellingtonvoid
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_dispatch_removeresponse(dns_dispatch_t *disp, dns_dispentry_t **resp,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_dispatchevent_t **sockevent)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence dns_dispentry_t *res;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_dispatchevent_t *ev;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned int bucket;
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington isc_boolean_t killit;
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_DISPATCH(disp));
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington REQUIRE(resp != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_RESPONSE(*resp));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington res = *resp;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *resp = NULL;
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington if (sockevent != NULL) {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington REQUIRE(*sockevent != NULL);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington ev = *sockevent;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington *sockevent = NULL;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington } else {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington ev = NULL;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington LOCK(&disp->lock);
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington INSIST(disp->requests > 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley disp->requests--;
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington INSIST(disp->refcount > 0);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews disp->refcount--;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley killit = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (disp->refcount == 0) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (disp->recvs > 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_socket_cancel(disp->socket, NULL,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ISC_SOCKCANCEL_RECV);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington else
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington killit = ISC_TRUE;
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res->magic = 0;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley bucket = res->bucket;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ISC_LIST_UNLINK(disp->qid_table[bucket], res, link);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_task_detach(&res->task);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (ev != NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(res->item_out = ISC_TRUE);
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 res->item_out = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley free_buffer(disp, ev->buffer.base, ev->buffer.length);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley free_event(disp, ev);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_mempool_put(disp->rpool, res);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (disp->shutting_down == 1)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington do_cancel(disp, NULL);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington startrecv(disp);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington UNLOCK(&disp->lock);
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington if (killit)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington destroy(disp);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_result_t
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafssondns_dispatch_addrequest(dns_dispatch_t *disp,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_task_t *task, isc_taskaction_t action, void *arg,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_dispentry_t **resp)
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson{
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_dispentry_t *res;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson REQUIRE(VALID_DISPATCH(disp));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(task != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(resp != NULL && *resp == NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (disp->requests == disp->maxrequests) {
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington UNLOCK(&disp->lock);
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington return (ISC_R_QUOTA);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res = isc_mempool_get(disp->rpool);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (res == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley UNLOCK(&disp->lock);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (DNS_R_NOMEMORY);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington disp->refcount++;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington disp->requests++;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington res->task = NULL;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington isc_task_attach(task, &res->task);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res->magic = REQUEST_MAGIC;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res->bucket = INVALID_BUCKET;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews res->action = action;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews res->arg = arg;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews res->item_out = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_LIST_INIT(res->items);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_LINK_INIT(res, link);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_LIST_APPEND(disp->rq_handlers, res, link);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington /*
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington * If there are queries waiting to be processed, give this critter
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * one of them.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington do_next_request(disp, res);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley startrecv(disp);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&disp->lock);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington *resp = res;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington return (DNS_R_SUCCESS);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington}
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellingtonvoid
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_dispatch_removerequest(dns_dispatch_t *disp, dns_dispentry_t **resp,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_dispatchevent_t **sockevent)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson dns_dispentry_t *res;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_dispatchevent_t *ev;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_boolean_t killit;
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_DISPATCH(disp));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(resp != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_REQUEST(*resp));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley res = *resp;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *resp = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (sockevent != NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(*sockevent != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ev = *sockevent;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *sockevent = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ev = NULL;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington LOCK(&disp->lock);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington INSIST(disp->requests > 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley disp->requests--;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(disp->refcount > 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley disp->refcount--;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington killit = ISC_FALSE;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (disp->refcount == 0) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (disp->recvs > 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_socket_cancel(disp->socket, NULL,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ISC_SOCKCANCEL_RECV);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley killit = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington res->magic = 0;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington ISC_LIST_UNLINK(disp->rq_handlers, res, link);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_task_detach(&res->task);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_mempool_put(disp->rpool, res);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (ev != NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(res->item_out = ISC_TRUE);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews res->item_out = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (ev->buffer.length != 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews free_buffer(disp, ev->buffer.base, ev->buffer.length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews free_event(disp, ev);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews startrecv(disp);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington if (killit)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(disp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvoid
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsdns_dispatch_freeevent(dns_dispatch_t *disp, dns_dispentry_t *resp,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_dispatchevent_t **sockevent)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington dns_dispatchevent_t *ev;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington isc_boolean_t response;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_DISPATCH(disp));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(sockevent != NULL && *sockevent != NULL);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington ev = *sockevent;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington *sockevent = NULL;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington response = ISC_FALSE;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington if (VALID_RESPONSE(resp)) {
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews response = ISC_TRUE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews REQUIRE(VALID_RESPONSE(resp) || VALID_REQUEST(resp));
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(ev != disp->failsafe_ev);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(resp->item_out = ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews resp->item_out = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews free_buffer(disp, ev->buffer.base, ev->buffer.length);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews free_event(disp, ev);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington if (response)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews do_next_response(disp, resp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews do_next_request(disp, resp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington startrecv(disp);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&disp->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic void
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdo_next_response(dns_dispatch_t *disp, dns_dispentry_t *resp)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews{
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_dispatchevent_t *ev;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews INSIST(resp->item_out == ISC_FALSE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ev = ISC_LIST_HEAD(resp->items);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (ev == NULL) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (disp->shutting_down == 1)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews do_cancel(disp, resp);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews ISC_LIST_UNLINK(disp->rq_events, ev, link);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp->action, resp->arg, resp, NULL, NULL);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews resp->item_out = ISC_TRUE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews XDEBUG(("Sent event for buffer %p (len %d) to task %p\n",
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews ev->buffer.base, ev->buffer.length, resp->task));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_TASK_SEND(resp->task, (isc_event_t **)&ev);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews}
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrewsstatic void
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrewsdo_next_request(dns_dispatch_t *disp, dns_dispentry_t *resp)
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews{
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews dns_dispatchevent_t *ev;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews INSIST(resp->item_out == ISC_FALSE);
cc7d91bd5c6b9be5a3c67a99112b885602c24873Mark Andrews
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews ev = ISC_LIST_HEAD(disp->rq_events);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (ev == NULL) {
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (disp->shutting_down == 1)
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews do_cancel(disp, resp);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_LIST_UNLINK(disp->rq_events, ev, link);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews resp->action, resp->arg, resp, NULL, NULL);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington resp->item_out = ISC_TRUE;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington XDEBUG(("Sent event for buffer %p (len %d) to task %p\n",
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ev->buffer.base, ev->buffer.length, resp->task));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ISC_TASK_SEND(resp->task, (isc_event_t **)&ev);
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson}
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic void
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdo_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp)
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson{
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_dispatchevent_t *ev;
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (disp->shutdown_out == 1) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley XDEBUG(("do_cancel() call ignored\n"));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * If no target given, find the first request handler. If
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * there are packets waiting for any handler, however, don't
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * kill them.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (resp == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley resp = ISC_LIST_HEAD(disp->rq_handlers);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (resp != NULL && resp->item_out == ISC_TRUE)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence resp = NULL;
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson }
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson /*
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson * Search for the first responce handler without packets outstanding.
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (resp == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley resp = linear_first(disp);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (resp == NULL) /* no first item? */
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson return;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson do {
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (resp->item_out == ISC_FALSE)
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington resp = linear_next(disp, resp);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington } while (resp != NULL);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington /*
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * No one to send the cancel event to, so nothing to do.
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington */
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (resp == NULL)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson return;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Send the shutdown failsafe event to this resp.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ev = disp->failsafe_ev;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ISC_EVENT_INIT(ev, sizeof (*ev), 0, NULL, DNS_EVENT_DISPATCH,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews resp->action, resp->arg, resp, NULL, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ev->result = disp->shutdown_why;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ev->buffer.base = NULL;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ev->buffer.length = 0;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley disp->shutdown_out = 1;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington XDEBUG(("Sending failsafe event to task %p\n", resp->task));
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson ISC_TASK_SEND(resp->task, (isc_event_t **)&ev);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson}
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyisc_socket_t *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_dispatch_getsocket(dns_dispatch_t *disp)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington REQUIRE(VALID_DISPATCH(disp));
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington return (disp->socket);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington}
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews