summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/request.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/request.c')
-rw-r--r--contrib/bind9/lib/dns/request.c1461
1 files changed, 0 insertions, 1461 deletions
diff --git a/contrib/bind9/lib/dns/request.c b/contrib/bind9/lib/dns/request.c
deleted file mode 100644
index be8f93d..0000000
--- a/contrib/bind9/lib/dns/request.c
+++ /dev/null
@@ -1,1461 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: request.c,v 1.72.18.5 2006/08/21 00:40:53 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/acl.h>
-#include <dns/compress.h>
-#include <dns/dispatch.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/request.h>
-#include <dns/result.h>
-#include <dns/tsig.h>
-
-#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
-#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
-
-#define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!')
-#define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC)
-
-typedef ISC_LIST(dns_request_t) dns_requestlist_t;
-
-#define DNS_REQUEST_NLOCKS 7
-
-struct dns_requestmgr {
- unsigned int magic;
- isc_mutex_t lock;
- isc_mem_t *mctx;
-
- /* locked */
- isc_int32_t eref;
- isc_int32_t iref;
- isc_timermgr_t *timermgr;
- isc_socketmgr_t *socketmgr;
- isc_taskmgr_t *taskmgr;
- dns_dispatchmgr_t *dispatchmgr;
- dns_dispatch_t *dispatchv4;
- dns_dispatch_t *dispatchv6;
- isc_boolean_t exiting;
- isc_eventlist_t whenshutdown;
- unsigned int hash;
- isc_mutex_t locks[DNS_REQUEST_NLOCKS];
- dns_requestlist_t requests;
-};
-
-struct dns_request {
- unsigned int magic;
- unsigned int hash;
- isc_mem_t *mctx;
- isc_int32_t flags;
- ISC_LINK(dns_request_t) link;
- isc_buffer_t *query;
- isc_buffer_t *answer;
- dns_requestevent_t *event;
- 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;
- isc_boolean_t canceling; /* ctlevent outstanding */
- isc_sockaddr_t destaddr;
- unsigned int udpcount;
-};
-
-#define DNS_REQUEST_F_CONNECTING 0x0001
-#define DNS_REQUEST_F_SENDING 0x0002
-#define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise
- synchronously canceled */
-#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< cancelled 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)
-#define DNS_REQUEST_CONNECTING(r) \
- (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
-#define DNS_REQUEST_SENDING(r) \
- (((r)->flags & DNS_REQUEST_F_SENDING) != 0)
-#define DNS_REQUEST_TIMEDOUT(r) \
- (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0)
-
-
-/***
- *** Forward
- ***/
-
-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 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);
-
-/***
- *** Public
- ***/
-
-isc_result_t
-dns_requestmgr_create(isc_mem_t *mctx,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- isc_taskmgr_t *taskmgr,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6,
- dns_requestmgr_t **requestmgrp)
-{
- dns_requestmgr_t *requestmgr;
- isc_socket_t *socket;
- isc_result_t result;
- int i;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
-
- REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
- REQUIRE(timermgr != NULL);
- REQUIRE(socketmgr != NULL);
- REQUIRE(taskmgr != NULL);
- REQUIRE(dispatchmgr != NULL);
- if (dispatchv4 != NULL) {
- socket = dns_dispatch_getsocket(dispatchv4);
- REQUIRE(isc_socket_gettype(socket) == isc_sockettype_udp);
- }
- if (dispatchv6 != NULL) {
- socket = dns_dispatch_getsocket(dispatchv6);
- REQUIRE(isc_socket_gettype(socket) == isc_sockettype_udp);
- }
-
- requestmgr = isc_mem_get(mctx, sizeof(*requestmgr));
- if (requestmgr == NULL)
- return (ISC_R_NOMEMORY);
-
- result = isc_mutex_init(&requestmgr->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- return (result);
- }
- for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
- result = isc_mutex_init(&requestmgr->locks[i]);
- if (result != ISC_R_SUCCESS) {
- while (--i >= 0)
- DESTROYLOCK(&requestmgr->locks[i]);
- DESTROYLOCK(&requestmgr->lock);
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- return (result);
- }
- }
- requestmgr->timermgr = timermgr;
- requestmgr->socketmgr = socketmgr;
- requestmgr->taskmgr = taskmgr;
- requestmgr->dispatchmgr = dispatchmgr;
- requestmgr->dispatchv4 = NULL;
- if (dispatchv4 != NULL)
- dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
- requestmgr->dispatchv6 = NULL;
- if (dispatchv6 != NULL)
- dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
- requestmgr->mctx = NULL;
- isc_mem_attach(mctx, &requestmgr->mctx);
- requestmgr->eref = 1; /* implict attach */
- requestmgr->iref = 0;
- ISC_LIST_INIT(requestmgr->whenshutdown);
- ISC_LIST_INIT(requestmgr->requests);
- requestmgr->exiting = ISC_FALSE;
- requestmgr->hash = 0;
- requestmgr->magic = REQUESTMGR_MAGIC;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr);
-
- *requestmgrp = requestmgr;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
- isc_event_t **eventp)
-{
- isc_task_t *clone;
- isc_event_t *event;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown");
-
- 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 {
- clone = NULL;
- isc_task_attach(task, &clone);
- event->ev_sender = clone;
- ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link);
- }
- UNLOCK(&requestmgr->lock);
-}
-
-void
-dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) {
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr);
-
- LOCK(&requestmgr->lock);
- mgr_shutdown(requestmgr);
- UNLOCK(&requestmgr->lock);
-}
-
-static void
-mgr_shutdown(dns_requestmgr_t *requestmgr) {
- dns_request_t *request;
-
- /*
- * Caller holds lock.
- */
- if (!requestmgr->exiting) {
- requestmgr->exiting = ISC_TRUE;
- for (request = ISC_LIST_HEAD(requestmgr->requests);
- request != NULL;
- request = ISC_LIST_NEXT(request, link)) {
- dns_request_cancel(request);
- }
- if (requestmgr->iref == 0) {
- INSIST(ISC_LIST_EMPTY(requestmgr->requests));
- send_shutdown_events(requestmgr);
- }
- }
-}
-
-static void
-requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
-
- /*
- * Locked by caller.
- */
-
- REQUIRE(VALID_REQUESTMGR(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- REQUIRE(!source->exiting);
-
- source->iref++;
- *targetp = source;
-
- req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
- source, source->eref, source->iref);
-}
-
-static void
-requestmgr_detach(dns_requestmgr_t **requestmgrp) {
- dns_requestmgr_t *requestmgr;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(requestmgrp != NULL);
- requestmgr = *requestmgrp;
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- *requestmgrp = NULL;
- LOCK(&requestmgr->lock);
- INSIST(requestmgr->iref > 0);
- requestmgr->iref--;
-
- req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
- requestmgr, requestmgr->eref, requestmgr->iref);
-
- if (requestmgr->iref == 0 && requestmgr->exiting) {
- INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL);
- send_shutdown_events(requestmgr);
- if (requestmgr->eref == 0)
- need_destroy = ISC_TRUE;
- }
- UNLOCK(&requestmgr->lock);
-
- if (need_destroy)
- mgr_destroy(requestmgr);
-}
-
-void
-dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
-
- REQUIRE(VALID_REQUESTMGR(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
- REQUIRE(!source->exiting);
-
- LOCK(&source->lock);
- source->eref++;
- *targetp = source;
- UNLOCK(&source->lock);
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
- source, source->eref, source->iref);
-}
-
-void
-dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) {
- dns_requestmgr_t *requestmgr;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(requestmgrp != NULL);
- requestmgr = *requestmgrp;
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- LOCK(&requestmgr->lock);
- INSIST(requestmgr->eref > 0);
- requestmgr->eref--;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
- requestmgr, requestmgr->eref, requestmgr->iref);
-
- if (requestmgr->eref == 0 && requestmgr->iref == 0) {
- INSIST(requestmgr->exiting &&
- ISC_LIST_HEAD(requestmgr->requests) == NULL);
- need_destroy = ISC_TRUE;
- }
- UNLOCK(&requestmgr->lock);
-
- if (need_destroy)
- mgr_destroy(requestmgr);
-
- *requestmgrp = NULL;
-}
-
-static void
-send_shutdown_events(dns_requestmgr_t *requestmgr) {
- isc_event_t *event, *next_event;
- isc_task_t *etask;
-
- req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr);
-
- /*
- * Caller must be holding the manager lock.
- */
- for (event = ISC_LIST_HEAD(requestmgr->whenshutdown);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link);
- etask = event->ev_sender;
- event->ev_sender = requestmgr;
- isc_task_sendanddetach(&etask, &event);
- }
-}
-
-static void
-mgr_destroy(dns_requestmgr_t *requestmgr) {
- int i;
- isc_mem_t *mctx;
-
- req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
-
- REQUIRE(requestmgr->eref == 0);
- REQUIRE(requestmgr->iref == 0);
-
- DESTROYLOCK(&requestmgr->lock);
- for (i = 0; i < DNS_REQUEST_NLOCKS; i++)
- DESTROYLOCK(&requestmgr->locks[i]);
- if (requestmgr->dispatchv4 != NULL)
- dns_dispatch_detach(&requestmgr->dispatchv4);
- if (requestmgr->dispatchv6 != NULL)
- dns_dispatch_detach(&requestmgr->dispatchv6);
- requestmgr->magic = 0;
- mctx = requestmgr->mctx;
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- isc_mem_detach(&mctx);
-}
-
-static unsigned int
-mgr_gethash(dns_requestmgr_t *requestmgr) {
- req_log(ISC_LOG_DEBUG(3), "mgr_gethash");
- /*
- * Locked by caller.
- */
- requestmgr->hash++;
- return (requestmgr->hash % DNS_REQUEST_NLOCKS);
-}
-
-static inline isc_result_t
-req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
- isc_region_t r;
- isc_socket_t *socket;
- isc_result_t result;
-
- req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
-
- REQUIRE(VALID_REQUEST(request));
- socket = dns_dispatch_getsocket(request->dispatch);
- isc_buffer_usedregion(request->query, &r);
- result = isc_socket_sendto(socket, &r, task, req_senddone,
- request, address, NULL);
- if (result == ISC_R_SUCCESS)
- request->flags |= DNS_REQUEST_F_SENDING;
- return (result);
-}
-
-static isc_result_t
-new_request(isc_mem_t *mctx, dns_request_t **requestp) {
- dns_request_t *request;
-
- request = isc_mem_get(mctx, sizeof(*request));
- if (request == NULL)
- return (ISC_R_NOMEMORY);
-
- /*
- * 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;
- ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL,
- DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL,
- NULL, NULL);
- request->canceling = ISC_FALSE;
- request->udpcount = 0;
-
- isc_mem_attach(mctx, &request->mctx);
-
- request->magic = REQUEST_MAGIC;
- *requestp = request;
- return (ISC_R_SUCCESS);
-}
-
-
-static isc_boolean_t
-isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
- dns_acl_t *blackhole;
- isc_netaddr_t netaddr;
- int match;
- isc_boolean_t drop = ISC_FALSE;
- char netaddrstr[ISC_NETADDR_FORMATSIZE];
-
- blackhole = dns_dispatchmgr_getblackhole(dispatchmgr);
- if (blackhole != NULL) {
- isc_netaddr_fromsockaddr(&netaddr, destaddr);
- if (dns_acl_match(&netaddr, NULL, blackhole,
- NULL, &match, NULL) == ISC_R_SUCCESS &&
- match > 0)
- drop = ISC_TRUE;
- }
- 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
-create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
- isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
-{
- isc_result_t result;
- isc_socket_t *socket = NULL;
- isc_sockaddr_t src;
- unsigned int attrs;
- isc_sockaddr_t bind_any;
-
- result = isc_socket_create(requestmgr->socketmgr,
- isc_sockaddr_pf(destaddr),
- isc_sockettype_tcp, &socket);
- if (result != ISC_R_SUCCESS)
- return (result);
-#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- if (srcaddr == NULL) {
- isc_sockaddr_anyofpf(&bind_any,
- isc_sockaddr_pf(destaddr));
- result = isc_socket_bind(socket, &bind_any);
- } else {
- src = *srcaddr;
- isc_sockaddr_setport(&src, 0);
- result = isc_socket_bind(socket, &src);
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-#endif
- attrs = 0;
- attrs |= DNS_DISPATCHATTR_TCP;
- attrs |= DNS_DISPATCHATTR_PRIVATE;
- if (isc_sockaddr_pf(destaddr) == AF_INET)
- attrs |= DNS_DISPATCHATTR_IPV4;
- else
- attrs |= DNS_DISPATCHATTR_IPV6;
- attrs |= DNS_DISPATCHATTR_MAKEQUERY;
- result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
- socket, requestmgr->taskmgr,
- 4096, 2, 1, 1, 3, attrs,
- dispatchp);
-cleanup:
- isc_socket_detach(&socket);
- return (result);
-}
-
-static isc_result_t
-find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
- isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
-{
- dns_dispatch_t *disp = NULL;
- unsigned int attrs, attrmask;
-
- 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);
- }
- if (disp == NULL)
- return (ISC_R_FAMILYNOSUPPORT);
- 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,
- requestmgr->socketmgr,
- requestmgr->taskmgr,
- srcaddr, 4096,
- 1000, 32768, 16411, 16433,
- attrs, attrmask,
- dispatchp));
-}
-
-static isc_result_t
-get_dispatch(isc_boolean_t tcp, dns_requestmgr_t *requestmgr,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- dns_dispatch_t **dispatchp)
-{
- isc_result_t result;
- if (tcp)
- result = create_tcp_dispatch(requestmgr, srcaddr,
- destaddr, dispatchp);
- else
- result = find_udp_dispatch(requestmgr, srcaddr,
- destaddr, dispatchp);
- return (result);
-}
-
-static isc_result_t
-set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) {
- isc_time_t expires;
- isc_interval_t interval;
- isc_result_t result;
- isc_timertype_t timertype;
-
- isc_interval_set(&interval, timeout, 0);
- result = isc_time_nowplusinterval(&expires, &interval);
- isc_interval_set(&interval, udpresend, 0);
-
- timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once;
- if (result == ISC_R_SUCCESS)
- result = isc_timer_reset(timer, timertype, &expires,
- &interval, ISC_FALSE);
- return (result);
-}
-
-isc_result_t
-dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return(dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
- options, timeout, 0, 0, task, action,
- arg, requestp));
-}
-
-isc_result_t
-dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- unsigned int udpretries = 0;
-
- if (udptimeout != 0)
- udpretries = timeout / udptimeout;
-
- return (dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
- options, timeout, udptimeout,
- udpretries, task, action, arg,
- requestp));
-}
-
-isc_result_t
-dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, unsigned int udpretries,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- dns_request_t *request = NULL;
- isc_task_t *tclone = NULL;
- isc_socket_t *socket = NULL;
- isc_result_t result;
- isc_mem_t *mctx;
- dns_messageid_t id;
- isc_boolean_t tcp = ISC_FALSE;
- isc_region_t r;
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
- REQUIRE(msgbuf != NULL);
- REQUIRE(destaddr != NULL);
- REQUIRE(task != NULL);
- REQUIRE(action != NULL);
- REQUIRE(requestp != NULL && *requestp == NULL);
- REQUIRE(timeout > 0);
- if (srcaddr != NULL)
- REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
-
- mctx = requestmgr->mctx;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
-
- if (isblackholed(requestmgr->dispatchmgr, destaddr))
- return (DNS_R_BLACKHOLED);
-
- request = NULL;
- result = new_request(mctx, &request);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (udptimeout == 0 && udpretries != 0) {
- udptimeout = timeout / (udpretries + 1);
- if (udptimeout == 0)
- udptimeout = 1;
- }
- request->udpcount = udpretries;
-
- /*
- * 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);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- request->event = (dns_requestevent_t *)
- isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
- action, arg, sizeof(dns_requestevent_t));
- if (request->event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- 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;
- }
-
- if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
- tcp = ISC_TRUE;
-
- result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
- &request->dispatch);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- socket = dns_dispatch_getsocket(request->dispatch);
- INSIST(socket != NULL);
- result = dns_dispatch_addresponse(request->dispatch, destaddr, task,
- req_response, request, &id,
- &request->dispentry);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = isc_buffer_allocate(mctx, &request->query,
- r.length + (tcp ? 2 : 0));
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (tcp)
- isc_buffer_putuint16(request->query, (isc_uint16_t)r.length);
- result = isc_buffer_copyregion(request->query, &r);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /* Add message ID. */
- isc_buffer_usedregion(request->query, &r);
- if (tcp)
- isc_region_consume(&r, 2);
- r.base[0] = (id>>8) & 0xff;
- 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);
-
- result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
- if (result != ISC_R_SUCCESS)
- goto unlink;
-
- request->destaddr = *destaddr;
- if (tcp) {
- result = isc_socket_connect(socket, destaddr, task,
- req_connected, request);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
- } else {
- result = req_send(request, task, destaddr);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- }
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p",
- request);
- *requestp = request;
- return (ISC_R_SUCCESS);
-
- unlink:
- LOCK(&requestmgr->lock);
- ISC_LIST_UNLINK(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- cleanup:
- if (tclone != NULL)
- isc_task_detach(&tclone);
- req_destroy(request);
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
- dns_result_totext(result));
- return (result);
-}
-
-isc_result_t
-dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *address, unsigned int options,
- dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return (dns_request_createvia3(requestmgr, message, NULL, address,
- options, key, timeout, 0, 0, task,
- action, arg, requestp));
-}
-
-isc_result_t
-dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return(dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
- options, key, timeout, 0, 0, task,
- action, arg, requestp));
-}
-
-isc_result_t
-dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udptimeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- unsigned int udpretries = 0;
-
- if (udptimeout != 0)
- udpretries = timeout / udptimeout;
- return (dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
- options, key, timeout, udptimeout,
- udpretries, task, action, arg,
- requestp));
-}
-
-isc_result_t
-dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- 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,
- dns_request_t **requestp)
-{
- dns_request_t *request = NULL;
- isc_task_t *tclone = NULL;
- isc_socket_t *socket = NULL;
- isc_result_t result;
- isc_mem_t *mctx;
- dns_messageid_t id;
- isc_boolean_t tcp;
- isc_boolean_t setkey = ISC_TRUE;
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
- REQUIRE(message != NULL);
- REQUIRE(destaddr != NULL);
- REQUIRE(task != NULL);
- REQUIRE(action != NULL);
- REQUIRE(requestp != NULL && *requestp == NULL);
- REQUIRE(timeout > 0);
- if (srcaddr != NULL)
- REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
-
- mctx = requestmgr->mctx;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
-
- if (isblackholed(requestmgr->dispatchmgr, destaddr))
- return (DNS_R_BLACKHOLED);
-
- request = NULL;
- result = new_request(mctx, &request);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (udptimeout == 0 && udpretries != 0) {
- udptimeout = timeout / (udpretries + 1);
- if (udptimeout == 0)
- udptimeout = 1;
- }
- request->udpcount = udpretries;
-
- /*
- * 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);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- request->event = (dns_requestevent_t *)
- isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
- action, arg, sizeof(dns_requestevent_t));
- if (request->event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- isc_task_attach(task, &tclone);
- request->event->ev_sender = task;
- request->event->request = request;
- request->event->result = ISC_R_FAILURE;
- if (key != NULL)
- dns_tsigkey_attach(key, &request->tsigkey);
-
- use_tcp:
- tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
- result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
- &request->dispatch);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- socket = dns_dispatch_getsocket(request->dispatch);
- INSIST(socket != NULL);
- result = dns_dispatch_addresponse(request->dispatch, destaddr, task,
- req_response, request, &id,
- &request->dispentry);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- message->id = id;
- if (setkey) {
- result = dns_message_settsigkey(message, request->tsigkey);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
- result = req_render(message, &request->query, options, mctx);
- if (result == DNS_R_USETCP &&
- (options & DNS_REQUESTOPT_TCP) == 0) {
- /*
- * Try again using TCP.
- */
- dns_message_renderreset(message);
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- dns_dispatch_detach(&request->dispatch);
- socket = NULL;
- options |= DNS_REQUESTOPT_TCP;
- setkey = ISC_FALSE;
- goto use_tcp;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_message_getquerytsig(message, mctx, &request->tsig);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- 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);
-
- result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
- if (result != ISC_R_SUCCESS)
- goto unlink;
-
- request->destaddr = *destaddr;
- if (tcp) {
- result = isc_socket_connect(socket, destaddr, task,
- req_connected, request);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
- } else {
- result = req_send(request, task, destaddr);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- }
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p",
- request);
- *requestp = request;
- return (ISC_R_SUCCESS);
-
- unlink:
- LOCK(&requestmgr->lock);
- ISC_LIST_UNLINK(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- cleanup:
- if (tclone != NULL)
- isc_task_detach(&tclone);
- req_destroy(request);
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
- dns_result_totext(result));
- return (result);
-}
-
-static isc_result_t
-req_render(dns_message_t *message, isc_buffer_t **bufferp,
- unsigned int options, isc_mem_t *mctx)
-{
- isc_buffer_t *buf1 = NULL;
- isc_buffer_t *buf2 = NULL;
- isc_result_t result;
- isc_region_t r;
- isc_boolean_t tcp = ISC_FALSE;
- dns_compress_t cctx;
- isc_boolean_t cleanup_cctx = ISC_FALSE;
-
- REQUIRE(bufferp != NULL && *bufferp == NULL);
-
- req_log(ISC_LOG_DEBUG(3), "request_render");
-
- /*
- * Create buffer able to hold largest possible message.
- */
- result = isc_buffer_allocate(mctx, &buf1, 65535);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_compress_init(&cctx, -1, mctx);
- if (result != ISC_R_SUCCESS)
- return (result);
- cleanup_cctx = ISC_TRUE;
-
- /*
- * Render message.
- */
- result = dns_message_renderbegin(message, &cctx, buf1);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_renderend(message);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_compress_invalidate(&cctx);
- cleanup_cctx = ISC_FALSE;
-
- /*
- * Copy rendered message to exact sized buffer.
- */
- isc_buffer_usedregion(buf1, &r);
- if ((options & DNS_REQUESTOPT_TCP) != 0) {
- tcp = ISC_TRUE;
- } else if (r.length > 512) {
- result = DNS_R_USETCP;
- goto cleanup;
- }
- result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (tcp)
- isc_buffer_putuint16(buf2, (isc_uint16_t)r.length);
- result = isc_buffer_copyregion(buf2, &r);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Cleanup and return.
- */
- isc_buffer_free(&buf1);
- *bufferp = buf2;
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_message_renderreset(message);
- if (buf1 != NULL)
- isc_buffer_free(&buf1);
- if (buf2 != NULL)
- isc_buffer_free(&buf2);
- if (cleanup_cctx)
- dns_compress_invalidate(&cctx);
- return (result);
-}
-
-
-/*
- * 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
-send_if_done(dns_request_t *request, isc_result_t result) {
- if (!DNS_REQUEST_CONNECTING(request) &&
- !DNS_REQUEST_SENDING(request) &&
- !request->canceling)
- req_sendevent(request, result);
-}
-
-/*
- * Handle the control event.
- */
-static void
-do_cancel(isc_task_t *task, isc_event_t *event) {
- dns_request_t *request = event->ev_arg;
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL);
- LOCK(&request->requestmgr->locks[request->hash]);
- request->canceling = ISC_FALSE;
- if (!DNS_REQUEST_CANCELED(request))
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-void
-dns_request_cancel(dns_request_t *request) {
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request);
-
- REQUIRE(VALID_REQUEST(request));
-
- LOCK(&request->requestmgr->locks[request->hash]);
- if (!request->canceling && !DNS_REQUEST_CANCELED(request)) {
- isc_event_t *ev = &request->ctlevent;
- isc_task_send(request->event->ev_sender, &ev);
- request->canceling = ISC_TRUE;
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-isc_result_t
-dns_request_getresponse(dns_request_t *request, dns_message_t *message,
- unsigned int options)
-{
- isc_result_t result;
-
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(request->answer != NULL);
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
- request);
-
- result = dns_message_setquerytsig(message, request->tsig);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_settsigkey(message, request->tsigkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_parse(message, request->answer, options);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (request->tsigkey != NULL)
- result = dns_tsig_verify(request->answer, message, NULL, NULL);
- return (result);
-}
-
-isc_boolean_t
-dns_request_usedtcp(dns_request_t *request) {
- REQUIRE(VALID_REQUEST(request));
-
- return (ISC_TF((request->flags & DNS_REQUEST_F_TCP) != 0));
-}
-
-void
-dns_request_destroy(dns_request_t **requestp) {
- dns_request_t *request;
-
- REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));
-
- request = *requestp;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request);
-
- LOCK(&request->requestmgr->lock);
- LOCK(&request->requestmgr->locks[request->hash]);
- ISC_LIST_UNLINK(request->requestmgr->requests, request, link);
- INSIST(!DNS_REQUEST_CONNECTING(request));
- INSIST(!DNS_REQUEST_SENDING(request));
- UNLOCK(&request->requestmgr->locks[request->hash]);
- UNLOCK(&request->requestmgr->lock);
-
- /*
- * 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);
-
- req_destroy(request);
-
- *requestp = NULL;
-}
-
-/***
- *** Private: request.
- ***/
-
-static void
-req_connected(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- isc_result_t result;
- dns_request_t *request = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(DNS_REQUEST_CONNECTING(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);
-
- LOCK(&request->requestmgr->locks[request->hash]);
- request->flags &= ~DNS_REQUEST_F_CONNECTING;
-
- if (DNS_REQUEST_CANCELED(request)) {
- /*
- * Send delayed event.
- */
- if (DNS_REQUEST_TIMEDOUT(request))
- send_if_done(request, ISC_R_TIMEDOUT);
- else
- send_if_done(request, ISC_R_CANCELED);
- } else {
- dns_dispatch_starttcp(request->dispatch);
- result = sevent->result;
- if (result == ISC_R_SUCCESS)
- result = req_send(request, task, NULL);
-
- if (result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- }
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
- isc_event_free(&event);
-}
-
-static void
-req_senddone(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- dns_request_t *request = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(DNS_REQUEST_SENDING(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
-
- UNUSED(task);
-
- LOCK(&request->requestmgr->locks[request->hash]);
- request->flags &= ~DNS_REQUEST_F_SENDING;
-
- if (DNS_REQUEST_CANCELED(request)) {
- /*
- * Send delayed event.
- */
- if (DNS_REQUEST_TIMEDOUT(request))
- send_if_done(request, ISC_R_TIMEDOUT);
- else
- send_if_done(request, ISC_R_CANCELED);
- } else if (sevent->result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
-
- isc_event_free(&event);
-}
-
-static void
-req_response(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- dns_request_t *request = event->ev_arg;
- dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
- isc_region_t r;
-
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
-
- UNUSED(task);
-
- req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,
- dns_result_totext(devent->result));
-
- LOCK(&request->requestmgr->locks[request->hash]);
- result = devent->result;
- if (result != ISC_R_SUCCESS)
- goto done;
-
- /*
- * Copy buffer to request.
- */
- isc_buffer_usedregion(&devent->buffer, &r);
- result = isc_buffer_allocate(request->mctx, &request->answer,
- r.length);
- if (result != ISC_R_SUCCESS)
- goto done;
- result = isc_buffer_copyregion(request->answer, &r);
- if (result != ISC_R_SUCCESS)
- isc_buffer_free(&request->answer);
- done:
- /*
- * Cleanup.
- */
- dns_dispatch_removeresponse(&request->dispentry, &devent);
- req_cancel(request);
- /*
- * Send completion event.
- */
- send_if_done(request, result);
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-static void
-req_timeout(isc_task_t *task, isc_event_t *event) {
- dns_request_t *request = event->ev_arg;
- isc_result_t result;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request);
-
- UNUSED(task);
- LOCK(&request->requestmgr->locks[request->hash]);
- if (event->ev_type == ISC_TIMEREVENT_TICK &&
- request->udpcount-- != 0) {
- if (! DNS_REQUEST_SENDING(request)) {
- result = req_send(request, task, &request->destaddr);
- if (result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, result);
- }
- }
- } else {
- request->flags |= DNS_REQUEST_F_TIMEDOUT;
- req_cancel(request);
- send_if_done(request, ISC_R_TIMEDOUT);
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
- isc_event_free(&event);
-}
-
-static void
-req_sendevent(dns_request_t *request, isc_result_t result) {
- isc_task_t *task;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request);
-
- /*
- * Lock held by caller.
- */
- task = request->event->ev_sender;
- request->event->ev_sender = request;
- request->event->result = result;
- isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
-}
-
-static void
-req_destroy(dns_request_t *request) {
- isc_mem_t *mctx;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);
-
- request->magic = 0;
- if (request->query != NULL)
- isc_buffer_free(&request->query);
- if (request->answer != NULL)
- isc_buffer_free(&request->answer);
- if (request->event != NULL)
- isc_event_free((isc_event_t **)&request->event);
- if (request->dispentry != NULL)
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- if (request->dispatch != NULL)
- dns_dispatch_detach(&request->dispatch);
- if (request->timer != NULL)
- isc_timer_detach(&request->timer);
- if (request->tsig != NULL)
- isc_buffer_free(&request->tsig);
- if (request->tsigkey != NULL)
- dns_tsigkey_detach(&request->tsigkey);
- if (request->requestmgr != NULL)
- requestmgr_detach(&request->requestmgr);
- mctx = request->mctx;
- isc_mem_put(mctx, request, sizeof(*request));
- isc_mem_detach(&mctx);
-}
-
-/*
- * Stop the current request. Must be called from the request's task.
- */
-static void
-req_cancel(dns_request_t *request) {
- isc_socket_t *socket;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request);
-
- /*
- * Lock held by caller.
- */
- request->flags |= DNS_REQUEST_F_CANCELED;
-
- if (request->timer != NULL)
- isc_timer_detach(&request->timer);
- if (request->dispentry != NULL)
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- if (DNS_REQUEST_CONNECTING(request)) {
- socket = dns_dispatch_getsocket(request->dispatch);
- isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT);
- }
- if (DNS_REQUEST_SENDING(request)) {
- socket = dns_dispatch_getsocket(request->dispatch);
- isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
- }
- dns_dispatch_detach(&request->dispatch);
-}
-
-static void
-req_log(int level, const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_REQUEST, level, fmt, ap);
- va_end(ap);
-}
OpenPOWER on IntegriCloud