2000-02-24 14:31:43 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
2000-02-24 14:31:43 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
2000-06-22 22:00:42 +00:00
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2018-03-28 14:19:37 +02:00
|
|
|
|
2001-06-04 19:33:39 +00:00
|
|
|
#include <isc/magic.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/mem.h>
|
2000-03-13 20:43:39 +00:00
|
|
|
#include <isc/task.h>
|
|
|
|
#include <isc/timer.h>
|
|
|
|
#include <isc/util.h>
|
|
|
|
|
2000-11-03 02:45:55 +00:00
|
|
|
#include <dns/acl.h>
|
2001-03-05 21:15:47 +00:00
|
|
|
#include <dns/compress.h>
|
2000-03-13 20:43:39 +00:00
|
|
|
#include <dns/dispatch.h>
|
|
|
|
#include <dns/events.h>
|
2000-05-09 05:12:49 +00:00
|
|
|
#include <dns/log.h>
|
2000-03-13 20:43:39 +00:00
|
|
|
#include <dns/message.h>
|
2000-05-24 17:30:41 +00:00
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdatastruct.h>
|
2000-02-24 14:31:43 +00:00
|
|
|
#include <dns/request.h>
|
2000-05-02 03:54:17 +00:00
|
|
|
#include <dns/result.h>
|
2000-05-24 17:30:41 +00:00
|
|
|
#include <dns/tsig.h>
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC)
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
typedef ISC_LIST(dns_request_t) dns_requestlist_t;
|
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
#define DNS_REQUEST_NLOCKS 7
|
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
struct dns_requestmgr {
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int magic;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mutex_t lock;
|
|
|
|
isc_mem_t *mctx;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
|
|
|
/* locked */
|
2020-02-13 14:44:37 -08:00
|
|
|
int32_t eref;
|
|
|
|
int32_t iref;
|
|
|
|
isc_timermgr_t *timermgr;
|
|
|
|
isc_socketmgr_t *socketmgr;
|
|
|
|
isc_taskmgr_t *taskmgr;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_dispatchmgr_t *dispatchmgr;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_t *dispatchv4;
|
|
|
|
dns_dispatch_t *dispatchv6;
|
|
|
|
bool exiting;
|
|
|
|
isc_eventlist_t whenshutdown;
|
|
|
|
unsigned int hash;
|
|
|
|
isc_mutex_t locks[DNS_REQUEST_NLOCKS];
|
|
|
|
dns_requestlist_t requests;
|
2000-02-24 14:31:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct dns_request {
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int magic;
|
|
|
|
unsigned int hash;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mem_t *mctx;
|
|
|
|
int32_t flags;
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LINK(dns_request_t) link;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_buffer_t *query;
|
|
|
|
isc_buffer_t *answer;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_requestevent_t *event;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_dispatch_t *dispatch;
|
|
|
|
dns_dispentry_t *dispentry;
|
|
|
|
isc_timer_t *timer;
|
|
|
|
dns_requestmgr_t *requestmgr;
|
|
|
|
isc_buffer_t *tsig;
|
|
|
|
dns_tsigkey_t *tsigkey;
|
|
|
|
isc_event_t ctlevent;
|
|
|
|
bool canceling; /* ctlevent outstanding */
|
|
|
|
isc_sockaddr_t destaddr;
|
|
|
|
unsigned int udpcount;
|
|
|
|
isc_dscp_t dscp;
|
2000-03-13 20:43:39 +00:00
|
|
|
};
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
#define DNS_REQUEST_F_CONNECTING 0x0001
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_REQUEST_F_SENDING 0x0002
|
|
|
|
#define DNS_REQUEST_F_CANCELED \
|
|
|
|
0x0004 /*%< ctlevent received, or otherwise \
|
|
|
|
* synchronously canceled */
|
|
|
|
#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */
|
|
|
|
#define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */
|
|
|
|
#define DNS_REQUEST_CANCELED(r) (((r)->flags & DNS_REQUEST_F_CANCELED) != 0)
|
2020-02-12 13:59:18 +01:00
|
|
|
#define DNS_REQUEST_CONNECTING(r) (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_REQUEST_SENDING(r) (((r)->flags & DNS_REQUEST_F_SENDING) != 0)
|
|
|
|
#define DNS_REQUEST_TIMEDOUT(r) (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0)
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
/***
|
|
|
|
*** Forward
|
|
|
|
***/
|
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
mgr_destroy(dns_requestmgr_t *requestmgr);
|
|
|
|
static void
|
|
|
|
mgr_shutdown(dns_requestmgr_t *requestmgr);
|
|
|
|
static unsigned int
|
|
|
|
mgr_gethash(dns_requestmgr_t *requestmgr);
|
|
|
|
static void
|
|
|
|
send_shutdown_events(dns_requestmgr_t *requestmgr);
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
req_render(dns_message_t *message, isc_buffer_t **buffer, unsigned int options,
|
|
|
|
isc_mem_t *mctx);
|
|
|
|
static void
|
|
|
|
req_senddone(isc_task_t *task, isc_event_t *event);
|
|
|
|
static void
|
|
|
|
req_response(isc_task_t *task, isc_event_t *event);
|
|
|
|
static void
|
|
|
|
req_timeout(isc_task_t *task, isc_event_t *event);
|
|
|
|
static isc_socket_t *
|
|
|
|
req_getsocket(dns_request_t *request);
|
|
|
|
static void
|
|
|
|
req_connected(isc_task_t *task, isc_event_t *event);
|
|
|
|
static void
|
|
|
|
req_sendevent(dns_request_t *request, isc_result_t result);
|
|
|
|
static void
|
|
|
|
req_cancel(dns_request_t *request);
|
|
|
|
static void
|
|
|
|
req_destroy(dns_request_t *request);
|
|
|
|
static void
|
|
|
|
req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
|
|
|
|
static void
|
|
|
|
do_cancel(isc_task_t *task, isc_event_t *event);
|
2000-02-24 14:31:43 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
*** Public
|
|
|
|
***/
|
|
|
|
|
|
|
|
isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
|
|
|
|
isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
|
2000-05-10 21:34:50 +00:00
|
|
|
dns_dispatchmgr_t *dispatchmgr,
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_requestmgr_t **requestmgrp) {
|
2000-02-24 14:31:43 +00:00
|
|
|
dns_requestmgr_t *requestmgr;
|
2020-02-13 14:44:37 -08:00
|
|
|
int i;
|
|
|
|
unsigned int dispattr;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
|
2000-03-20 12:22:02 +00:00
|
|
|
REQUIRE(timermgr != NULL);
|
|
|
|
REQUIRE(socketmgr != NULL);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
REQUIRE(taskmgr != NULL);
|
2000-05-10 21:34:50 +00:00
|
|
|
REQUIRE(dispatchmgr != NULL);
|
2020-08-06 12:21:50 +10:00
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
if (dispatchv4 != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
dispattr = dns_dispatch_getattributes(dispatchv4);
|
|
|
|
REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
if (dispatchv6 != NULL) {
|
2008-06-23 19:41:20 +00:00
|
|
|
dispattr = dns_dispatch_getattributes(dispatchv6);
|
|
|
|
REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
requestmgr = isc_mem_get(mctx, sizeof(*requestmgr));
|
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&requestmgr->lock);
|
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&requestmgr->locks[i]);
|
2000-03-22 07:00:39 +00:00
|
|
|
}
|
2000-02-24 14:31:43 +00:00
|
|
|
requestmgr->timermgr = timermgr;
|
2000-03-20 12:22:02 +00:00
|
|
|
requestmgr->socketmgr = socketmgr;
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
requestmgr->taskmgr = taskmgr;
|
2000-05-10 21:34:50 +00:00
|
|
|
requestmgr->dispatchmgr = dispatchmgr;
|
2000-02-24 14:31:43 +00:00
|
|
|
requestmgr->dispatchv4 = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispatchv4 != NULL) {
|
2000-03-13 20:43:39 +00:00
|
|
|
dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-24 14:31:43 +00:00
|
|
|
requestmgr->dispatchv6 = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dispatchv6 != NULL) {
|
2000-03-13 20:43:39 +00:00
|
|
|
dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-04-18 08:27:48 +00:00
|
|
|
requestmgr->mctx = NULL;
|
|
|
|
isc_mem_attach(mctx, &requestmgr->mctx);
|
2020-02-12 13:59:18 +01:00
|
|
|
requestmgr->eref = 1; /* implicit attach */
|
2000-04-18 08:27:48 +00:00
|
|
|
requestmgr->iref = 0;
|
2000-02-24 14:31:43 +00:00
|
|
|
ISC_LIST_INIT(requestmgr->whenshutdown);
|
2000-03-20 12:22:02 +00:00
|
|
|
ISC_LIST_INIT(requestmgr->requests);
|
2018-04-17 08:29:14 -07:00
|
|
|
requestmgr->exiting = false;
|
2000-03-22 07:00:39 +00:00
|
|
|
requestmgr->hash = 0;
|
2000-02-24 14:31:43 +00:00
|
|
|
requestmgr->magic = REQUESTMGR_MAGIC;
|
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr);
|
|
|
|
|
|
|
|
*requestmgrp = requestmgr;
|
2000-02-24 14:31:43 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_event_t **eventp) {
|
|
|
|
isc_task_t *tclone;
|
2000-12-11 19:24:30 +00:00
|
|
|
isc_event_t *event;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown");
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-12-11 19:24:30 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
|
|
|
REQUIRE(eventp != NULL);
|
|
|
|
|
|
|
|
event = *eventp;
|
|
|
|
*eventp = NULL;
|
|
|
|
|
|
|
|
LOCK(&requestmgr->lock);
|
|
|
|
|
|
|
|
if (requestmgr->exiting) {
|
|
|
|
/*
|
|
|
|
* We're already shutdown. Send the event.
|
|
|
|
*/
|
|
|
|
event->ev_sender = requestmgr;
|
|
|
|
isc_task_send(task, &event);
|
|
|
|
} else {
|
2016-06-28 21:25:30 -04:00
|
|
|
tclone = NULL;
|
|
|
|
isc_task_attach(task, &tclone);
|
|
|
|
event->ev_sender = tclone;
|
2000-12-11 19:24:30 +00:00
|
|
|
ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) {
|
2000-12-11 19:24:30 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr);
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
LOCK(&requestmgr->lock);
|
2000-03-20 12:22:02 +00:00
|
|
|
mgr_shutdown(requestmgr);
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
}
|
|
|
|
|
2000-08-01 01:33:37 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
mgr_shutdown(dns_requestmgr_t *requestmgr) {
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_request_t *request;
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
/*
|
|
|
|
* Caller holds lock.
|
|
|
|
*/
|
2000-02-24 14:31:43 +00:00
|
|
|
if (!requestmgr->exiting) {
|
2018-04-17 08:29:14 -07:00
|
|
|
requestmgr->exiting = true;
|
2000-03-20 12:22:02 +00:00
|
|
|
for (request = ISC_LIST_HEAD(requestmgr->requests);
|
2020-02-13 14:44:37 -08:00
|
|
|
request != NULL; request = ISC_LIST_NEXT(request, link))
|
|
|
|
{
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_request_cancel(request);
|
|
|
|
}
|
2000-04-20 13:45:36 +00:00
|
|
|
if (requestmgr->iref == 0) {
|
|
|
|
INSIST(ISC_LIST_EMPTY(requestmgr->requests));
|
2000-04-18 08:27:48 +00:00
|
|
|
send_shutdown_events(requestmgr);
|
2000-04-20 13:45:36 +00:00
|
|
|
}
|
2000-04-18 08:27:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
|
2000-04-18 08:27:48 +00:00
|
|
|
/*
|
|
|
|
* Locked by caller.
|
|
|
|
*/
|
|
|
|
|
2000-12-11 19:24:30 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(source));
|
|
|
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
2000-04-18 08:27:48 +00:00
|
|
|
|
|
|
|
REQUIRE(!source->exiting);
|
|
|
|
|
|
|
|
source->iref++;
|
|
|
|
*targetp = source;
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
|
|
|
|
source, source->eref, source->iref);
|
2000-04-18 08:27:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
requestmgr_detach(dns_requestmgr_t **requestmgrp) {
|
2000-04-18 08:27:48 +00:00
|
|
|
dns_requestmgr_t *requestmgr;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool need_destroy = false;
|
2000-04-18 08:27:48 +00:00
|
|
|
|
|
|
|
REQUIRE(requestmgrp != NULL);
|
|
|
|
requestmgr = *requestmgrp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*requestmgrp = NULL;
|
2000-04-18 08:27:48 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
2000-05-09 05:12:49 +00:00
|
|
|
|
2000-04-18 08:27:48 +00:00
|
|
|
LOCK(&requestmgr->lock);
|
|
|
|
INSIST(requestmgr->iref > 0);
|
|
|
|
requestmgr->iref--;
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
|
|
|
|
requestmgr, requestmgr->eref, requestmgr->iref);
|
|
|
|
|
2000-04-20 13:45:36 +00:00
|
|
|
if (requestmgr->iref == 0 && requestmgr->exiting) {
|
|
|
|
INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL);
|
2000-02-24 14:31:43 +00:00
|
|
|
send_shutdown_events(requestmgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (requestmgr->eref == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
need_destroy = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
2000-04-18 08:27:48 +00:00
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (need_destroy) {
|
2000-04-18 08:27:48 +00:00
|
|
|
mgr_destroy(requestmgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
|
2000-12-11 19:24:30 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(source));
|
|
|
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
2000-03-13 20:43:39 +00:00
|
|
|
REQUIRE(!source->exiting);
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-04-18 08:27:48 +00:00
|
|
|
LOCK(&source->lock);
|
|
|
|
source->eref++;
|
2000-02-24 14:31:43 +00:00
|
|
|
*targetp = source;
|
2000-04-18 08:27:48 +00:00
|
|
|
UNLOCK(&source->lock);
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
|
|
|
|
source, source->eref, source->iref);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) {
|
2000-02-24 14:31:43 +00:00
|
|
|
dns_requestmgr_t *requestmgr;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool need_destroy = false;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
|
|
|
REQUIRE(requestmgrp != NULL);
|
2000-03-13 20:43:39 +00:00
|
|
|
requestmgr = *requestmgrp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*requestmgrp = NULL;
|
2000-02-24 14:31:43 +00:00
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
|
|
|
|
|
|
|
LOCK(&requestmgr->lock);
|
2000-04-18 08:27:48 +00:00
|
|
|
INSIST(requestmgr->eref > 0);
|
|
|
|
requestmgr->eref--;
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
|
|
|
|
requestmgr, requestmgr->eref, requestmgr->iref);
|
|
|
|
|
2000-04-18 08:27:48 +00:00
|
|
|
if (requestmgr->eref == 0 && requestmgr->iref == 0) {
|
2000-03-20 12:22:02 +00:00
|
|
|
INSIST(requestmgr->exiting &&
|
|
|
|
ISC_LIST_HEAD(requestmgr->requests) == NULL);
|
2018-04-17 08:29:14 -07:00
|
|
|
need_destroy = true;
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
UNLOCK(&requestmgr->lock);
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (need_destroy) {
|
2000-03-20 12:22:02 +00:00
|
|
|
mgr_destroy(requestmgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
send_shutdown_events(dns_requestmgr_t *requestmgr) {
|
2000-02-24 14:31:43 +00:00
|
|
|
isc_event_t *event, *next_event;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_task_t *etask;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr);
|
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
/*
|
|
|
|
* Caller must be holding the manager lock.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
for (event = ISC_LIST_HEAD(requestmgr->whenshutdown); event != NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
event = next_event)
|
|
|
|
{
|
2000-04-17 19:22:44 +00:00
|
|
|
next_event = ISC_LIST_NEXT(event, ev_link);
|
|
|
|
ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link);
|
|
|
|
etask = event->ev_sender;
|
|
|
|
event->ev_sender = requestmgr;
|
2000-02-24 14:31:43 +00:00
|
|
|
isc_task_sendanddetach(&etask, &event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
mgr_destroy(dns_requestmgr_t *requestmgr) {
|
2000-03-22 07:00:39 +00:00
|
|
|
int i;
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
|
2000-03-22 07:00:39 +00:00
|
|
|
|
2000-04-18 08:27:48 +00:00
|
|
|
REQUIRE(requestmgr->eref == 0);
|
|
|
|
REQUIRE(requestmgr->iref == 0);
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&requestmgr->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&requestmgr->locks[i]);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (requestmgr->dispatchv4 != NULL) {
|
2000-02-24 14:31:43 +00:00
|
|
|
dns_dispatch_detach(&requestmgr->dispatchv4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (requestmgr->dispatchv6 != NULL) {
|
2000-04-18 08:27:48 +00:00
|
|
|
dns_dispatch_detach(&requestmgr->dispatchv6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
requestmgr->magic = 0;
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_mem_putanddetach(&requestmgr->mctx, requestmgr,
|
|
|
|
sizeof(*requestmgr));
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
static unsigned int
|
2020-02-13 14:44:37 -08:00
|
|
|
mgr_gethash(dns_requestmgr_t *requestmgr) {
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "mgr_gethash");
|
2000-03-22 07:00:39 +00:00
|
|
|
/*
|
|
|
|
* Locked by caller.
|
|
|
|
*/
|
|
|
|
requestmgr->hash++;
|
2001-01-23 02:00:56 +00:00
|
|
|
return (requestmgr->hash % DNS_REQUEST_NLOCKS);
|
2000-03-22 07:00:39 +00:00
|
|
|
}
|
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
static inline isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
req_send(dns_request_t *request, isc_task_t *task,
|
2020-02-13 14:44:37 -08:00
|
|
|
const isc_sockaddr_t *address) {
|
|
|
|
isc_region_t r;
|
|
|
|
isc_socket_t *sock;
|
2013-03-22 12:27:54 -07:00
|
|
|
isc_socketevent_t *sendevent;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
|
|
|
|
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = req_getsocket(request);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(request->query, &r);
|
2008-06-23 19:41:20 +00:00
|
|
|
/*
|
|
|
|
* We could connect the socket when we are using an exclusive dispatch
|
|
|
|
* as we do in resolver.c, but we prefer implementation simplicity
|
|
|
|
* at this moment.
|
|
|
|
*/
|
2015-02-27 10:55:55 +11:00
|
|
|
sendevent = isc_socket_socketevent(request->mctx, sock,
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_SOCKEVENT_SENDDONE, req_senddone,
|
|
|
|
request);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (sendevent == NULL) {
|
2015-01-11 09:24:33 +11:00
|
|
|
return (ISC_R_NOMEMORY);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-22 12:27:54 -07:00
|
|
|
if (request->dscp == -1) {
|
|
|
|
sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
|
|
|
|
sendevent->dscp = 0;
|
|
|
|
} else {
|
|
|
|
sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
|
|
|
|
sendevent->dscp = request->dscp;
|
|
|
|
}
|
|
|
|
|
2016-12-14 10:31:26 +11:00
|
|
|
request->flags |= DNS_REQUEST_F_SENDING;
|
2020-02-13 14:44:37 -08:00
|
|
|
result = isc_socket_sendto2(sock, &r, task, address, NULL, sendevent,
|
|
|
|
0);
|
2018-01-16 08:33:30 +01:00
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
2000-12-31 05:05:34 +00:00
|
|
|
return (result);
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
|
|
|
|
2001-01-23 19:50:10 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
new_request(isc_mem_t *mctx, dns_request_t **requestp) {
|
2001-01-23 19:50:10 +00:00
|
|
|
dns_request_t *request;
|
|
|
|
|
|
|
|
request = isc_mem_get(mctx, sizeof(*request));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Zero structure.
|
|
|
|
*/
|
|
|
|
request->magic = 0;
|
|
|
|
request->mctx = NULL;
|
|
|
|
request->flags = 0;
|
|
|
|
ISC_LINK_INIT(request, link);
|
|
|
|
request->query = NULL;
|
|
|
|
request->answer = NULL;
|
|
|
|
request->event = NULL;
|
|
|
|
request->dispatch = NULL;
|
|
|
|
request->dispentry = NULL;
|
|
|
|
request->timer = NULL;
|
|
|
|
request->requestmgr = NULL;
|
|
|
|
request->tsig = NULL;
|
|
|
|
request->tsigkey = NULL;
|
2013-03-22 12:27:54 -07:00
|
|
|
request->dscp = -1;
|
2001-02-13 02:49:07 +00:00
|
|
|
ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL,
|
2020-02-12 13:59:18 +01:00
|
|
|
DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL, NULL,
|
|
|
|
NULL);
|
2018-04-17 08:29:14 -07:00
|
|
|
request->canceling = false;
|
2002-11-12 23:58:14 +00:00
|
|
|
request->udpcount = 0;
|
2001-01-23 19:50:10 +00:00
|
|
|
|
|
|
|
isc_mem_attach(mctx, &request->mctx);
|
|
|
|
|
2001-04-16 18:50:32 +00:00
|
|
|
request->magic = REQUEST_MAGIC;
|
2001-01-23 19:50:10 +00:00
|
|
|
*requestp = request;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2020-02-13 14:44:37 -08:00
|
|
|
isblackholed(dns_dispatchmgr_t *dispatchmgr, const isc_sockaddr_t *destaddr) {
|
|
|
|
dns_acl_t *blackhole;
|
2001-01-23 07:36:06 +00:00
|
|
|
isc_netaddr_t netaddr;
|
2020-02-13 14:44:37 -08:00
|
|
|
int match;
|
|
|
|
bool drop = false;
|
|
|
|
char netaddrstr[ISC_NETADDR_FORMATSIZE];
|
2001-01-23 07:36:06 +00:00
|
|
|
|
2001-02-09 00:23:16 +00:00
|
|
|
blackhole = dns_dispatchmgr_getblackhole(dispatchmgr);
|
2001-01-23 07:36:06 +00:00
|
|
|
if (blackhole != NULL) {
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, destaddr);
|
2020-02-12 13:59:18 +01:00
|
|
|
if (dns_acl_match(&netaddr, NULL, blackhole, NULL, &match,
|
|
|
|
NULL) == ISC_R_SUCCESS &&
|
2020-02-13 14:44:37 -08:00
|
|
|
match > 0)
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
drop = true;
|
2018-04-26 20:57:41 -07:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
}
|
|
|
|
if (drop) {
|
|
|
|
isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr));
|
|
|
|
req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr);
|
|
|
|
}
|
|
|
|
return (drop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
create_tcp_dispatch(bool newtcp, bool share, dns_requestmgr_t *requestmgr,
|
2016-12-30 15:45:08 +11:00
|
|
|
const isc_sockaddr_t *srcaddr,
|
|
|
|
const isc_sockaddr_t *destaddr, isc_dscp_t dscp,
|
2020-02-13 14:44:37 -08:00
|
|
|
bool *connected, dns_dispatch_t **dispatchp) {
|
|
|
|
isc_result_t result;
|
|
|
|
isc_socket_t *sock = NULL;
|
2001-01-23 07:36:06 +00:00
|
|
|
isc_sockaddr_t src;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int attrs;
|
2001-01-23 07:36:06 +00:00
|
|
|
isc_sockaddr_t bind_any;
|
|
|
|
|
2015-01-20 17:22:31 -08:00
|
|
|
if (!newtcp && share) {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr,
|
|
|
|
srcaddr, connected, dispatchp);
|
2015-01-20 17:22:31 -08:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
char peer[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
|
|
|
|
isc_sockaddr_format(destaddr, peer, sizeof(peer));
|
2020-02-12 13:59:18 +01:00
|
|
|
req_log(ISC_LOG_DEBUG(1),
|
|
|
|
"attached to %s TCP "
|
2015-01-20 17:22:31 -08:00
|
|
|
"connection to %s",
|
|
|
|
*connected ? "existing" : "pending", peer);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
} else if (!newtcp) {
|
2014-10-01 07:24:16 +10:00
|
|
|
result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr,
|
2020-02-12 13:59:18 +01:00
|
|
|
srcaddr, NULL, dispatchp);
|
2014-10-01 07:24:16 +10:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
char peer[ISC_SOCKADDR_FORMATSIZE];
|
2014-09-04 14:20:25 +10:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
*connected = true;
|
2014-10-01 07:24:16 +10:00
|
|
|
isc_sockaddr_format(destaddr, peer, sizeof(peer));
|
2020-02-12 13:59:18 +01:00
|
|
|
req_log(ISC_LOG_DEBUG(1),
|
|
|
|
"attached to existing TCP "
|
|
|
|
"connection to %s",
|
|
|
|
peer);
|
2014-10-01 07:24:16 +10:00
|
|
|
return (result);
|
|
|
|
}
|
2014-09-04 10:37:45 +10:00
|
|
|
}
|
|
|
|
|
2001-01-23 07:36:06 +00:00
|
|
|
result = isc_socket_create(requestmgr->socketmgr,
|
|
|
|
isc_sockaddr_pf(destaddr),
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_sockettype_tcp, &sock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 07:36:06 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2006-01-04 04:15:55 +00:00
|
|
|
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
|
2001-01-23 07:36:06 +00:00
|
|
|
if (srcaddr == NULL) {
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_sockaddr_anyofpf(&bind_any, isc_sockaddr_pf(destaddr));
|
2015-02-27 10:55:55 +11:00
|
|
|
result = isc_socket_bind(sock, &bind_any, 0);
|
2001-01-23 07:36:06 +00:00
|
|
|
} else {
|
|
|
|
src = *srcaddr;
|
|
|
|
isc_sockaddr_setport(&src, 0);
|
2015-02-27 10:55:55 +11:00
|
|
|
result = isc_socket_bind(sock, &src, 0);
|
2001-01-23 07:36:06 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 07:36:06 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
#endif /* ifndef BROKEN_TCP_BIND_BEFORE_CONNECT */
|
2013-03-22 12:27:54 -07:00
|
|
|
|
2001-01-23 07:36:06 +00:00
|
|
|
attrs = 0;
|
|
|
|
attrs |= DNS_DISPATCHATTR_TCP;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isc_sockaddr_pf(destaddr) == AF_INET) {
|
2001-01-23 07:36:06 +00:00
|
|
|
attrs |= DNS_DISPATCHATTR_IPV4;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2001-01-23 07:36:06 +00:00
|
|
|
attrs |= DNS_DISPATCHATTR_IPV6;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
2013-03-22 12:27:54 -07:00
|
|
|
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_dscp(sock, dscp);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_dispatch_createtcp(
|
|
|
|
requestmgr->dispatchmgr, sock, requestmgr->taskmgr, srcaddr,
|
|
|
|
destaddr, 4096, 32768, 32768, 16411, 16433, attrs, dispatchp);
|
2001-01-23 07:36:06 +00:00
|
|
|
cleanup:
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_detach(&sock);
|
2001-01-23 07:36:06 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
find_udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr,
|
2020-02-13 14:44:37 -08:00
|
|
|
const isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp) {
|
2001-01-23 07:36:06 +00:00
|
|
|
dns_dispatch_t *disp = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int attrs, attrmask;
|
2001-01-23 07:36:06 +00:00
|
|
|
|
|
|
|
if (srcaddr == NULL) {
|
|
|
|
switch (isc_sockaddr_pf(destaddr)) {
|
|
|
|
case PF_INET:
|
|
|
|
disp = requestmgr->dispatchv4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PF_INET6:
|
|
|
|
disp = requestmgr->dispatchv6;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (disp == NULL) {
|
2001-01-23 07:36:06 +00:00
|
|
|
return (ISC_R_FAMILYNOSUPPORT);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
dns_dispatch_attach(disp, dispatchp);
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
attrs = 0;
|
|
|
|
attrs |= DNS_DISPATCHATTR_UDP;
|
|
|
|
switch (isc_sockaddr_pf(srcaddr)) {
|
|
|
|
case PF_INET:
|
|
|
|
attrs |= DNS_DISPATCHATTR_IPV4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PF_INET6:
|
|
|
|
attrs |= DNS_DISPATCHATTR_IPV6;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
|
|
|
}
|
|
|
|
attrmask = 0;
|
|
|
|
attrmask |= DNS_DISPATCHATTR_UDP;
|
|
|
|
attrmask |= DNS_DISPATCHATTR_TCP;
|
|
|
|
attrmask |= DNS_DISPATCHATTR_IPV4;
|
|
|
|
attrmask |= DNS_DISPATCHATTR_IPV6;
|
|
|
|
return (dns_dispatch_getudp(requestmgr->dispatchmgr,
|
2020-02-12 13:59:18 +01:00
|
|
|
requestmgr->socketmgr, requestmgr->taskmgr,
|
|
|
|
srcaddr, 4096, 32768, 32768, 16411, 16433,
|
|
|
|
attrs, attrmask, dispatchp));
|
2001-01-23 07:36:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
get_dispatch(bool tcp, bool newtcp, bool share, dns_requestmgr_t *requestmgr,
|
2016-12-30 15:45:08 +11:00
|
|
|
const isc_sockaddr_t *srcaddr, const isc_sockaddr_t *destaddr,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_dscp_t dscp, bool *connected, dns_dispatch_t **dispatchp) {
|
2001-01-23 07:36:06 +00:00
|
|
|
isc_result_t result;
|
2014-09-04 10:37:45 +10:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tcp) {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = create_tcp_dispatch(newtcp, share, requestmgr, srcaddr,
|
|
|
|
destaddr, dscp, connected,
|
|
|
|
dispatchp);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = find_udp_dispatch(requestmgr, srcaddr, destaddr,
|
|
|
|
dispatchp);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) {
|
|
|
|
isc_time_t expires;
|
|
|
|
isc_interval_t interval;
|
|
|
|
isc_result_t result;
|
2001-10-18 06:09:39 +00:00
|
|
|
isc_timertype_t timertype;
|
2001-01-23 07:36:06 +00:00
|
|
|
|
|
|
|
isc_interval_set(&interval, timeout, 0);
|
|
|
|
result = isc_time_nowplusinterval(&expires, &interval);
|
2001-10-18 06:09:39 +00:00
|
|
|
isc_interval_set(&interval, udpresend, 0);
|
2001-01-23 07:36:06 +00:00
|
|
|
|
2001-10-18 06:09:39 +00:00
|
|
|
timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = isc_timer_reset(timer, timertype, &expires, &interval,
|
|
|
|
false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-09-11 06:35:57 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
2016-12-30 15:45:08 +11:00
|
|
|
const isc_sockaddr_t *srcaddr,
|
2020-02-12 13:59:18 +01:00
|
|
|
const isc_sockaddr_t *destaddr, isc_dscp_t dscp,
|
|
|
|
unsigned int options, unsigned int timeout,
|
|
|
|
unsigned int udptimeout, unsigned int udpretries,
|
|
|
|
isc_task_t *task, isc_taskaction_t action, void *arg,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_t **requestp) {
|
|
|
|
dns_request_t *request = NULL;
|
|
|
|
isc_task_t *tclone = NULL;
|
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_mem_t *mctx;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_messageid_t id;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool tcp = false;
|
|
|
|
bool newtcp = false;
|
|
|
|
bool share = false;
|
|
|
|
isc_region_t r;
|
|
|
|
bool connected = false;
|
|
|
|
unsigned int dispopt = 0;
|
2000-09-11 06:35:57 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
|
|
|
REQUIRE(msgbuf != NULL);
|
|
|
|
REQUIRE(destaddr != NULL);
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(action != NULL);
|
|
|
|
REQUIRE(requestp != NULL && *requestp == NULL);
|
|
|
|
REQUIRE(timeout > 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (srcaddr != NULL) {
|
2000-10-30 05:08:07 +00:00
|
|
|
REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
|
|
|
mctx = requestmgr->mctx;
|
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isblackholed(requestmgr->dispatchmgr, destaddr)) {
|
2001-01-23 07:36:06 +00:00
|
|
|
return (DNS_R_BLACKHOLED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-03 02:45:55 +00:00
|
|
|
|
2001-01-23 19:50:10 +00:00
|
|
|
request = NULL;
|
|
|
|
result = new_request(mctx, &request);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 19:50:10 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
2002-11-12 23:58:14 +00:00
|
|
|
if (udptimeout == 0 && udpretries != 0) {
|
|
|
|
udptimeout = timeout / (udpretries + 1);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (udptimeout == 0) {
|
2002-11-12 23:58:14 +00:00
|
|
|
udptimeout = 1;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-11-12 23:58:14 +00:00
|
|
|
}
|
2006-08-21 00:35:36 +00:00
|
|
|
request->udpcount = udpretries;
|
2013-03-22 12:27:54 -07:00
|
|
|
request->dscp = dscp;
|
2002-11-12 23:58:14 +00:00
|
|
|
|
2000-09-11 06:35:57 +00:00
|
|
|
/*
|
|
|
|
* Create timer now. We will set it below once.
|
|
|
|
*/
|
|
|
|
result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
|
|
|
|
NULL, NULL, task, req_timeout, request,
|
|
|
|
&request->timer);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-11 06:35:57 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
request->event = (dns_requestevent_t *)isc_event_allocate(
|
|
|
|
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
|
|
|
|
sizeof(dns_requestevent_t));
|
2000-09-11 06:35:57 +00:00
|
|
|
isc_task_attach(task, &tclone);
|
|
|
|
request->event->ev_sender = task;
|
|
|
|
request->event->request = request;
|
|
|
|
request->event->result = ISC_R_FAILURE;
|
|
|
|
|
|
|
|
isc_buffer_usedregion(msgbuf, &r);
|
|
|
|
if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) {
|
|
|
|
result = DNS_R_FORMERR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-06-23 23:47:11 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) {
|
2018-04-17 08:29:14 -07:00
|
|
|
tcp = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
share = (options & DNS_REQUESTOPT_SHARE);
|
2000-09-11 06:35:57 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
again:
|
|
|
|
result = get_dispatch(tcp, newtcp, share, requestmgr, srcaddr, destaddr,
|
|
|
|
dscp, &connected, &request->dispatch);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 07:36:06 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
|
2014-10-01 07:24:16 +10:00
|
|
|
if ((options & DNS_REQUESTOPT_FIXEDID) != 0) {
|
|
|
|
id = (r.base[0] << 8) | r.base[1];
|
|
|
|
dispopt |= DNS_DISPATCHOPT_FIXEDID;
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_dispatch_addresponse(
|
|
|
|
request->dispatch, dispopt, destaddr, task, req_response,
|
|
|
|
request, &id, &request->dispentry, requestmgr->socketmgr);
|
2014-10-01 07:24:16 +10:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
|
2018-04-17 08:29:14 -07:00
|
|
|
newtcp = true;
|
|
|
|
connected = false;
|
2014-10-01 07:24:16 +10:00
|
|
|
dns_dispatch_detach(&request->dispatch);
|
|
|
|
goto again;
|
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
goto cleanup;
|
2014-10-01 07:24:16 +10:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = req_getsocket(request);
|
|
|
|
INSIST(sock != NULL);
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2020-02-02 08:35:46 +01:00
|
|
|
isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tcp) {
|
2018-03-28 14:19:37 +02:00
|
|
|
isc_buffer_putuint16(request->query, (uint16_t)r.length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
result = isc_buffer_copyregion(request->query, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-11 06:35:57 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
|
|
|
/* Add message ID. */
|
|
|
|
isc_buffer_usedregion(request->query, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tcp) {
|
2000-09-11 06:35:57 +00:00
|
|
|
isc_region_consume(&r, 2);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
r.base[0] = (id >> 8) & 0xff;
|
2000-09-11 06:35:57 +00:00
|
|
|
r.base[1] = id & 0xff;
|
|
|
|
|
|
|
|
LOCK(&requestmgr->lock);
|
|
|
|
if (requestmgr->exiting) {
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
result = ISC_R_SHUTTINGDOWN;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
requestmgr_attach(requestmgr, &request->requestmgr);
|
|
|
|
request->hash = mgr_gethash(requestmgr);
|
|
|
|
ISC_LIST_APPEND(requestmgr->requests, request, link);
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
|
2002-11-12 23:58:14 +00:00
|
|
|
result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-11 06:35:57 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
|
2001-10-18 06:09:39 +00:00
|
|
|
request->destaddr = *destaddr;
|
2014-09-04 10:37:45 +10:00
|
|
|
if (tcp && !connected) {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = isc_socket_connect(sock, destaddr, task, req_connected,
|
|
|
|
request);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-11 06:35:57 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
|
2000-09-11 06:35:57 +00:00
|
|
|
} else {
|
2014-09-04 10:37:45 +10:00
|
|
|
result = req_send(request, task, connected ? NULL : destaddr);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-11 06:35:57 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-11 06:35:57 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", request);
|
2000-09-11 06:35:57 +00:00
|
|
|
*requestp = request;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
unlink:
|
2000-09-11 06:35:57 +00:00
|
|
|
LOCK(&requestmgr->lock);
|
|
|
|
ISC_LIST_UNLINK(requestmgr->requests, request, link);
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tclone != NULL) {
|
2000-09-11 06:35:57 +00:00
|
|
|
isc_task_detach(&tclone);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 19:50:10 +00:00
|
|
|
req_destroy(request);
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
|
2000-09-11 06:35:57 +00:00
|
|
|
dns_result_totext(result));
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
2016-12-30 15:45:08 +11:00
|
|
|
const isc_sockaddr_t *address, unsigned int options,
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_tsigkey_t *key, unsigned int timeout, isc_task_t *task,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_taskaction_t action, void *arg,
|
|
|
|
dns_request_t **requestp) {
|
2020-02-12 13:59:18 +01:00
|
|
|
return (dns_request_createvia(requestmgr, message, NULL, address, -1,
|
|
|
|
options, key, timeout, 0, 0, task, action,
|
|
|
|
arg, requestp));
|
2000-10-31 01:17:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
2016-12-30 15:45:08 +11:00
|
|
|
const isc_sockaddr_t *srcaddr,
|
2020-02-12 13:59:18 +01:00
|
|
|
const isc_sockaddr_t *destaddr, isc_dscp_t dscp,
|
|
|
|
unsigned int options, dns_tsigkey_t *key,
|
|
|
|
unsigned int timeout, unsigned int udptimeout,
|
|
|
|
unsigned int udpretries, isc_task_t *task,
|
|
|
|
isc_taskaction_t action, void *arg,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_t **requestp) {
|
|
|
|
dns_request_t *request = NULL;
|
|
|
|
isc_task_t *tclone = NULL;
|
|
|
|
isc_socket_t *sock = NULL;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_mem_t *mctx;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_messageid_t id;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool tcp;
|
|
|
|
bool share;
|
|
|
|
bool settsigkey = true;
|
|
|
|
bool connected = false;
|
2000-02-24 14:31:43 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
|
|
|
REQUIRE(message != NULL);
|
2000-10-31 01:17:19 +00:00
|
|
|
REQUIRE(destaddr != NULL);
|
2000-02-24 14:31:43 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(action != NULL);
|
|
|
|
REQUIRE(requestp != NULL && *requestp == NULL);
|
|
|
|
REQUIRE(timeout > 0);
|
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
mctx = requestmgr->mctx;
|
|
|
|
|
2001-01-23 19:50:10 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
|
2000-05-09 05:12:49 +00:00
|
|
|
|
2013-01-23 15:39:05 -08:00
|
|
|
if (srcaddr != NULL &&
|
2020-02-13 21:48:23 +01:00
|
|
|
isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr)) {
|
2013-01-23 15:39:05 -08:00
|
|
|
return (ISC_R_FAMILYMISMATCH);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-01-23 15:39:05 -08:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isblackholed(requestmgr->dispatchmgr, destaddr)) {
|
2001-01-23 07:36:06 +00:00
|
|
|
return (DNS_R_BLACKHOLED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-03 02:45:55 +00:00
|
|
|
|
2001-01-23 19:50:10 +00:00
|
|
|
request = NULL;
|
|
|
|
result = new_request(mctx, &request);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 19:50:10 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2002-11-12 23:58:14 +00:00
|
|
|
if (udptimeout == 0 && udpretries != 0) {
|
|
|
|
udptimeout = timeout / (udpretries + 1);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (udptimeout == 0) {
|
2002-11-12 23:58:14 +00:00
|
|
|
udptimeout = 1;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-11-12 23:58:14 +00:00
|
|
|
}
|
2006-08-21 00:35:36 +00:00
|
|
|
request->udpcount = udpretries;
|
2013-03-22 12:27:54 -07:00
|
|
|
request->dscp = dscp;
|
2002-11-12 23:58:14 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
/*
|
|
|
|
* Create timer now. We will set it below once.
|
|
|
|
*/
|
|
|
|
result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
|
|
|
|
NULL, NULL, task, req_timeout, request,
|
|
|
|
&request->timer);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-20 12:22:02 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
request->event = (dns_requestevent_t *)isc_event_allocate(
|
|
|
|
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
|
|
|
|
sizeof(dns_requestevent_t));
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_task_attach(task, &tclone);
|
2000-04-17 19:22:44 +00:00
|
|
|
request->event->ev_sender = task;
|
2000-03-20 12:22:02 +00:00
|
|
|
request->event->request = request;
|
|
|
|
request->event->result = ISC_R_FAILURE;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (key != NULL) {
|
2000-07-21 23:00:31 +00:00
|
|
|
dns_tsigkey_attach(key, &request->tsigkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
use_tcp:
|
2018-10-11 11:57:57 +02:00
|
|
|
tcp = ((options & DNS_REQUESTOPT_TCP) != 0);
|
|
|
|
share = ((options & DNS_REQUESTOPT_SHARE) != 0);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = get_dispatch(tcp, false, share, requestmgr, srcaddr, destaddr,
|
2014-10-01 07:24:16 +10:00
|
|
|
dscp, &connected, &request->dispatch);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-01-23 07:36:06 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 07:36:06 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_dispatch_addresponse(
|
|
|
|
request->dispatch, 0, destaddr, task, req_response, request,
|
|
|
|
&id, &request->dispentry, requestmgr->socketmgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = req_getsocket(request);
|
|
|
|
INSIST(sock != NULL);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
message->id = id;
|
2015-02-27 10:55:55 +11:00
|
|
|
if (settsigkey) {
|
2001-11-30 01:59:49 +00:00
|
|
|
result = dns_message_settsigkey(message, request->tsigkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-11-30 01:59:49 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-11-30 01:59:49 +00:00
|
|
|
}
|
2000-06-20 23:54:01 +00:00
|
|
|
result = req_render(message, &request->query, options, mctx);
|
2020-02-12 13:59:18 +01:00
|
|
|
if (result == DNS_R_USETCP && (options & DNS_REQUESTOPT_TCP) == 0) {
|
2000-03-20 12:22:02 +00:00
|
|
|
/*
|
|
|
|
* Try again using TCP.
|
|
|
|
*/
|
|
|
|
dns_message_renderreset(message);
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dns_dispatch_removeresponse(&request->dispentry, NULL);
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_dispatch_detach(&request->dispatch);
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = NULL;
|
2000-03-20 12:22:02 +00:00
|
|
|
options |= DNS_REQUESTOPT_TCP;
|
2018-04-17 08:29:14 -07:00
|
|
|
settsigkey = false;
|
2000-03-20 12:22:02 +00:00
|
|
|
goto use_tcp;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
|
|
|
|
result = dns_message_getquerytsig(message, mctx, &request->tsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-05-30 23:14:57 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
LOCK(&requestmgr->lock);
|
2000-04-18 08:27:48 +00:00
|
|
|
if (requestmgr->exiting) {
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
result = ISC_R_SHUTTINGDOWN;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
requestmgr_attach(requestmgr, &request->requestmgr);
|
2000-03-22 07:00:39 +00:00
|
|
|
request->hash = mgr_gethash(requestmgr);
|
2000-03-20 12:22:02 +00:00
|
|
|
ISC_LIST_APPEND(requestmgr->requests, request, link);
|
|
|
|
UNLOCK(&requestmgr->lock);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2002-11-12 23:58:14 +00:00
|
|
|
result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-04-18 08:27:48 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2001-10-18 06:09:39 +00:00
|
|
|
request->destaddr = *destaddr;
|
2014-09-04 10:37:45 +10:00
|
|
|
if (tcp && !connected) {
|
2020-02-12 13:59:18 +01:00
|
|
|
result = isc_socket_connect(sock, destaddr, task, req_connected,
|
|
|
|
request);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-04-18 08:27:48 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
|
2000-03-20 12:22:02 +00:00
|
|
|
} else {
|
2014-09-04 10:37:45 +10:00
|
|
|
result = req_send(request, task, connected ? NULL : destaddr);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-04-18 08:27:48 +00:00
|
|
|
goto unlink;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", request);
|
2000-03-20 12:22:02 +00:00
|
|
|
*requestp = request;
|
2000-02-24 14:31:43 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
unlink:
|
2000-04-18 08:27:48 +00:00
|
|
|
LOCK(&requestmgr->lock);
|
|
|
|
ISC_LIST_UNLINK(requestmgr->requests, request, link);
|
|
|
|
UNLOCK(&requestmgr->lock);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tclone != NULL) {
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_task_detach(&tclone);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-01-23 19:50:10 +00:00
|
|
|
req_destroy(request);
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
|
2000-05-09 05:12:49 +00:00
|
|
|
dns_result_totext(result));
|
2000-03-13 20:43:39 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
req_render(dns_message_t *message, isc_buffer_t **bufferp, unsigned int options,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mem_t *mctx) {
|
|
|
|
isc_buffer_t *buf1 = NULL;
|
|
|
|
isc_buffer_t *buf2 = NULL;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_region_t r;
|
|
|
|
bool tcp = false;
|
2001-03-05 21:15:47 +00:00
|
|
|
dns_compress_t cctx;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool cleanup_cctx = false;
|
2000-03-13 20:43:39 +00:00
|
|
|
|
|
|
|
REQUIRE(bufferp != NULL && *bufferp == NULL);
|
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "request_render");
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
/*
|
|
|
|
* Create buffer able to hold largest possible message.
|
|
|
|
*/
|
2020-02-02 08:35:46 +01:00
|
|
|
isc_buffer_allocate(mctx, &buf1, 65535);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2001-03-05 21:15:47 +00:00
|
|
|
result = dns_compress_init(&cctx, -1, mctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-03-05 21:15:47 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
cleanup_cctx = true;
|
2001-03-05 21:15:47 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((options & DNS_REQUESTOPT_CASE) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_compress_setsensitive(&cctx, true);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-03-04 05:24:56 +00:00
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
/*
|
|
|
|
* Render message.
|
|
|
|
*/
|
2001-03-05 21:15:47 +00:00
|
|
|
result = dns_message_renderbegin(message, &cctx, buf1);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = dns_message_renderend(message);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2001-03-05 21:15:47 +00:00
|
|
|
dns_compress_invalidate(&cctx);
|
2018-04-17 08:29:14 -07:00
|
|
|
cleanup_cctx = false;
|
2001-03-05 21:15:47 +00:00
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
/*
|
|
|
|
* Copy rendered message to exact sized buffer.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(buf1, &r);
|
2000-06-20 23:54:01 +00:00
|
|
|
if ((options & DNS_REQUESTOPT_TCP) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
tcp = true;
|
2000-06-20 23:54:01 +00:00
|
|
|
} else if (r.length > 512) {
|
|
|
|
result = DNS_R_USETCP;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2020-02-02 08:35:46 +01:00
|
|
|
isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tcp) {
|
2018-03-28 14:19:37 +02:00
|
|
|
isc_buffer_putuint16(buf2, (uint16_t)r.length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
result = isc_buffer_copyregion(buf2, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Cleanup and return.
|
|
|
|
*/
|
|
|
|
isc_buffer_free(&buf1);
|
|
|
|
*bufferp = buf2;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_message_renderreset(message);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (buf1 != NULL) {
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_buffer_free(&buf1);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (buf2 != NULL) {
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_buffer_free(&buf2);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (cleanup_cctx) {
|
2001-03-05 21:15:47 +00:00
|
|
|
dns_compress_invalidate(&cctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
return (result);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
2001-02-13 02:49:07 +00:00
|
|
|
/*
|
|
|
|
* If this request is no longer waiting for events,
|
|
|
|
* send the completion event. This will ultimately
|
|
|
|
* cause the request to be destroyed.
|
|
|
|
*
|
|
|
|
* Requires:
|
|
|
|
* 'request' is locked by the caller.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
send_if_done(dns_request_t *request, isc_result_t result) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (request->event != NULL && !request->canceling) {
|
2001-02-13 02:49:07 +00:00
|
|
|
req_sendevent(request, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-13 02:49:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle the control event.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
do_cancel(isc_task_t *task, isc_event_t *event) {
|
2001-02-13 02:49:07 +00:00
|
|
|
dns_request_t *request = event->ev_arg;
|
|
|
|
UNUSED(task);
|
|
|
|
INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL);
|
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2018-04-17 08:29:14 -07:00
|
|
|
request->canceling = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!DNS_REQUEST_CANCELED(request)) {
|
2001-02-13 02:49:07 +00:00
|
|
|
req_cancel(request);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-08-29 23:52:28 +00:00
|
|
|
send_if_done(request, ISC_R_CANCELED);
|
2008-06-23 23:47:11 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2001-02-13 02:49:07 +00:00
|
|
|
}
|
|
|
|
|
2001-11-30 01:59:49 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_cancel(dns_request_t *request) {
|
2000-03-20 12:22:02 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request);
|
|
|
|
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2001-02-13 21:06:25 +00:00
|
|
|
if (!request->canceling && !DNS_REQUEST_CANCELED(request)) {
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_event_t *ev = &request->ctlevent;
|
2001-02-13 02:49:07 +00:00
|
|
|
isc_task_send(request->event->ev_sender, &ev);
|
2018-04-17 08:29:14 -07:00
|
|
|
request->canceling = true;
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
2000-03-22 07:00:39 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
isc_result_t
|
2000-05-18 02:59:20 +00:00
|
|
|
dns_request_getresponse(dns_request_t *request, dns_message_t *message,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int options) {
|
2000-07-21 20:33:13 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
|
|
|
REQUIRE(request->answer != NULL);
|
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
|
|
|
|
request);
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2001-11-30 01:59:49 +00:00
|
|
|
result = dns_message_setquerytsig(message, request->tsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-11-30 01:59:49 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-11-30 01:59:49 +00:00
|
|
|
result = dns_message_settsigkey(message, request->tsigkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-11-30 01:59:49 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-10-06 18:58:30 +00:00
|
|
|
result = dns_message_parse(message, request->answer, options);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-07-21 20:33:13 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->tsigkey != NULL) {
|
2000-07-21 22:22:55 +00:00
|
|
|
result = dns_tsig_verify(request->answer, message, NULL, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-07-21 20:33:13 +00:00
|
|
|
return (result);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
|
|
|
|
2019-07-20 14:35:59 -04:00
|
|
|
isc_buffer_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_getanswer(dns_request_t *request) {
|
2019-07-20 14:35:59 -04:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
|
|
|
|
|
|
|
return (request->answer);
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_usedtcp(dns_request_t *request) {
|
2000-06-06 02:07:13 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
return ((request->flags & DNS_REQUEST_F_TCP) != 0);
|
2000-06-06 02:07:13 +00:00
|
|
|
}
|
|
|
|
|
2000-02-24 14:31:43 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_destroy(dns_request_t **requestp) {
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_request_t *request;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
request = *requestp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*requestp = NULL;
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request);
|
|
|
|
|
2001-08-29 21:15:56 +00:00
|
|
|
LOCK(&request->requestmgr->lock);
|
2000-03-22 07:00:39 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2001-08-29 21:15:56 +00:00
|
|
|
ISC_LIST_UNLINK(request->requestmgr->requests, request, link);
|
2000-12-22 19:39:01 +00:00
|
|
|
INSIST(!DNS_REQUEST_CONNECTING(request));
|
2000-12-31 05:05:34 +00:00
|
|
|
INSIST(!DNS_REQUEST_SENDING(request));
|
2000-03-22 07:00:39 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2001-08-29 21:15:56 +00:00
|
|
|
UNLOCK(&request->requestmgr->lock);
|
2000-03-22 07:00:39 +00:00
|
|
|
|
2001-02-13 02:49:07 +00:00
|
|
|
/*
|
|
|
|
* These should have been cleaned up by req_cancel() before
|
|
|
|
* the completion event was sent.
|
|
|
|
*/
|
|
|
|
INSIST(!ISC_LINK_LINKED(request, link));
|
|
|
|
INSIST(request->dispentry == NULL);
|
|
|
|
INSIST(request->dispatch == NULL);
|
|
|
|
INSIST(request->timer == NULL);
|
|
|
|
|
2000-12-22 19:39:01 +00:00
|
|
|
req_destroy(request);
|
2000-02-24 14:31:43 +00:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
*** Private: request.
|
|
|
|
***/
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2008-06-23 19:41:20 +00:00
|
|
|
static isc_socket_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
req_getsocket(dns_request_t *request) {
|
|
|
|
unsigned int dispattr;
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_t *sock;
|
2008-06-23 19:41:20 +00:00
|
|
|
|
|
|
|
dispattr = dns_dispatch_getattributes(request->dispatch);
|
|
|
|
if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
|
|
|
|
INSIST(request->dispentry != NULL);
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = dns_dispatch_getentrysocket(request->dispentry);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = dns_dispatch_getsocket(request->dispatch);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
|
2015-02-27 10:55:55 +11:00
|
|
|
return (sock);
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
|
|
|
|
2000-03-13 20:43:39 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_connected(isc_task_t *task, isc_event_t *event) {
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
dns_request_t *request = event->ev_arg;
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-06-10 00:37:05 +00:00
|
|
|
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-03-20 12:22:02 +00:00
|
|
|
REQUIRE(DNS_REQUEST_CONNECTING(request));
|
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-12-19 03:36:48 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-20 12:22:02 +00:00
|
|
|
request->flags &= ~DNS_REQUEST_F_CONNECTING;
|
|
|
|
|
|
|
|
if (DNS_REQUEST_CANCELED(request)) {
|
2000-12-22 19:39:01 +00:00
|
|
|
/*
|
|
|
|
* Send delayed event.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (DNS_REQUEST_TIMEDOUT(request)) {
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, ISC_R_TIMEDOUT);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, ISC_R_CANCELED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
} else {
|
2000-06-20 23:54:01 +00:00
|
|
|
dns_dispatch_starttcp(request->dispatch);
|
2000-03-20 12:22:02 +00:00
|
|
|
result = sevent->result;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2000-03-20 12:22:02 +00:00
|
|
|
result = req_send(request, task, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2001-01-03 23:14:53 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-12-19 03:36:48 +00:00
|
|
|
req_cancel(request);
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, ISC_R_CANCELED);
|
2000-12-19 03:36:48 +00:00
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
2000-12-19 03:36:48 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_event_free(&event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_senddone(isc_task_t *task, isc_event_t *event) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_request_t *request = event->ev_arg;
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-04-17 19:22:44 +00:00
|
|
|
REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-12-31 05:05:34 +00:00
|
|
|
REQUIRE(DNS_REQUEST_SENDING(request));
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
|
|
|
|
|
2000-08-11 16:47:33 +00:00
|
|
|
UNUSED(task);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-12-31 05:05:34 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
|
|
|
request->flags &= ~DNS_REQUEST_F_SENDING;
|
|
|
|
|
|
|
|
if (DNS_REQUEST_CANCELED(request)) {
|
|
|
|
/*
|
|
|
|
* Send delayed event.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (DNS_REQUEST_TIMEDOUT(request)) {
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, ISC_R_TIMEDOUT);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, ISC_R_CANCELED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-12-31 05:05:34 +00:00
|
|
|
} else if (sevent->result != ISC_R_SUCCESS) {
|
2012-02-07 19:50:20 +00:00
|
|
|
req_cancel(request);
|
|
|
|
send_if_done(request, ISC_R_CANCELED);
|
2000-12-31 05:05:34 +00:00
|
|
|
}
|
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
|
|
|
isc_event_free(&event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_response(isc_task_t *task, isc_event_t *event) {
|
|
|
|
isc_result_t result;
|
|
|
|
dns_request_t *request = event->ev_arg;
|
2000-03-13 20:43:39 +00:00
|
|
|
dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_region_t r;
|
2000-03-13 20:43:39 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-04-17 19:22:44 +00:00
|
|
|
REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
|
2000-03-13 20:43:39 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
UNUSED(task);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-05-09 05:12:49 +00:00
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,
|
|
|
|
dns_result_totext(devent->result));
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-20 12:22:02 +00:00
|
|
|
result = devent->result;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-13 20:43:39 +00:00
|
|
|
goto done;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-13 20:43:39 +00:00
|
|
|
|
|
|
|
/*
|
2000-03-20 12:22:02 +00:00
|
|
|
* Copy buffer to request.
|
2000-03-13 20:43:39 +00:00
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&devent->buffer, &r);
|
2020-02-02 08:35:46 +01:00
|
|
|
isc_buffer_allocate(request->mctx, &request->answer, r.length);
|
2000-03-20 12:22:02 +00:00
|
|
|
result = isc_buffer_copyregion(request->answer, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_buffer_free(&request->answer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
done:
|
2000-03-20 12:22:02 +00:00
|
|
|
/*
|
|
|
|
* Cleanup.
|
|
|
|
*/
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dns_dispatch_removeresponse(&request->dispentry, &devent);
|
2000-03-20 12:22:02 +00:00
|
|
|
req_cancel(request);
|
|
|
|
/*
|
|
|
|
* Send completion event.
|
|
|
|
*/
|
2001-02-13 02:49:07 +00:00
|
|
|
send_if_done(request, result);
|
2000-03-22 07:00:39 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-13 20:43:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_timeout(isc_task_t *task, isc_event_t *event) {
|
2000-04-17 19:22:44 +00:00
|
|
|
dns_request_t *request = event->ev_arg;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request);
|
2000-04-20 13:45:36 +00:00
|
|
|
|
2000-03-20 12:22:02 +00:00
|
|
|
UNUSED(task);
|
2000-03-22 07:00:39 +00:00
|
|
|
LOCK(&request->requestmgr->locks[request->hash]);
|
2020-02-12 13:59:18 +01:00
|
|
|
if (event->ev_type == ISC_TIMEREVENT_TICK && request->udpcount-- != 0) {
|
|
|
|
if (!DNS_REQUEST_SENDING(request)) {
|
2001-10-23 23:10:14 +00:00
|
|
|
result = req_send(request, task, &request->destaddr);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
req_cancel(request);
|
|
|
|
send_if_done(request, result);
|
|
|
|
}
|
2001-10-18 06:09:39 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
request->flags |= DNS_REQUEST_F_TIMEDOUT;
|
|
|
|
req_cancel(request);
|
|
|
|
send_if_done(request, ISC_R_TIMEDOUT);
|
|
|
|
}
|
2000-03-22 07:00:39 +00:00
|
|
|
UNLOCK(&request->requestmgr->locks[request->hash]);
|
2000-03-13 20:43:39 +00:00
|
|
|
isc_event_free(&event);
|
|
|
|
}
|
2000-03-20 12:22:02 +00:00
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_sendevent(dns_request_t *request, isc_result_t result) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_task_t *task;
|
|
|
|
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request);
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
/*
|
|
|
|
* Lock held by caller.
|
|
|
|
*/
|
2000-04-17 19:22:44 +00:00
|
|
|
task = request->event->ev_sender;
|
|
|
|
request->event->ev_sender = request;
|
2000-03-20 12:22:02 +00:00
|
|
|
request->event->result = result;
|
|
|
|
isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_destroy(dns_request_t *request) {
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);
|
2000-03-20 12:22:02 +00:00
|
|
|
|
|
|
|
request->magic = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (request->query != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_buffer_free(&request->query);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->answer != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_buffer_free(&request->answer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->event != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_event_free((isc_event_t **)&request->event);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->dispentry != NULL) {
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dns_dispatch_removeresponse(&request->dispentry, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->dispatch != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
dns_dispatch_detach(&request->dispatch);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->timer != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_timer_detach(&request->timer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->tsig != NULL) {
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_free(&request->tsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->tsigkey != NULL) {
|
2000-07-21 23:00:31 +00:00
|
|
|
dns_tsigkey_detach(&request->tsigkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (request->requestmgr != NULL) {
|
2001-01-23 19:50:10 +00:00
|
|
|
requestmgr_detach(&request->requestmgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2019-07-23 17:16:57 -04:00
|
|
|
isc_mem_putanddetach(&request->mctx, request, sizeof(*request));
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
|
|
|
|
2001-08-29 23:52:28 +00:00
|
|
|
/*
|
|
|
|
* Stop the current request. Must be called from the request's task.
|
|
|
|
*/
|
2000-03-20 12:22:02 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_cancel(dns_request_t *request) {
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_t *sock;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int dispattr;
|
2000-03-20 12:22:02 +00:00
|
|
|
|
2000-04-28 22:07:29 +00:00
|
|
|
REQUIRE(VALID_REQUEST(request));
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request);
|
2000-04-18 08:27:48 +00:00
|
|
|
|
2000-03-22 07:00:39 +00:00
|
|
|
/*
|
2000-04-18 08:27:48 +00:00
|
|
|
* Lock held by caller.
|
2000-03-22 07:00:39 +00:00
|
|
|
*/
|
2000-03-20 12:22:02 +00:00
|
|
|
request->flags |= DNS_REQUEST_F_CANCELED;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (request->timer != NULL) {
|
2000-03-20 12:22:02 +00:00
|
|
|
isc_timer_detach(&request->timer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
dispattr = dns_dispatch_getattributes(request->dispatch);
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = NULL;
|
2008-06-23 19:41:20 +00:00
|
|
|
if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) {
|
|
|
|
if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
|
|
|
|
if (request->dispentry != NULL) {
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = dns_dispatch_getentrysocket(
|
2008-06-23 19:41:20 +00:00
|
|
|
request->dispentry);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2015-02-27 10:55:55 +11:00
|
|
|
sock = dns_dispatch_getsocket(request->dispatch);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (DNS_REQUEST_CONNECTING(request) && sock != NULL) {
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (DNS_REQUEST_SENDING(request) && sock != NULL) {
|
2015-02-27 10:55:55 +11:00
|
|
|
isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-06-23 19:41:20 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (request->dispentry != NULL) {
|
Merge the mlg-20000518 branch onto the mainline. Change summary:
dns_dispatch_create() no longer exists. dns_dispatch_createtcp()
and dns_dispatch_getudp() are the replacements. _createtcp() takes
a bound, connected TCP socket, while _getudp() will search for
a sharable UDP socket, and if found, attach to it and return a
pointer to it. If one is not found, it will create a udp socket,
bind it to a supplied local address, and create a new dispatcher
around it.
dns_dispatch_remove{request,response}() no longer take the dispatch
as an argument.
query-source can now be set per view.
The dispatch manager holds onto three memory pools, one for
allocating dispatchers from, one for events, and one for
requests/replies. The free list on these pools is hard-coded,
but set to 1024. This keeps us from having to dig into the
isc_mem_t the pools draw from as often.
dns_resolver_create() and dns_view_createresolver() require that
valid dispatchers be passed in; dispatchers are no longer created
for the caller.
2000-05-19 21:46:46 +00:00
|
|
|
dns_dispatch_removeresponse(&request->dispentry, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-04-18 08:27:48 +00:00
|
|
|
dns_dispatch_detach(&request->dispatch);
|
2000-03-20 12:22:02 +00:00
|
|
|
}
|
2000-05-09 05:12:49 +00:00
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
req_log(int level, const char *fmt, ...) {
|
2000-05-09 05:12:49 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_REQUEST,
|
|
|
|
level, fmt, ap);
|
2000-05-09 05:12:49 +00:00
|
|
|
va_end(ap);
|
|
|
|
}
|