b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2000-2002, 2004-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#include <config.h>
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#include <isc/magic.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <isc/task.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <isc/timer.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <isc/util.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington#include <dns/acl.h>
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington#include <dns/compress.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <dns/dispatch.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <dns/events.h>
8b61d2012063306528286680bd9f086fa868d86eMark Andrews#include <dns/log.h>
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews#include <dns/message.h>
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington#include <dns/rdata.h>
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington#include <dns/rdatastruct.h>
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#include <dns/request.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/result.h>
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington#include <dns/tsig.h>
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!')
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewstypedef ISC_LIST(dns_request_t) dns_requestlist_t;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews#define DNS_REQUEST_NLOCKS 7
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstruct dns_requestmgr {
28fc90e6c81338c5f34e065fdda49d320e362583Mark Andrews unsigned int magic;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mutex_t lock;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_t *mctx;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews /* locked */
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_int32_t eref;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_int32_t iref;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_timermgr_t *timermgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_socketmgr_t *socketmgr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatchmgr_t *dispatchmgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatch_t *dispatchv4;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatch_t *dispatchv6;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_boolean_t exiting;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_eventlist_t whenshutdown;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff unsigned int hash;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mutex_t locks[DNS_REQUEST_NLOCKS];
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_requestlist_t requests;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews};
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstruct dns_request {
28fc90e6c81338c5f34e065fdda49d320e362583Mark Andrews unsigned int magic;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff unsigned int hash;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_mem_t *mctx;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_int32_t flags;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff ISC_LINK(dns_request_t) link;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_buffer_t *query;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_buffer_t *answer;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_requestevent_t *event;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatch_t *dispatch;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispentry_t *dispentry;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff isc_timer_t *timer;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_requestmgr_t *requestmgr;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_t *tsig;
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington dns_tsigkey_t *tsigkey;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson isc_event_t ctlevent;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson isc_boolean_t canceling; /* ctlevent outstanding */
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_sockaddr_t destaddr;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udpcount;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_dscp_t dscp;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews};
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews#define DNS_REQUEST_F_CONNECTING 0x0001
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews#define DNS_REQUEST_F_SENDING 0x0002
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson synchronously canceled */
bdfaef63f576f810fab27f64395faccf2fcd9434Francis Dupont#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews#define DNS_REQUEST_CANCELED(r) \
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews (((r)->flags & DNS_REQUEST_F_CANCELED) != 0)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews#define DNS_REQUEST_CONNECTING(r) \
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews#define DNS_REQUEST_SENDING(r) \
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews (((r)->flags & DNS_REQUEST_F_SENDING) != 0)
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson#define DNS_REQUEST_TIMEDOUT(r) \
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0)
f53848e17123569387b279578f0100dca5407da5Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/***
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews *** Forward
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ***/
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void mgr_destroy(dns_requestmgr_t *requestmgr);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void mgr_shutdown(dns_requestmgr_t *requestmgr);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrewsstatic unsigned int mgr_gethash(dns_requestmgr_t *requestmgr);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void send_shutdown_events(dns_requestmgr_t *requestmgr);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
59abb512d344bfa09012cc11b7d814966f035da4Mark Andrewsstatic isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer,
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews unsigned int options, isc_mem_t *mctx);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_senddone(isc_task_t *task, isc_event_t *event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_response(isc_task_t *task, isc_event_t *event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_timeout(isc_task_t *task, isc_event_t *event);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_socket_t * req_getsocket(dns_request_t *request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_connected(isc_task_t *task, isc_event_t *event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_sendevent(dns_request_t *request, isc_result_t result);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_cancel(dns_request_t *request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void req_destroy(dns_request_t *request);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonstatic void req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssonstatic void do_cancel(isc_task_t *task, isc_event_t *event);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/***
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews *** Public
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ***/
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsisc_result_t
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsdns_requestmgr_create(isc_mem_t *mctx,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_timermgr_t *timermgr,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_socketmgr_t *socketmgr,
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff isc_taskmgr_t *taskmgr,
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff dns_dispatchmgr_t *dispatchmgr,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_dispatch_t *dispatchv4,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_dispatch_t *dispatchv6,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_requestmgr_t **requestmgrp)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews{
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews dns_requestmgr_t *requestmgr;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_result_t result;
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews int i;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int dispattr;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(timermgr != NULL);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(socketmgr != NULL);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff REQUIRE(taskmgr != NULL);
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff REQUIRE(dispatchmgr != NULL);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews UNUSED(sock);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (dispatchv4 != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispattr = dns_dispatch_getattributes(dispatchv4);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (dispatchv6 != NULL) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispattr = dns_dispatch_getattributes(dispatchv6);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr = isc_mem_get(mctx, sizeof(*requestmgr));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (requestmgr == NULL)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews return (ISC_R_NOMEMORY);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = isc_mutex_init(&requestmgr->lock);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews return (result);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews result = isc_mutex_init(&requestmgr->locks[i]);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews while (--i >= 0)
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&requestmgr->locks[i]);
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews return (result);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews }
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews }
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->timermgr = timermgr;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews requestmgr->socketmgr = socketmgr;
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff requestmgr->taskmgr = taskmgr;
ca9739800f045cd4d39014f98b920d4354b5bd14Michael Graff requestmgr->dispatchmgr = dispatchmgr;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->dispatchv4 = NULL;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (dispatchv4 != NULL)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->dispatchv6 = NULL;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (dispatchv6 != NULL)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr->mctx = NULL;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_attach(mctx, &requestmgr->mctx);
bdfaef63f576f810fab27f64395faccf2fcd9434Francis Dupont requestmgr->eref = 1; /* implicit attach */
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr->iref = 0;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ISC_LIST_INIT(requestmgr->whenshutdown);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ISC_LIST_INIT(requestmgr->requests);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->exiting = ISC_FALSE;
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews requestmgr->hash = 0;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->magic = REQUESTMGR_MAGIC;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews *requestmgrp = requestmgr;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews return (ISC_R_SUCCESS);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_event_t **eventp)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews{
cccfafa31131844c3b82e4c92f87f243d7ca3287Mark Andrews isc_task_t *tclone;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington isc_event_t *event;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown");
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(VALID_REQUESTMGR(requestmgr));
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(eventp != NULL);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington event = *eventp;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington *eventp = NULL;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington LOCK(&requestmgr->lock);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington if (requestmgr->exiting) {
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington /*
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * We're already shutdown. Send the event.
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington */
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington event->ev_sender = requestmgr;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington isc_task_send(task, &event);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington } else {
cccfafa31131844c3b82e4c92f87f243d7ca3287Mark Andrews tclone = NULL;
cccfafa31131844c3b82e4c92f87f243d7ca3287Mark Andrews isc_task_attach(task, &tclone);
cccfafa31131844c3b82e4c92f87f243d7ca3287Mark Andrews event->ev_sender = tclone;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews UNLOCK(&requestmgr->lock);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(VALID_REQUESTMGR(requestmgr));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews LOCK(&requestmgr->lock);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews mgr_shutdown(requestmgr);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews UNLOCK(&requestmgr->lock);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencestatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsmgr_shutdown(dns_requestmgr_t *requestmgr) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_request_t *request;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Caller holds lock.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (!requestmgr->exiting) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews requestmgr->exiting = ISC_TRUE;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews for (request = ISC_LIST_HEAD(requestmgr->requests);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request != NULL;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request = ISC_LIST_NEXT(request, link)) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_request_cancel(request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews }
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews if (requestmgr->iref == 0) {
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews INSIST(ISC_LIST_EMPTY(requestmgr->requests));
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews send_shutdown_events(requestmgr);
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews }
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews }
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews}
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrewsstatic void
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrewsrequestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews /*
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews * Locked by caller.
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews */
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(VALID_REQUESTMGR(source));
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(targetp != NULL && *targetp == NULL);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(!source->exiting);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews source->iref++;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews *targetp = source;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews source, source->eref, source->iref);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews}
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrewsstatic void
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrewsrequestmgr_detach(dns_requestmgr_t **requestmgrp) {
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews dns_requestmgr_t *requestmgr;
f53848e17123569387b279578f0100dca5407da5Mark Andrews isc_boolean_t need_destroy = ISC_FALSE;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(requestmgrp != NULL);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr = *requestmgrp;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(VALID_REQUESTMGR(requestmgr));
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews *requestmgrp = NULL;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews LOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews INSIST(requestmgr->iref > 0);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr->iref--;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews requestmgr, requestmgr->eref, requestmgr->iref);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews if (requestmgr->iref == 0 && requestmgr->exiting) {
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews send_shutdown_events(requestmgr);
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews if (requestmgr->eref == 0)
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews need_destroy = ISC_TRUE;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews UNLOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews if (need_destroy)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews mgr_destroy(requestmgr);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(VALID_REQUESTMGR(source));
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(targetp != NULL && *targetp == NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(!source->exiting);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews LOCK(&source->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews source->eref++;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews *targetp = source;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews UNLOCK(&source->lock);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews source, source->eref, source->iref);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_requestmgr_detach(dns_requestmgr_t **requestmgrp) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews dns_requestmgr_t *requestmgr;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_boolean_t need_destroy = ISC_FALSE;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(requestmgrp != NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews requestmgr = *requestmgrp;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(VALID_REQUESTMGR(requestmgr));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews LOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews INSIST(requestmgr->eref > 0);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr->eref--;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews requestmgr, requestmgr->eref, requestmgr->iref);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews if (requestmgr->eref == 0 && requestmgr->iref == 0) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews INSIST(requestmgr->exiting &&
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ISC_LIST_HEAD(requestmgr->requests) == NULL);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews need_destroy = ISC_TRUE;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews UNLOCK(&requestmgr->lock);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (need_destroy)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews mgr_destroy(requestmgr);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews *requestmgrp = NULL;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewssend_shutdown_events(dns_requestmgr_t *requestmgr) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_event_t *event, *next_event;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_task_t *etask;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews /*
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Caller must be holding the manager lock.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews for (event = ISC_LIST_HEAD(requestmgr->whenshutdown);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews event != NULL;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews event = next_event) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff next_event = ISC_LIST_NEXT(event, ev_link);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff etask = event->ev_sender;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff event->ev_sender = requestmgr;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_task_sendanddetach(&etask, &event);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews }
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsmgr_destroy(dns_requestmgr_t *requestmgr) {
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews int i;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_t *mctx;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(requestmgr->eref == 0);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews REQUIRE(requestmgr->iref == 0);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&requestmgr->lock);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews for (i = 0; i < DNS_REQUEST_NLOCKS; i++)
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&requestmgr->locks[i]);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews if (requestmgr->dispatchv4 != NULL)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews dns_dispatch_detach(&requestmgr->dispatchv4);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews if (requestmgr->dispatchv6 != NULL)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews dns_dispatch_detach(&requestmgr->dispatchv6);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews requestmgr->magic = 0;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews mctx = requestmgr->mctx;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_detach(&mctx);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrewsstatic unsigned int
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrewsmgr_gethash(dns_requestmgr_t *requestmgr) {
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "mgr_gethash");
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews /*
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews * Locked by caller.
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews */
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews requestmgr->hash++;
668eb43f1f24c887b6972f6a1610b4b38b281080Brian Wellington return (requestmgr->hash % DNS_REQUEST_NLOCKS);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews}
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic inline isc_result_t
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_region_t r;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_socketevent_t *sendevent;
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews isc_result_t result;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = req_getsocket(request);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(request->query, &r);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 /*
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * We could connect the socket when we are using an exclusive dispatch
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * as we do in resolver.c, but we prefer implementation simplicity
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 * at this moment.
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 */
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sendevent = isc_socket_socketevent(request->mctx, sock,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt ISC_SOCKEVENT_SENDDONE,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt req_senddone, request);
f4dda9cf28f8be880097ee931b3237e09731a28aMark Andrews if (sendevent == NULL)
f4dda9cf28f8be880097ee931b3237e09731a28aMark Andrews return (ISC_R_NOMEMORY);
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt if (request->dscp == -1) {
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt sendevent->dscp = 0;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt } else {
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt sendevent->dscp = request->dscp;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt }
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt
1160ea4c2847b276946cf6bd00504929ec4f6e44Mark Andrews request->flags |= DNS_REQUEST_F_SENDING;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews result = isc_socket_sendto2(sock, &r, task, address, NULL,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt sendevent, 0);
1160ea4c2847b276946cf6bd00504929ec4f6e44Mark Andrews if (result != ISC_R_SUCCESS)
1160ea4c2847b276946cf6bd00504929ec4f6e44Mark Andrews request->flags &= ~DNS_REQUEST_F_SENDING;
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews return (result);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellingtonstatic isc_result_t
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉new_request(isc_mem_t *mctx, dns_request_t **requestp)
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉{
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington dns_request_t *request;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request = isc_mem_get(mctx, sizeof(*request));
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington if (request == NULL)
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington return (ISC_R_NOMEMORY);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington /*
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington * Zero structure.
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington */
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->magic = 0;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->mctx = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->flags = 0;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington ISC_LINK_INIT(request, link);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->query = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->answer = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->event = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->dispatch = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->dispentry = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->timer = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->requestmgr = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->tsig = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request->tsigkey = NULL;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt request->dscp = -1;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson NULL, NULL);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson request->canceling = ISC_FALSE;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff request->udpcount = 0;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington isc_mem_attach(mctx, &request->mctx);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
ac6afcd0caf72aaa2a537e0003de30b363b4a68bBrian Wellington request->magic = REQUEST_MAGIC;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington *requestp = request;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington return (ISC_R_SUCCESS);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington}
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsstatic isc_boolean_t
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsisblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
97f26b88f62b10a9c26a91ebe8387d2e498c2d00Andreas Gustafsson dns_acl_t *blackhole;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_netaddr_t netaddr;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews int match;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_boolean_t drop = ISC_FALSE;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews char netaddrstr[ISC_NETADDR_FORMATSIZE];
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
97f26b88f62b10a9c26a91ebe8387d2e498c2d00Andreas Gustafsson blackhole = dns_dispatchmgr_getblackhole(dispatchmgr);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (blackhole != NULL) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_netaddr_fromsockaddr(&netaddr, destaddr);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (dns_acl_match(&netaddr, NULL, blackhole,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews NULL, &match, NULL) == ISC_R_SUCCESS &&
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews match > 0)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews drop = ISC_TRUE;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (drop) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr));
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (drop);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews}
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsstatic isc_result_t
ff62d4458acda2110a3763ec576a4f728450662cEvan Huntcreate_tcp_dispatch(isc_boolean_t newtcp, isc_boolean_t share,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt dns_requestmgr_t *requestmgr,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews isc_sockaddr_t *srcaddr,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_sockaddr_t *destaddr, isc_dscp_t dscp,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews isc_boolean_t *connected, dns_dispatch_t **dispatchp)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews{
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_result_t result;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock = NULL;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_t src;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned int attrs;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_t bind_any;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt if (!newtcp && share) {
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt result = dns_dispatch_gettcp2(requestmgr->dispatchmgr,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt destaddr, srcaddr,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt connected, dispatchp);
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt if (result == ISC_R_SUCCESS) {
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt char peer[ISC_SOCKADDR_FORMATSIZE];
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt isc_sockaddr_format(destaddr, peer, sizeof(peer));
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt req_log(ISC_LOG_DEBUG(1), "attached to %s TCP "
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt "connection to %s",
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt *connected ? "existing" : "pending", peer);
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt return (result);
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt }
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt } else if (!newtcp) {
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews srcaddr, dispatchp);
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews if (result == ISC_R_SUCCESS) {
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews char peer[ISC_SOCKADDR_FORMATSIZE];
3560b7d66c3f85816ed4b51d5eca111200b17b6cMark Andrews
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews *connected = ISC_TRUE;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews isc_sockaddr_format(destaddr, peer, sizeof(peer));
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews req_log(ISC_LOG_DEBUG(1), "attached to existing TCP "
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews "connection to %s", peer);
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews return (result);
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews }
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews }
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews result = isc_socket_create(requestmgr->socketmgr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_pf(destaddr),
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_sockettype_tcp, &sock);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (result != ISC_R_SUCCESS)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (result);
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (srcaddr == NULL) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_anyofpf(&bind_any,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_pf(destaddr));
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews result = isc_socket_bind(sock, &bind_any, 0);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews } else {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews src = *srcaddr;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_setport(&src, 0);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews result = isc_socket_bind(sock, &src, 0);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (result != ISC_R_SUCCESS)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews goto cleanup;
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews#endif
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs = 0;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_TCP;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (isc_sockaddr_pf(destaddr) == AF_INET)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_IPV4;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews else
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_IPV6;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_MAKEQUERY;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_dscp(sock, dscp);
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews result = dns_dispatch_createtcp2(requestmgr->dispatchmgr,
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock, requestmgr->taskmgr,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews srcaddr, destaddr,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews 4096, 32768, 32768, 16411, 16433,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews attrs, dispatchp);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewscleanup:
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_detach(&sock);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (result);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews}
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsstatic isc_result_t
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsfind_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews{
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews dns_dispatch_t *disp = NULL;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews unsigned int attrs, attrmask;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (srcaddr == NULL) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews switch (isc_sockaddr_pf(destaddr)) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews case PF_INET:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews disp = requestmgr->dispatchv4;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews break;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews case PF_INET6:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews disp = requestmgr->dispatchv6;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews break;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews default:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (ISC_R_NOTIMPLEMENTED);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (disp == NULL)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (ISC_R_FAMILYNOSUPPORT);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews dns_dispatch_attach(disp, dispatchp);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (ISC_R_SUCCESS);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs = 0;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_UDP;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews switch (isc_sockaddr_pf(srcaddr)) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews case PF_INET:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_IPV4;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews break;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews case PF_INET6:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs |= DNS_DISPATCHATTR_IPV6;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews break;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews default:
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (ISC_R_NOTIMPLEMENTED);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews }
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrmask = 0;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrmask |= DNS_DISPATCHATTR_UDP;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrmask |= DNS_DISPATCHATTR_TCP;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrmask |= DNS_DISPATCHATTR_IPV4;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrmask |= DNS_DISPATCHATTR_IPV6;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (dns_dispatch_getudp(requestmgr->dispatchmgr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews requestmgr->socketmgr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews requestmgr->taskmgr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews srcaddr, 4096,
6a3fa181d1253db5191139e20231512eebaddeebEvan Hunt 32768, 32768, 16411, 16433,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews attrs, attrmask,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews dispatchp));
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews}
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsstatic isc_result_t
ff62d4458acda2110a3763ec576a4f728450662cEvan Huntget_dispatch(isc_boolean_t tcp, isc_boolean_t newtcp, isc_boolean_t share,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews dns_requestmgr_t *requestmgr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews isc_dscp_t dscp, isc_boolean_t *connected,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews dns_dispatch_t **dispatchp)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews{
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_result_t result;
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (tcp)
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt result = create_tcp_dispatch(newtcp, share, requestmgr,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt srcaddr, destaddr, dscp,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt connected, dispatchp);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews else
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews result = find_udp_dispatch(requestmgr, srcaddr,
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews destaddr, dispatchp);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (result);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews}
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrewsstatic isc_result_t
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrewsset_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) {
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_time_t expires;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_interval_t interval;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_result_t result;
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_timertype_t timertype;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_interval_set(&interval, timeout, 0);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews result = isc_time_nowplusinterval(&expires, &interval);
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_interval_set(&interval, udpresend, 0);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (result == ISC_R_SUCCESS)
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews result = isc_timer_reset(timer, timertype, &expires,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews &interval, ISC_FALSE);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (result);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews}
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsisc_result_t
056141f2878d1046306ef0ba035263a00de57f98Mark Andrewsdns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews unsigned int options, unsigned int timeout,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_task_t *task, isc_taskaction_t action, void *arg,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews dns_request_t **requestp)
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews{
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return(dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, timeout, 0, 0, task, action,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff arg, requestp));
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews}
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrewsisc_result_t
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrewsdns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int options, unsigned int timeout,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udptimeout, isc_task_t *task,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_taskaction_t action, void *arg,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews dns_request_t **requestp)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff{
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udpretries = 0;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout != 0)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udpretries = timeout / udptimeout;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, timeout, udptimeout,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udpretries, task, action, arg,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff requestp));
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff}
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graffisc_result_t
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graffdns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int options, unsigned int timeout,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udptimeout, unsigned int udpretries,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff isc_task_t *task, isc_taskaction_t action, void *arg,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff dns_request_t **requestp)
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt{
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, timeout, udptimeout,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt udpretries, task, action, arg,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt requestp));
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt}
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt
67adc03ef81fb610f8df093b17f55275ee816754Evan Huntisc_result_t
67adc03ef81fb610f8df093b17f55275ee816754Evan Huntdns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_dscp_t dscp, unsigned int options,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt unsigned int timeout, unsigned int udptimeout,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt unsigned int udpretries, isc_task_t *task,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_taskaction_t action, void *arg,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt dns_request_t **requestp)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews{
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews dns_request_t *request = NULL;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_task_t *tclone = NULL;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock = NULL;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_result_t result;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_mem_t *mctx;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews dns_messageid_t id;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_boolean_t tcp = ISC_FALSE;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews isc_boolean_t newtcp = ISC_FALSE;
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt isc_boolean_t share = ISC_FALSE;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_region_t r;
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews isc_boolean_t connected = ISC_FALSE;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews unsigned int dispopt = 0;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(VALID_REQUESTMGR(requestmgr));
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(msgbuf != NULL);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(destaddr != NULL);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(task != NULL);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(action != NULL);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(requestp != NULL && *requestp == NULL);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews REQUIRE(timeout > 0);
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater if (srcaddr != NULL)
6ef15459b8fd3fc8b5672da4ad72c19a755dbe45Mark Andrews REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews mctx = requestmgr->mctx;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (isblackholed(requestmgr->dispatchmgr, destaddr))
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (DNS_R_BLACKHOLED);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington result = new_request(mctx, &request);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington if (result != ISC_R_SUCCESS)
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington return (result);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout == 0 && udpretries != 0) {
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udptimeout = timeout / (udpretries + 1);
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout == 0)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udptimeout = 1;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff }
240e57ab983296e6d52031a594d3345728191b48Mark Andrews request->udpcount = udpretries;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt request->dscp = dscp;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews /*
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews * Create timer now. We will set it below once.
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews */
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews NULL, NULL, task, req_timeout, request,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews &request->timer);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->event = (dns_requestevent_t *)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson action, arg, sizeof(dns_requestevent_t));
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (request->event == NULL) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = ISC_R_NOMEMORY;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews }
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_task_attach(task, &tclone);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->event->ev_sender = task;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->event->request = request;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->event->result = ISC_R_FAILURE;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_buffer_usedregion(msgbuf, &r);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = DNS_R_FORMERR;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews }
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews tcp = ISC_TRUE;
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt share = ISC_TF((options & DNS_REQUESTOPT_SHARE) != 0);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews again:
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt result = get_dispatch(tcp, newtcp, share, requestmgr,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt srcaddr, destaddr, dscp,
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews &connected, &request->dispatch);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (result != ISC_R_SUCCESS)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews goto cleanup;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews if ((options & DNS_REQUESTOPT_FIXEDID) != 0) {
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews id = (r.base[0] << 8) | r.base[1];
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews dispopt |= DNS_DISPATCHOPT_FIXEDID;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews }
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews result = dns_dispatch_addresponse3(request->dispatch, dispopt,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews destaddr, task, req_response,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews request, &id, &request->dispentry,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 requestmgr->socketmgr);
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews if (result != ISC_R_SUCCESS) {
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews newtcp = ISC_TRUE;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews connected = ISC_FALSE;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews dns_dispatch_detach(&request->dispatch);
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews goto again;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews }
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews }
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = req_getsocket(request);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews INSIST(sock != NULL);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = isc_buffer_allocate(mctx, &request->query,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews r.length + (tcp ? 2 : 0));
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (tcp)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_buffer_putuint16(request->query, (isc_uint16_t)r.length);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = isc_buffer_copyregion(request->query, &r);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews /* Add message ID. */
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_buffer_usedregion(request->query, &r);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (tcp)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_region_consume(&r, 2);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews r.base[0] = (id>>8) & 0xff;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews r.base[1] = id & 0xff;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews LOCK(&requestmgr->lock);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (requestmgr->exiting) {
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews UNLOCK(&requestmgr->lock);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews result = ISC_R_SHUTTINGDOWN;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto cleanup;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews }
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews requestmgr_attach(requestmgr, &request->requestmgr);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->hash = mgr_gethash(requestmgr);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews ISC_LIST_APPEND(requestmgr->requests, request, link);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews UNLOCK(&requestmgr->lock);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto unlink;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews request->destaddr = *destaddr;
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews if (tcp && !connected) {
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews result = isc_socket_connect(sock, destaddr, task,
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews req_connected, request);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto unlink;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews } else {
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews result = req_send(request, task, connected ? NULL : destaddr);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (result != ISC_R_SUCCESS)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews goto unlink;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews }
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p",
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews *requestp = request;
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews return (ISC_R_SUCCESS);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews unlink:
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews LOCK(&requestmgr->lock);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews ISC_LIST_UNLINK(requestmgr->requests, request, link);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews UNLOCK(&requestmgr->lock);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews cleanup:
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews if (tclone != NULL)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews isc_task_detach(&tclone);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_destroy(request);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews dns_result_totext(result));
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews return (result);
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews}
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsisc_result_t
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_sockaddr_t *address, unsigned int options,
19d1b1667d073850d4366352aaf8319efc5debeeBrian Wellington dns_tsigkey_t *key,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned int timeout, isc_task_t *task,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews isc_taskaction_t action, void *arg,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews dns_request_t **requestp)
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews{
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return (dns_request_createvia4(requestmgr, message, NULL, address,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, key, timeout, 0, 0, task,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff action, arg, requestp));
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews}
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrewsisc_result_t
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrewsdns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews unsigned int options, dns_tsigkey_t *key,
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews unsigned int timeout, isc_task_t *task,
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews isc_taskaction_t action, void *arg,
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews dns_request_t **requestp)
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews{
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return(dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, key, timeout, 0, 0, task,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff action, arg, requestp));
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews}
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrewsisc_result_t
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrewsdns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews unsigned int options, dns_tsigkey_t *key,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int timeout, unsigned int udptimeout,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_task_t *task, isc_taskaction_t action, void *arg,
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews dns_request_t **requestp)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff{
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udpretries = 0;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout != 0)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udpretries = timeout / udptimeout;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, key, timeout, udptimeout,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udpretries, task, action, arg,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff requestp));
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff}
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graffisc_result_t
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graffdns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int options, dns_tsigkey_t *key,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int timeout, unsigned int udptimeout,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff unsigned int udpretries, isc_task_t *task,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff isc_taskaction_t action, void *arg,
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff dns_request_t **requestp)
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt{
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
b8cf73a3b3e21d61f5a06670551ac22e61bcc4b1Mark Andrews -1, options, key, timeout, udptimeout,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt udpretries, task, action, arg,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt requestp));
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt}
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt
67adc03ef81fb610f8df093b17f55275ee816754Evan Huntisc_result_t
67adc03ef81fb610f8df093b17f55275ee816754Evan Huntdns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_dscp_t dscp, unsigned int options,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt dns_tsigkey_t *key, unsigned int timeout,
1e9f7a42bcfdfaa0ad314bed46e6c1297cdd0348Tinderbox User unsigned int udptimeout, unsigned int udpretries,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt isc_task_t *task, isc_taskaction_t action, void *arg,
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt dns_request_t **requestp)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews{
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_request_t *request = NULL;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_task_t *tclone = NULL;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock = NULL;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_result_t result;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_mem_t *mctx;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_messageid_t id;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews isc_boolean_t tcp;
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt isc_boolean_t share;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_boolean_t settsigkey = ISC_TRUE;
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews isc_boolean_t connected = ISC_FALSE;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(VALID_REQUESTMGR(requestmgr));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(message != NULL);
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews REQUIRE(destaddr != NULL);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(task != NULL);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(action != NULL);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(requestp != NULL && *requestp == NULL);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews REQUIRE(timeout > 0);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews mctx = requestmgr->mctx;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
ffff5d67926821d3db8df63bdd84a9cb1ce56739Evan Hunt if (srcaddr != NULL &&
ffff5d67926821d3db8df63bdd84a9cb1ce56739Evan Hunt isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr))
ffff5d67926821d3db8df63bdd84a9cb1ce56739Evan Hunt return (ISC_R_FAMILYMISMATCH);
ffff5d67926821d3db8df63bdd84a9cb1ce56739Evan Hunt
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (isblackholed(requestmgr->dispatchmgr, destaddr))
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews return (DNS_R_BLACKHOLED);
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request = NULL;
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington result = new_request(mctx, &request);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington if (result != ISC_R_SUCCESS)
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington return (result);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout == 0 && udpretries != 0) {
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udptimeout = timeout / (udpretries + 1);
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (udptimeout == 0)
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff udptimeout = 1;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff }
240e57ab983296e6d52031a594d3345728191b48Mark Andrews request->udpcount = udpretries;
67adc03ef81fb610f8df093b17f55275ee816754Evan Hunt request->dscp = dscp;
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Create timer now. We will set it below once.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews NULL, NULL, task, req_timeout, request,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews &request->timer);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews goto cleanup;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->event = (dns_requestevent_t *)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson action, arg, sizeof(dns_requestevent_t));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->event == NULL) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = ISC_R_NOMEMORY;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews }
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_task_attach(task, &tclone);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff request->event->ev_sender = task;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->event->request = request;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->event->result = ISC_R_FAILURE;
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington if (key != NULL)
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington dns_tsigkey_attach(key, &request->tsigkey);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews use_tcp:
dcc7ea97174501f0409c0c919b3ca04083e4e1b8Andreas Gustafsson tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt share = ISC_TF((options & DNS_REQUESTOPT_SHARE) != 0);
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt result = get_dispatch(tcp, ISC_FALSE, share,
ff62d4458acda2110a3763ec576a4f728450662cEvan Hunt requestmgr, srcaddr, destaddr,
ffeaac1d826b541af39d7b20b9b68ff19ff01832Mark Andrews dscp, &connected, &request->dispatch);
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews if (result != ISC_R_SUCCESS)
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews goto cleanup;
7c2dce3c4d2c863ff268576f13c4ddd6f29d67edMark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 result = dns_dispatch_addresponse2(request->dispatch, destaddr, task,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 req_response, request, &id,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 &request->dispentry,
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 requestmgr->socketmgr);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = req_getsocket(request);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews INSIST(sock != NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews message->id = id;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews if (settsigkey) {
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = dns_message_settsigkey(message, request->tsigkey);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (result != ISC_R_SUCCESS)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson goto cleanup;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson }
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews result = req_render(message, &request->query, options, mctx);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result == DNS_R_USETCP &&
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews (options & DNS_REQUESTOPT_TCP) == 0) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Try again using TCP.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_message_renderreset(message);
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_removeresponse(&request->dispentry, NULL);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_dispatch_detach(&request->dispatch);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = NULL;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews options |= DNS_REQUESTOPT_TCP;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews settsigkey = ISC_FALSE;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews goto use_tcp;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews }
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_getquerytsig(message, mctx, &request->tsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews LOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews if (requestmgr->exiting) {
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews UNLOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews result = ISC_R_SHUTTINGDOWN;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews goto cleanup;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews }
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews requestmgr_attach(requestmgr, &request->requestmgr);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews request->hash = mgr_gethash(requestmgr);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ISC_LIST_APPEND(requestmgr->requests, request, link);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews UNLOCK(&requestmgr->lock);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews goto unlink;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews request->destaddr = *destaddr;
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews if (tcp && !connected) {
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews result = isc_socket_connect(sock, destaddr, task,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews req_connected, request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews goto unlink;
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews } else {
74717eef53ba5d6aefc80eb262bbb090ff4bb3b5Mark Andrews result = req_send(request, task, connected ? NULL : destaddr);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews goto unlink;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews }
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p",
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews *requestp = request;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews return (ISC_R_SUCCESS);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews unlink:
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews LOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews ISC_LIST_UNLINK(requestmgr->requests, request, link);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews UNLOCK(&requestmgr->lock);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews cleanup:
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (tclone != NULL)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_task_detach(&tclone);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_destroy(request);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews dns_result_totext(result));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews return (result);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews}
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsstatic isc_result_t
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrewsreq_render(dns_message_t *message, isc_buffer_t **bufferp,
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews unsigned int options, isc_mem_t *mctx)
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews{
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_t *buf1 = NULL;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_t *buf2 = NULL;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_result_t result;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_region_t r;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews isc_boolean_t tcp = ISC_FALSE;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington dns_compress_t cctx;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington isc_boolean_t cleanup_cctx = ISC_FALSE;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(bufferp != NULL && *bufferp == NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "request_render");
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /*
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Create buffer able to hold largest possible message.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(mctx, &buf1, 65535);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews return (result);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington result = dns_compress_init(&cctx, -1, mctx);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington if (result != ISC_R_SUCCESS)
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington return (result);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington cleanup_cctx = ISC_TRUE;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
2e20dea9fc0a84217c7debdef8b4b6c6f04d3998Mark Andrews if ((options & DNS_REQUESTOPT_CASE) != 0)
2e20dea9fc0a84217c7debdef8b4b6c6f04d3998Mark Andrews dns_compress_setsensitive(&cctx, ISC_TRUE);
2e20dea9fc0a84217c7debdef8b4b6c6f04d3998Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /*
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Render message.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews */
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington result = dns_message_renderbegin(message, &cctx, buf1);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = dns_message_renderend(message);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington dns_compress_invalidate(&cctx);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington cleanup_cctx = ISC_FALSE;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /*
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Copy rendered message to exact sized buffer.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(buf1, &r);
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews if ((options & DNS_REQUESTOPT_TCP) != 0) {
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews tcp = ISC_TRUE;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews } else if (r.length > 512) {
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews result = DNS_R_USETCP;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews goto cleanup;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews }
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews if (tcp)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_putuint16(buf2, (isc_uint16_t)r.length);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews result = isc_buffer_copyregion(buf2, &r);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto cleanup;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /*
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Cleanup and return.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews */
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_free(&buf1);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews *bufferp = buf2;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews return (ISC_R_SUCCESS);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews cleanup:
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_message_renderreset(message);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (buf1 != NULL)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_free(&buf1);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (buf2 != NULL)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_buffer_free(&buf2);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington if (cleanup_cctx)
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington dns_compress_invalidate(&cctx);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews return (result);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson/*
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * If this request is no longer waiting for events,
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * send the completion event. This will ultimately
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * cause the request to be destroyed.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson *
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * Requires:
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * 'request' is locked by the caller.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssonstatic void
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssonsend_if_done(dns_request_t *request, isc_result_t result) {
936036e82337c5aba40e735e5b46f9112869772fMark Andrews if (request->event != NULL && !request->canceling)
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson req_sendevent(request, result);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson}
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson/*
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * Handle the control event.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssonstatic void
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafssondo_cancel(isc_task_t *task, isc_event_t *event) {
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson dns_request_t *request = event->ev_arg;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson UNUSED(task);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson LOCK(&request->requestmgr->locks[request->hash]);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson request->canceling = ISC_FALSE;
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson if (!DNS_REQUEST_CANCELED(request))
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson req_cancel(request);
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson send_if_done(request, ISC_R_CANCELED);
2cf81a3d8a8a12e81a762a0bc3d46e0b117733bfAutomatic Updater UNLOCK(&request->requestmgr->locks[request->hash]);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson}
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafssonvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_request_cancel(dns_request_t *request) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(VALID_REQUEST(request));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews LOCK(&request->requestmgr->locks[request->hash]);
8f17525ebc8ab06446b613f56972dcf063548141Andreas Gustafsson if (!request->canceling && !DNS_REQUEST_CANCELED(request)) {
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson isc_event_t *ev = &request->ctlevent;
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson isc_task_send(request->event->ev_sender, &ev);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson request->canceling = ISC_TRUE;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews }
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsisc_result_t
59abb512d344bfa09012cc11b7d814966f035da4Mark Andrewsdns_request_getresponse(dns_request_t *request, dns_message_t *message,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington unsigned int options)
59abb512d344bfa09012cc11b7d814966f035da4Mark Andrews{
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington isc_result_t result;
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(VALID_REQUEST(request));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(request->answer != NULL);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
8b61d2012063306528286680bd9f086fa868d86eMark Andrews request);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = dns_message_setquerytsig(message, request->tsig);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (result != ISC_R_SUCCESS)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson return (result);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = dns_message_settsigkey(message, request->tsigkey);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (result != ISC_R_SUCCESS)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson return (result);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = dns_message_parse(message, request->answer, options);
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington if (result != ISC_R_SUCCESS)
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington return (result);
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington if (request->tsigkey != NULL)
2483a850e8b82230331defb0e22c67f6b46cfb38Brian Wellington result = dns_tsig_verify(request->answer, message, NULL, NULL);
84a47e20aedd16ba86feb25848732338ad618b16Brian Wellington return (result);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrewsisc_boolean_t
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrewsdns_request_usedtcp(dns_request_t *request) {
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews REQUIRE(VALID_REQUEST(request));
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews return (ISC_TF((request->flags & DNS_REQUEST_F_TCP) != 0));
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews}
7ed73313b1c129c7134d7d33beb82c85bd6d1df4Mark Andrews
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsvoid
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsdns_request_destroy(dns_request_t **requestp) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_request_t *request;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request = *requestp;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
9cb39bbe40998ee14df86609da806441b9e144ceAndreas Gustafsson LOCK(&request->requestmgr->lock);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews LOCK(&request->requestmgr->locks[request->hash]);
9cb39bbe40998ee14df86609da806441b9e144ceAndreas Gustafsson ISC_LIST_UNLINK(request->requestmgr->requests, request, link);
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson INSIST(!DNS_REQUEST_CONNECTING(request));
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews INSIST(!DNS_REQUEST_SENDING(request));
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
9cb39bbe40998ee14df86609da806441b9e144ceAndreas Gustafsson UNLOCK(&request->requestmgr->lock);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson /*
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * These should have been cleaned up by req_cancel() before
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson * the completion event was sent.
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson INSIST(!ISC_LINK_LINKED(request, link));
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson INSIST(request->dispentry == NULL);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson INSIST(request->dispatch == NULL);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson INSIST(request->timer == NULL);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson req_destroy(request);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews *requestp = NULL;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews/***
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews *** Private: request.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ***/
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉static isc_socket_t *
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉req_getsocket(dns_request_t *request) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int dispattr;
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispattr = dns_dispatch_getattributes(request->dispatch);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 INSIST(request->dispentry != NULL);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = dns_dispatch_getentrysocket(request->dispentry);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = dns_dispatch_getsocket(request->dispatch);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews return (sock);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉}
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_connected(isc_task_t *task, isc_event_t *event) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_socketevent_t *sevent = (isc_socketevent_t *)event;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_result_t result;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff dns_request_t *request = event->ev_arg;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
2c12768b4306035c208afc92bace4f3501f051f7Michael Sawyer REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(DNS_REQUEST_CONNECTING(request));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
f53848e17123569387b279578f0100dca5407da5Mark Andrews LOCK(&request->requestmgr->locks[request->hash]);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->flags &= ~DNS_REQUEST_F_CONNECTING;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (DNS_REQUEST_CANCELED(request)) {
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson /*
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson * Send delayed event.
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson */
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson if (DNS_REQUEST_TIMEDOUT(request))
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, ISC_R_TIMEDOUT);
0ad8ee89c532951a55b7de25317eeca2c3b2ed63Andreas Gustafsson else
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, ISC_R_CANCELED);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews } else {
559bb1016f1b00a3661cb2790dc837a977057b86Mark Andrews dns_dispatch_starttcp(request->dispatch);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = sevent->result;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result == ISC_R_SUCCESS)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = req_send(request, task, NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
84d982f168ca104186490a93190c8e28d333026dMark Andrews if (result != ISC_R_SUCCESS) {
f53848e17123569387b279578f0100dca5407da5Mark Andrews req_cancel(request);
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, ISC_R_CANCELED);
f53848e17123569387b279578f0100dca5407da5Mark Andrews }
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews }
f53848e17123569387b279578f0100dca5407da5Mark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_event_free(&event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_senddone(isc_task_t *task, isc_event_t *event) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_socketevent_t *sevent = (isc_socketevent_t *)event;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff dns_request_t *request = event->ev_arg;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews REQUIRE(DNS_REQUEST_SENDING(request));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson UNUSED(task);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews LOCK(&request->requestmgr->locks[request->hash]);
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews request->flags &= ~DNS_REQUEST_F_SENDING;
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews if (DNS_REQUEST_CANCELED(request)) {
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews /*
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews * Send delayed event.
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews */
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews if (DNS_REQUEST_TIMEDOUT(request))
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, ISC_R_TIMEDOUT);
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews else
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, ISC_R_CANCELED);
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews } else if (sevent->result != ISC_R_SUCCESS) {
936036e82337c5aba40e735e5b46f9112869772fMark Andrews req_cancel(request);
936036e82337c5aba40e735e5b46f9112869772fMark Andrews send_if_done(request, ISC_R_CANCELED);
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews }
046a9aca49bdc25bd57d75fd0dd34c021722f095Mark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_event_free(&event);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews}
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_response(isc_task_t *task, isc_event_t *event) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_result_t result;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff dns_request_t *request = event->ev_arg;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_region_t r;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(VALID_REQUEST(request));
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews UNUSED(task);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,
8b61d2012063306528286680bd9f086fa868d86eMark Andrews dns_result_totext(devent->result));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews LOCK(&request->requestmgr->locks[request->hash]);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = devent->result;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews goto done;
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Copy buffer to request.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(&devent->buffer, &r);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(request->mctx, &request->answer,
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence r.length);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews goto done;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = isc_buffer_copyregion(request->answer, &r);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result != ISC_R_SUCCESS)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_buffer_free(&request->answer);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews done:
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Cleanup.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews */
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_removeresponse(&request->dispentry, &devent);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews req_cancel(request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /*
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Send completion event.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews */
8126e45e8cc3fd54517c034dd30a42928f5206e3Andreas Gustafsson send_if_done(request, result);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews}
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_timeout(isc_task_t *task, isc_event_t *event) {
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff dns_request_t *request = event->ev_arg;
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews isc_result_t result;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request);
4be19dcd14cea678511f1d1b269ab89273e987eeMark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews UNUSED(task);
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews LOCK(&request->requestmgr->locks[request->hash]);
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff if (event->ev_type == ISC_TIMEREVENT_TICK &&
e903df2f012869e36251e9a76b13a9aa228fb1acMichael Graff request->udpcount-- != 0) {
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson if (! DNS_REQUEST_SENDING(request)) {
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson result = req_send(request, task, &request->destaddr);
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson if (result != ISC_R_SUCCESS) {
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson req_cancel(request);
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson send_if_done(request, result);
897f762e3caf052688d4ec7b725746cfef09b058Andreas Gustafsson }
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews }
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews } else {
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews request->flags |= DNS_REQUEST_F_TIMEDOUT;
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews req_cancel(request);
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews send_if_done(request, ISC_R_TIMEDOUT);
cf70df7d0e24401a358f0b9c1a616ad0e8c783a6Mark Andrews }
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews UNLOCK(&request->requestmgr->locks[request->hash]);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_event_free(&event);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_sendevent(dns_request_t *request, isc_result_t result) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_task_t *task;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews /*
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews * Lock held by caller.
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff task = request->event->ev_sender;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff request->event->ev_sender = request;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->event->result = result;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_destroy(dns_request_t *request) {
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_t *mctx;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->magic = 0;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->query != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_buffer_free(&request->query);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->answer != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_buffer_free(&request->answer);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->event != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_event_free((isc_event_t **)&request->event);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->dispentry != NULL)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_removeresponse(&request->dispentry, NULL);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->dispatch != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_dispatch_detach(&request->dispatch);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->timer != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_timer_detach(&request->timer);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (request->tsig != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_free(&request->tsig);
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington if (request->tsigkey != NULL)
c27767a7b946f4c6f08d33129691e2d6339e8350Brian Wellington dns_tsigkey_detach(&request->tsigkey);
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington if (request->requestmgr != NULL)
dac1e1dd18b62be8cc3bec1a3656968b7b8633e6Brian Wellington requestmgr_detach(&request->requestmgr);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews mctx = request->mctx;
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_put(mctx, request, sizeof(*request));
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews isc_mem_detach(&mctx);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson/*
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson * Stop the current request. Must be called from the request's task.
8068ceb2a9cc56d18016c3cd94a09e4bb0bc7b0dAndreas Gustafsson */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsreq_cancel(dns_request_t *request) {
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_t *sock;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 unsigned int dispattr;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
390b2077fc751105e40174ceaa1ce34ef06e7dd4Mark Andrews REQUIRE(VALID_REQUEST(request));
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews /*
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews * Lock held by caller.
440164d3e36353a4b9801fcc05fe66b6cf1fb8ceMark Andrews */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews request->flags |= DNS_REQUEST_F_CANCELED;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->timer != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_timer_detach(&request->timer);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 dispattr = dns_dispatch_getattributes(request->dispatch);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = NULL;
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 if (request->dispentry != NULL) {
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = dns_dispatch_getentrysocket(
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 request->dispentry);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 } else
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews sock = dns_dispatch_getsocket(request->dispatch);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews if (DNS_REQUEST_CONNECTING(request) && sock != NULL)
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT);
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews if (DNS_REQUEST_SENDING(request) && sock != NULL)
af669cb4fd7ecfb67ed145b176e5e764b249573bMark Andrews isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND);
386d3a99c190bad55edf44d076e6bd087e230ab8Tatuya JINMEI 神明達哉 }
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (request->dispentry != NULL)
46993e1d9d18410a5852b7d990338b70b158855cMichael Graff dns_dispatch_removeresponse(&request->dispentry, NULL);
a5c30de2601a1d130a15a78cf3dc7610a02b2d85Mark Andrews dns_dispatch_detach(&request->dispatch);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews}
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrewsstatic void
8b61d2012063306528286680bd9f086fa868d86eMark Andrewsreq_log(int level, const char *fmt, ...) {
8b61d2012063306528286680bd9f086fa868d86eMark Andrews va_list ap;
8b61d2012063306528286680bd9f086fa868d86eMark Andrews
8b61d2012063306528286680bd9f086fa868d86eMark Andrews va_start(ap, fmt);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
8b61d2012063306528286680bd9f086fa868d86eMark Andrews DNS_LOGMODULE_REQUEST, level, fmt, ap);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews va_end(ap);
8b61d2012063306528286680bd9f086fa868d86eMark Andrews}