2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: request.c,v 1.79.128.5 2009/01/19 23:47:02 tbox Exp $ */
24 #include <isc/magic.h>
27 #include <isc/timer.h>
31 #include <dns/compress.h>
32 #include <dns/dispatch.h>
33 #include <dns/events.h>
35 #include <dns/message.h>
36 #include <dns/rdata.h>
37 #include <dns/rdatastruct.h>
38 #include <dns/request.h>
39 #include <dns/result.h>
42 #define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
43 #define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
45 #define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!')
46 #define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC)
48 typedef ISC_LIST(dns_request_t
) dns_requestlist_t
;
50 #define DNS_REQUEST_NLOCKS 7
52 struct dns_requestmgr
{
60 isc_timermgr_t
*timermgr
;
61 isc_socketmgr_t
*socketmgr
;
62 isc_taskmgr_t
*taskmgr
;
63 dns_dispatchmgr_t
*dispatchmgr
;
64 dns_dispatch_t
*dispatchv4
;
65 dns_dispatch_t
*dispatchv6
;
66 isc_boolean_t exiting
;
67 isc_eventlist_t whenshutdown
;
69 isc_mutex_t locks
[DNS_REQUEST_NLOCKS
];
70 dns_requestlist_t requests
;
78 ISC_LINK(dns_request_t
) link
;
81 dns_requestevent_t
*event
;
82 dns_dispatch_t
*dispatch
;
83 dns_dispentry_t
*dispentry
;
85 dns_requestmgr_t
*requestmgr
;
87 dns_tsigkey_t
*tsigkey
;
89 isc_boolean_t canceling
; /* ctlevent outstanding */
90 isc_sockaddr_t destaddr
;
91 unsigned int udpcount
;
94 #define DNS_REQUEST_F_CONNECTING 0x0001
95 #define DNS_REQUEST_F_SENDING 0x0002
96 #define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise
97 synchronously canceled */
98 #define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */
99 #define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */
100 #define DNS_REQUEST_CANCELED(r) \
101 (((r)->flags & DNS_REQUEST_F_CANCELED) != 0)
102 #define DNS_REQUEST_CONNECTING(r) \
103 (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
104 #define DNS_REQUEST_SENDING(r) \
105 (((r)->flags & DNS_REQUEST_F_SENDING) != 0)
106 #define DNS_REQUEST_TIMEDOUT(r) \
107 (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0)
114 static void mgr_destroy(dns_requestmgr_t
*requestmgr
);
115 static void mgr_shutdown(dns_requestmgr_t
*requestmgr
);
116 static unsigned int mgr_gethash(dns_requestmgr_t
*requestmgr
);
117 static void send_shutdown_events(dns_requestmgr_t
*requestmgr
);
119 static isc_result_t
req_render(dns_message_t
*message
, isc_buffer_t
**buffer
,
120 unsigned int options
, isc_mem_t
*mctx
);
121 static void req_senddone(isc_task_t
*task
, isc_event_t
*event
);
122 static void req_response(isc_task_t
*task
, isc_event_t
*event
);
123 static void req_timeout(isc_task_t
*task
, isc_event_t
*event
);
124 static isc_socket_t
* req_getsocket(dns_request_t
*request
);
125 static void req_connected(isc_task_t
*task
, isc_event_t
*event
);
126 static void req_sendevent(dns_request_t
*request
, isc_result_t result
);
127 static void req_cancel(dns_request_t
*request
);
128 static void req_destroy(dns_request_t
*request
);
129 static void req_log(int level
, const char *fmt
, ...) ISC_FORMAT_PRINTF(2, 3);
130 static void do_cancel(isc_task_t
*task
, isc_event_t
*event
);
137 dns_requestmgr_create(isc_mem_t
*mctx
,
138 isc_timermgr_t
*timermgr
,
139 isc_socketmgr_t
*socketmgr
,
140 isc_taskmgr_t
*taskmgr
,
141 dns_dispatchmgr_t
*dispatchmgr
,
142 dns_dispatch_t
*dispatchv4
,
143 dns_dispatch_t
*dispatchv6
,
144 dns_requestmgr_t
**requestmgrp
)
146 dns_requestmgr_t
*requestmgr
;
147 isc_socket_t
*socket
;
150 unsigned int dispattr
;
152 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
154 REQUIRE(requestmgrp
!= NULL
&& *requestmgrp
== NULL
);
155 REQUIRE(timermgr
!= NULL
);
156 REQUIRE(socketmgr
!= NULL
);
157 REQUIRE(taskmgr
!= NULL
);
158 REQUIRE(dispatchmgr
!= NULL
);
160 if (dispatchv4
!= NULL
) {
161 dispattr
= dns_dispatch_getattributes(dispatchv4
);
162 REQUIRE((dispattr
& DNS_DISPATCHATTR_UDP
) != 0);
164 if (dispatchv6
!= NULL
) {
165 dispattr
= dns_dispatch_getattributes(dispatchv6
);
166 REQUIRE((dispattr
& DNS_DISPATCHATTR_UDP
) != 0);
169 requestmgr
= isc_mem_get(mctx
, sizeof(*requestmgr
));
170 if (requestmgr
== NULL
)
171 return (ISC_R_NOMEMORY
);
173 result
= isc_mutex_init(&requestmgr
->lock
);
174 if (result
!= ISC_R_SUCCESS
) {
175 isc_mem_put(mctx
, requestmgr
, sizeof(*requestmgr
));
178 for (i
= 0; i
< DNS_REQUEST_NLOCKS
; i
++) {
179 result
= isc_mutex_init(&requestmgr
->locks
[i
]);
180 if (result
!= ISC_R_SUCCESS
) {
182 DESTROYLOCK(&requestmgr
->locks
[i
]);
183 DESTROYLOCK(&requestmgr
->lock
);
184 isc_mem_put(mctx
, requestmgr
, sizeof(*requestmgr
));
188 requestmgr
->timermgr
= timermgr
;
189 requestmgr
->socketmgr
= socketmgr
;
190 requestmgr
->taskmgr
= taskmgr
;
191 requestmgr
->dispatchmgr
= dispatchmgr
;
192 requestmgr
->dispatchv4
= NULL
;
193 if (dispatchv4
!= NULL
)
194 dns_dispatch_attach(dispatchv4
, &requestmgr
->dispatchv4
);
195 requestmgr
->dispatchv6
= NULL
;
196 if (dispatchv6
!= NULL
)
197 dns_dispatch_attach(dispatchv6
, &requestmgr
->dispatchv6
);
198 requestmgr
->mctx
= NULL
;
199 isc_mem_attach(mctx
, &requestmgr
->mctx
);
200 requestmgr
->eref
= 1; /* implicit attach */
201 requestmgr
->iref
= 0;
202 ISC_LIST_INIT(requestmgr
->whenshutdown
);
203 ISC_LIST_INIT(requestmgr
->requests
);
204 requestmgr
->exiting
= ISC_FALSE
;
205 requestmgr
->hash
= 0;
206 requestmgr
->magic
= REQUESTMGR_MAGIC
;
208 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr
);
210 *requestmgrp
= requestmgr
;
211 return (ISC_R_SUCCESS
);
215 dns_requestmgr_whenshutdown(dns_requestmgr_t
*requestmgr
, isc_task_t
*task
,
216 isc_event_t
**eventp
)
221 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown");
223 REQUIRE(VALID_REQUESTMGR(requestmgr
));
224 REQUIRE(eventp
!= NULL
);
229 LOCK(&requestmgr
->lock
);
231 if (requestmgr
->exiting
) {
233 * We're already shutdown. Send the event.
235 event
->ev_sender
= requestmgr
;
236 isc_task_send(task
, &event
);
239 isc_task_attach(task
, &clone
);
240 event
->ev_sender
= clone
;
241 ISC_LIST_APPEND(requestmgr
->whenshutdown
, event
, ev_link
);
243 UNLOCK(&requestmgr
->lock
);
247 dns_requestmgr_shutdown(dns_requestmgr_t
*requestmgr
) {
249 REQUIRE(VALID_REQUESTMGR(requestmgr
));
251 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr
);
253 LOCK(&requestmgr
->lock
);
254 mgr_shutdown(requestmgr
);
255 UNLOCK(&requestmgr
->lock
);
259 mgr_shutdown(dns_requestmgr_t
*requestmgr
) {
260 dns_request_t
*request
;
265 if (!requestmgr
->exiting
) {
266 requestmgr
->exiting
= ISC_TRUE
;
267 for (request
= ISC_LIST_HEAD(requestmgr
->requests
);
269 request
= ISC_LIST_NEXT(request
, link
)) {
270 dns_request_cancel(request
);
272 if (requestmgr
->iref
== 0) {
273 INSIST(ISC_LIST_EMPTY(requestmgr
->requests
));
274 send_shutdown_events(requestmgr
);
280 requestmgr_attach(dns_requestmgr_t
*source
, dns_requestmgr_t
**targetp
) {
286 REQUIRE(VALID_REQUESTMGR(source
));
287 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
289 REQUIRE(!source
->exiting
);
294 req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
295 source
, source
->eref
, source
->iref
);
299 requestmgr_detach(dns_requestmgr_t
**requestmgrp
) {
300 dns_requestmgr_t
*requestmgr
;
301 isc_boolean_t need_destroy
= ISC_FALSE
;
303 REQUIRE(requestmgrp
!= NULL
);
304 requestmgr
= *requestmgrp
;
305 REQUIRE(VALID_REQUESTMGR(requestmgr
));
308 LOCK(&requestmgr
->lock
);
309 INSIST(requestmgr
->iref
> 0);
312 req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
313 requestmgr
, requestmgr
->eref
, requestmgr
->iref
);
315 if (requestmgr
->iref
== 0 && requestmgr
->exiting
) {
316 INSIST(ISC_LIST_HEAD(requestmgr
->requests
) == NULL
);
317 send_shutdown_events(requestmgr
);
318 if (requestmgr
->eref
== 0)
319 need_destroy
= ISC_TRUE
;
321 UNLOCK(&requestmgr
->lock
);
324 mgr_destroy(requestmgr
);
328 dns_requestmgr_attach(dns_requestmgr_t
*source
, dns_requestmgr_t
**targetp
) {
330 REQUIRE(VALID_REQUESTMGR(source
));
331 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
332 REQUIRE(!source
->exiting
);
337 UNLOCK(&source
->lock
);
339 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
340 source
, source
->eref
, source
->iref
);
344 dns_requestmgr_detach(dns_requestmgr_t
**requestmgrp
) {
345 dns_requestmgr_t
*requestmgr
;
346 isc_boolean_t need_destroy
= ISC_FALSE
;
348 REQUIRE(requestmgrp
!= NULL
);
349 requestmgr
= *requestmgrp
;
350 REQUIRE(VALID_REQUESTMGR(requestmgr
));
352 LOCK(&requestmgr
->lock
);
353 INSIST(requestmgr
->eref
> 0);
356 req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
357 requestmgr
, requestmgr
->eref
, requestmgr
->iref
);
359 if (requestmgr
->eref
== 0 && requestmgr
->iref
== 0) {
360 INSIST(requestmgr
->exiting
&&
361 ISC_LIST_HEAD(requestmgr
->requests
) == NULL
);
362 need_destroy
= ISC_TRUE
;
364 UNLOCK(&requestmgr
->lock
);
367 mgr_destroy(requestmgr
);
373 send_shutdown_events(dns_requestmgr_t
*requestmgr
) {
374 isc_event_t
*event
, *next_event
;
377 req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr
);
380 * Caller must be holding the manager lock.
382 for (event
= ISC_LIST_HEAD(requestmgr
->whenshutdown
);
384 event
= next_event
) {
385 next_event
= ISC_LIST_NEXT(event
, ev_link
);
386 ISC_LIST_UNLINK(requestmgr
->whenshutdown
, event
, ev_link
);
387 etask
= event
->ev_sender
;
388 event
->ev_sender
= requestmgr
;
389 isc_task_sendanddetach(&etask
, &event
);
394 mgr_destroy(dns_requestmgr_t
*requestmgr
) {
398 req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
400 REQUIRE(requestmgr
->eref
== 0);
401 REQUIRE(requestmgr
->iref
== 0);
403 DESTROYLOCK(&requestmgr
->lock
);
404 for (i
= 0; i
< DNS_REQUEST_NLOCKS
; i
++)
405 DESTROYLOCK(&requestmgr
->locks
[i
]);
406 if (requestmgr
->dispatchv4
!= NULL
)
407 dns_dispatch_detach(&requestmgr
->dispatchv4
);
408 if (requestmgr
->dispatchv6
!= NULL
)
409 dns_dispatch_detach(&requestmgr
->dispatchv6
);
410 requestmgr
->magic
= 0;
411 mctx
= requestmgr
->mctx
;
412 isc_mem_put(mctx
, requestmgr
, sizeof(*requestmgr
));
413 isc_mem_detach(&mctx
);
417 mgr_gethash(dns_requestmgr_t
*requestmgr
) {
418 req_log(ISC_LOG_DEBUG(3), "mgr_gethash");
423 return (requestmgr
->hash
% DNS_REQUEST_NLOCKS
);
426 static inline isc_result_t
427 req_send(dns_request_t
*request
, isc_task_t
*task
, isc_sockaddr_t
*address
) {
429 isc_socket_t
*socket
;
431 unsigned int dispattr
;
433 req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request
);
435 REQUIRE(VALID_REQUEST(request
));
436 dispattr
= dns_dispatch_getattributes(request
->dispatch
);
437 socket
= req_getsocket(request
);
438 isc_buffer_usedregion(request
->query
, &r
);
440 * We could connect the socket when we are using an exclusive dispatch
441 * as we do in resolver.c, but we prefer implementation simplicity
444 result
= isc_socket_sendto(socket
, &r
, task
, req_senddone
,
445 request
, address
, NULL
);
446 if (result
== ISC_R_SUCCESS
)
447 request
->flags
|= DNS_REQUEST_F_SENDING
;
452 new_request(isc_mem_t
*mctx
, dns_request_t
**requestp
) {
453 dns_request_t
*request
;
455 request
= isc_mem_get(mctx
, sizeof(*request
));
457 return (ISC_R_NOMEMORY
);
463 request
->mctx
= NULL
;
465 ISC_LINK_INIT(request
, link
);
466 request
->query
= NULL
;
467 request
->answer
= NULL
;
468 request
->event
= NULL
;
469 request
->dispatch
= NULL
;
470 request
->dispentry
= NULL
;
471 request
->timer
= NULL
;
472 request
->requestmgr
= NULL
;
473 request
->tsig
= NULL
;
474 request
->tsigkey
= NULL
;
475 ISC_EVENT_INIT(&request
->ctlevent
, sizeof(request
->ctlevent
), 0, NULL
,
476 DNS_EVENT_REQUESTCONTROL
, do_cancel
, request
, NULL
,
478 request
->canceling
= ISC_FALSE
;
479 request
->udpcount
= 0;
481 isc_mem_attach(mctx
, &request
->mctx
);
483 request
->magic
= REQUEST_MAGIC
;
485 return (ISC_R_SUCCESS
);
490 isblackholed(dns_dispatchmgr_t
*dispatchmgr
, isc_sockaddr_t
*destaddr
) {
491 dns_acl_t
*blackhole
;
492 isc_netaddr_t netaddr
;
494 isc_boolean_t drop
= ISC_FALSE
;
495 char netaddrstr
[ISC_NETADDR_FORMATSIZE
];
497 blackhole
= dns_dispatchmgr_getblackhole(dispatchmgr
);
498 if (blackhole
!= NULL
) {
499 isc_netaddr_fromsockaddr(&netaddr
, destaddr
);
500 if (dns_acl_match(&netaddr
, NULL
, blackhole
,
501 NULL
, &match
, NULL
) == ISC_R_SUCCESS
&&
506 isc_netaddr_format(&netaddr
, netaddrstr
, sizeof(netaddrstr
));
507 req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr
);
513 create_tcp_dispatch(dns_requestmgr_t
*requestmgr
, isc_sockaddr_t
*srcaddr
,
514 isc_sockaddr_t
*destaddr
, dns_dispatch_t
**dispatchp
)
517 isc_socket_t
*socket
= NULL
;
520 isc_sockaddr_t bind_any
;
522 result
= isc_socket_create(requestmgr
->socketmgr
,
523 isc_sockaddr_pf(destaddr
),
524 isc_sockettype_tcp
, &socket
);
525 if (result
!= ISC_R_SUCCESS
)
527 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
528 if (srcaddr
== NULL
) {
529 isc_sockaddr_anyofpf(&bind_any
,
530 isc_sockaddr_pf(destaddr
));
531 result
= isc_socket_bind(socket
, &bind_any
, 0);
534 isc_sockaddr_setport(&src
, 0);
535 result
= isc_socket_bind(socket
, &src
, 0);
537 if (result
!= ISC_R_SUCCESS
)
541 attrs
|= DNS_DISPATCHATTR_TCP
;
542 attrs
|= DNS_DISPATCHATTR_PRIVATE
;
543 if (isc_sockaddr_pf(destaddr
) == AF_INET
)
544 attrs
|= DNS_DISPATCHATTR_IPV4
;
546 attrs
|= DNS_DISPATCHATTR_IPV6
;
547 attrs
|= DNS_DISPATCHATTR_MAKEQUERY
;
548 result
= dns_dispatch_createtcp(requestmgr
->dispatchmgr
,
549 socket
, requestmgr
->taskmgr
,
550 4096, 2, 1, 1, 3, attrs
,
553 isc_socket_detach(&socket
);
558 find_udp_dispatch(dns_requestmgr_t
*requestmgr
, isc_sockaddr_t
*srcaddr
,
559 isc_sockaddr_t
*destaddr
, dns_dispatch_t
**dispatchp
)
561 dns_dispatch_t
*disp
= NULL
;
562 unsigned int attrs
, attrmask
;
564 if (srcaddr
== NULL
) {
565 switch (isc_sockaddr_pf(destaddr
)) {
567 disp
= requestmgr
->dispatchv4
;
571 disp
= requestmgr
->dispatchv6
;
575 return (ISC_R_NOTIMPLEMENTED
);
578 return (ISC_R_FAMILYNOSUPPORT
);
579 dns_dispatch_attach(disp
, dispatchp
);
580 return (ISC_R_SUCCESS
);
583 attrs
|= DNS_DISPATCHATTR_UDP
;
584 switch (isc_sockaddr_pf(srcaddr
)) {
586 attrs
|= DNS_DISPATCHATTR_IPV4
;
590 attrs
|= DNS_DISPATCHATTR_IPV6
;
594 return (ISC_R_NOTIMPLEMENTED
);
597 attrmask
|= DNS_DISPATCHATTR_UDP
;
598 attrmask
|= DNS_DISPATCHATTR_TCP
;
599 attrmask
|= DNS_DISPATCHATTR_IPV4
;
600 attrmask
|= DNS_DISPATCHATTR_IPV6
;
601 return (dns_dispatch_getudp(requestmgr
->dispatchmgr
,
602 requestmgr
->socketmgr
,
605 1000, 32768, 16411, 16433,
611 get_dispatch(isc_boolean_t tcp
, dns_requestmgr_t
*requestmgr
,
612 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
613 dns_dispatch_t
**dispatchp
)
617 result
= create_tcp_dispatch(requestmgr
, srcaddr
,
618 destaddr
, dispatchp
);
620 result
= find_udp_dispatch(requestmgr
, srcaddr
,
621 destaddr
, dispatchp
);
626 set_timer(isc_timer_t
*timer
, unsigned int timeout
, unsigned int udpresend
) {
628 isc_interval_t interval
;
630 isc_timertype_t timertype
;
632 isc_interval_set(&interval
, timeout
, 0);
633 result
= isc_time_nowplusinterval(&expires
, &interval
);
634 isc_interval_set(&interval
, udpresend
, 0);
636 timertype
= udpresend
!= 0 ? isc_timertype_limited
: isc_timertype_once
;
637 if (result
== ISC_R_SUCCESS
)
638 result
= isc_timer_reset(timer
, timertype
, &expires
,
639 &interval
, ISC_FALSE
);
644 dns_request_createraw(dns_requestmgr_t
*requestmgr
, isc_buffer_t
*msgbuf
,
645 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
646 unsigned int options
, unsigned int timeout
,
647 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
648 dns_request_t
**requestp
)
650 return(dns_request_createraw3(requestmgr
, msgbuf
, srcaddr
, destaddr
,
651 options
, timeout
, 0, 0, task
, action
,
656 dns_request_createraw2(dns_requestmgr_t
*requestmgr
, isc_buffer_t
*msgbuf
,
657 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
658 unsigned int options
, unsigned int timeout
,
659 unsigned int udptimeout
, isc_task_t
*task
,
660 isc_taskaction_t action
, void *arg
,
661 dns_request_t
**requestp
)
663 unsigned int udpretries
= 0;
666 udpretries
= timeout
/ udptimeout
;
668 return (dns_request_createraw3(requestmgr
, msgbuf
, srcaddr
, destaddr
,
669 options
, timeout
, udptimeout
,
670 udpretries
, task
, action
, arg
,
675 dns_request_createraw3(dns_requestmgr_t
*requestmgr
, isc_buffer_t
*msgbuf
,
676 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
677 unsigned int options
, unsigned int timeout
,
678 unsigned int udptimeout
, unsigned int udpretries
,
679 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
680 dns_request_t
**requestp
)
682 dns_request_t
*request
= NULL
;
683 isc_task_t
*tclone
= NULL
;
684 isc_socket_t
*socket
= NULL
;
688 isc_boolean_t tcp
= ISC_FALSE
;
691 REQUIRE(VALID_REQUESTMGR(requestmgr
));
692 REQUIRE(msgbuf
!= NULL
);
693 REQUIRE(destaddr
!= NULL
);
694 REQUIRE(task
!= NULL
);
695 REQUIRE(action
!= NULL
);
696 REQUIRE(requestp
!= NULL
&& *requestp
== NULL
);
697 REQUIRE(timeout
> 0);
699 REQUIRE(isc_sockaddr_pf(srcaddr
) == isc_sockaddr_pf(destaddr
));
701 mctx
= requestmgr
->mctx
;
703 req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
705 if (isblackholed(requestmgr
->dispatchmgr
, destaddr
))
706 return (DNS_R_BLACKHOLED
);
709 result
= new_request(mctx
, &request
);
710 if (result
!= ISC_R_SUCCESS
)
713 if (udptimeout
== 0 && udpretries
!= 0) {
714 udptimeout
= timeout
/ (udpretries
+ 1);
718 request
->udpcount
= udpretries
;
721 * Create timer now. We will set it below once.
723 result
= isc_timer_create(requestmgr
->timermgr
, isc_timertype_inactive
,
724 NULL
, NULL
, task
, req_timeout
, request
,
726 if (result
!= ISC_R_SUCCESS
)
729 request
->event
= (dns_requestevent_t
*)
730 isc_event_allocate(mctx
, task
, DNS_EVENT_REQUESTDONE
,
731 action
, arg
, sizeof(dns_requestevent_t
));
732 if (request
->event
== NULL
) {
733 result
= ISC_R_NOMEMORY
;
736 isc_task_attach(task
, &tclone
);
737 request
->event
->ev_sender
= task
;
738 request
->event
->request
= request
;
739 request
->event
->result
= ISC_R_FAILURE
;
741 isc_buffer_usedregion(msgbuf
, &r
);
742 if (r
.length
< DNS_MESSAGE_HEADERLEN
|| r
.length
> 65535) {
743 result
= DNS_R_FORMERR
;
747 if ((options
& DNS_REQUESTOPT_TCP
) != 0 || r
.length
> 512)
750 result
= get_dispatch(tcp
, requestmgr
, srcaddr
, destaddr
,
752 if (result
!= ISC_R_SUCCESS
)
755 result
= dns_dispatch_addresponse2(request
->dispatch
, destaddr
, task
,
756 req_response
, request
, &id
,
758 requestmgr
->socketmgr
);
759 if (result
!= ISC_R_SUCCESS
)
762 socket
= req_getsocket(request
);
763 INSIST(socket
!= NULL
);
765 result
= isc_buffer_allocate(mctx
, &request
->query
,
766 r
.length
+ (tcp
? 2 : 0));
767 if (result
!= ISC_R_SUCCESS
)
770 isc_buffer_putuint16(request
->query
, (isc_uint16_t
)r
.length
);
771 result
= isc_buffer_copyregion(request
->query
, &r
);
772 if (result
!= ISC_R_SUCCESS
)
775 /* Add message ID. */
776 isc_buffer_usedregion(request
->query
, &r
);
778 isc_region_consume(&r
, 2);
779 r
.base
[0] = (id
>>8) & 0xff;
780 r
.base
[1] = id
& 0xff;
782 LOCK(&requestmgr
->lock
);
783 if (requestmgr
->exiting
) {
784 UNLOCK(&requestmgr
->lock
);
785 result
= ISC_R_SHUTTINGDOWN
;
788 requestmgr_attach(requestmgr
, &request
->requestmgr
);
789 request
->hash
= mgr_gethash(requestmgr
);
790 ISC_LIST_APPEND(requestmgr
->requests
, request
, link
);
791 UNLOCK(&requestmgr
->lock
);
793 result
= set_timer(request
->timer
, timeout
, tcp
? 0 : udptimeout
);
794 if (result
!= ISC_R_SUCCESS
)
797 request
->destaddr
= *destaddr
;
799 result
= isc_socket_connect(socket
, destaddr
, task
,
800 req_connected
, request
);
801 if (result
!= ISC_R_SUCCESS
)
803 request
->flags
|= DNS_REQUEST_F_CONNECTING
|DNS_REQUEST_F_TCP
;
805 result
= req_send(request
, task
, destaddr
);
806 if (result
!= ISC_R_SUCCESS
)
810 req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p",
813 return (ISC_R_SUCCESS
);
816 LOCK(&requestmgr
->lock
);
817 ISC_LIST_UNLINK(requestmgr
->requests
, request
, link
);
818 UNLOCK(&requestmgr
->lock
);
822 isc_task_detach(&tclone
);
823 req_destroy(request
);
824 req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
825 dns_result_totext(result
));
830 dns_request_create(dns_requestmgr_t
*requestmgr
, dns_message_t
*message
,
831 isc_sockaddr_t
*address
, unsigned int options
,
833 unsigned int timeout
, isc_task_t
*task
,
834 isc_taskaction_t action
, void *arg
,
835 dns_request_t
**requestp
)
837 return (dns_request_createvia3(requestmgr
, message
, NULL
, address
,
838 options
, key
, timeout
, 0, 0, task
,
839 action
, arg
, requestp
));
843 dns_request_createvia(dns_requestmgr_t
*requestmgr
, dns_message_t
*message
,
844 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
845 unsigned int options
, dns_tsigkey_t
*key
,
846 unsigned int timeout
, isc_task_t
*task
,
847 isc_taskaction_t action
, void *arg
,
848 dns_request_t
**requestp
)
850 return(dns_request_createvia3(requestmgr
, message
, srcaddr
, destaddr
,
851 options
, key
, timeout
, 0, 0, task
,
852 action
, arg
, requestp
));
856 dns_request_createvia2(dns_requestmgr_t
*requestmgr
, dns_message_t
*message
,
857 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
858 unsigned int options
, dns_tsigkey_t
*key
,
859 unsigned int timeout
, unsigned int udptimeout
,
860 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
861 dns_request_t
**requestp
)
863 unsigned int udpretries
= 0;
866 udpretries
= timeout
/ udptimeout
;
867 return (dns_request_createvia3(requestmgr
, message
, srcaddr
, destaddr
,
868 options
, key
, timeout
, udptimeout
,
869 udpretries
, task
, action
, arg
,
874 dns_request_createvia3(dns_requestmgr_t
*requestmgr
, dns_message_t
*message
,
875 isc_sockaddr_t
*srcaddr
, isc_sockaddr_t
*destaddr
,
876 unsigned int options
, dns_tsigkey_t
*key
,
877 unsigned int timeout
, unsigned int udptimeout
,
878 unsigned int udpretries
, isc_task_t
*task
,
879 isc_taskaction_t action
, void *arg
,
880 dns_request_t
**requestp
)
882 dns_request_t
*request
= NULL
;
883 isc_task_t
*tclone
= NULL
;
884 isc_socket_t
*socket
= NULL
;
889 isc_boolean_t setkey
= ISC_TRUE
;
891 REQUIRE(VALID_REQUESTMGR(requestmgr
));
892 REQUIRE(message
!= NULL
);
893 REQUIRE(destaddr
!= NULL
);
894 REQUIRE(task
!= NULL
);
895 REQUIRE(action
!= NULL
);
896 REQUIRE(requestp
!= NULL
&& *requestp
== NULL
);
897 REQUIRE(timeout
> 0);
899 REQUIRE(isc_sockaddr_pf(srcaddr
) == isc_sockaddr_pf(destaddr
));
901 mctx
= requestmgr
->mctx
;
903 req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
905 if (isblackholed(requestmgr
->dispatchmgr
, destaddr
))
906 return (DNS_R_BLACKHOLED
);
909 result
= new_request(mctx
, &request
);
910 if (result
!= ISC_R_SUCCESS
)
913 if (udptimeout
== 0 && udpretries
!= 0) {
914 udptimeout
= timeout
/ (udpretries
+ 1);
918 request
->udpcount
= udpretries
;
921 * Create timer now. We will set it below once.
923 result
= isc_timer_create(requestmgr
->timermgr
, isc_timertype_inactive
,
924 NULL
, NULL
, task
, req_timeout
, request
,
926 if (result
!= ISC_R_SUCCESS
)
929 request
->event
= (dns_requestevent_t
*)
930 isc_event_allocate(mctx
, task
, DNS_EVENT_REQUESTDONE
,
931 action
, arg
, sizeof(dns_requestevent_t
));
932 if (request
->event
== NULL
) {
933 result
= ISC_R_NOMEMORY
;
936 isc_task_attach(task
, &tclone
);
937 request
->event
->ev_sender
= task
;
938 request
->event
->request
= request
;
939 request
->event
->result
= ISC_R_FAILURE
;
941 dns_tsigkey_attach(key
, &request
->tsigkey
);
944 tcp
= ISC_TF((options
& DNS_REQUESTOPT_TCP
) != 0);
945 result
= get_dispatch(tcp
, requestmgr
, srcaddr
, destaddr
,
947 if (result
!= ISC_R_SUCCESS
)
950 result
= dns_dispatch_addresponse2(request
->dispatch
, destaddr
, task
,
951 req_response
, request
, &id
,
953 requestmgr
->socketmgr
);
954 if (result
!= ISC_R_SUCCESS
)
956 socket
= req_getsocket(request
);
957 INSIST(socket
!= NULL
);
961 result
= dns_message_settsigkey(message
, request
->tsigkey
);
962 if (result
!= ISC_R_SUCCESS
)
965 result
= req_render(message
, &request
->query
, options
, mctx
);
966 if (result
== DNS_R_USETCP
&&
967 (options
& DNS_REQUESTOPT_TCP
) == 0) {
969 * Try again using TCP.
971 dns_message_renderreset(message
);
972 dns_dispatch_removeresponse(&request
->dispentry
, NULL
);
973 dns_dispatch_detach(&request
->dispatch
);
975 options
|= DNS_REQUESTOPT_TCP
;
979 if (result
!= ISC_R_SUCCESS
)
982 result
= dns_message_getquerytsig(message
, mctx
, &request
->tsig
);
983 if (result
!= ISC_R_SUCCESS
)
986 LOCK(&requestmgr
->lock
);
987 if (requestmgr
->exiting
) {
988 UNLOCK(&requestmgr
->lock
);
989 result
= ISC_R_SHUTTINGDOWN
;
992 requestmgr_attach(requestmgr
, &request
->requestmgr
);
993 request
->hash
= mgr_gethash(requestmgr
);
994 ISC_LIST_APPEND(requestmgr
->requests
, request
, link
);
995 UNLOCK(&requestmgr
->lock
);
997 result
= set_timer(request
->timer
, timeout
, tcp
? 0 : udptimeout
);
998 if (result
!= ISC_R_SUCCESS
)
1001 request
->destaddr
= *destaddr
;
1003 result
= isc_socket_connect(socket
, destaddr
, task
,
1004 req_connected
, request
);
1005 if (result
!= ISC_R_SUCCESS
)
1007 request
->flags
|= DNS_REQUEST_F_CONNECTING
|DNS_REQUEST_F_TCP
;
1009 result
= req_send(request
, task
, destaddr
);
1010 if (result
!= ISC_R_SUCCESS
)
1014 req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p",
1016 *requestp
= request
;
1017 return (ISC_R_SUCCESS
);
1020 LOCK(&requestmgr
->lock
);
1021 ISC_LIST_UNLINK(requestmgr
->requests
, request
, link
);
1022 UNLOCK(&requestmgr
->lock
);
1026 isc_task_detach(&tclone
);
1027 req_destroy(request
);
1028 req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
1029 dns_result_totext(result
));
1034 req_render(dns_message_t
*message
, isc_buffer_t
**bufferp
,
1035 unsigned int options
, isc_mem_t
*mctx
)
1037 isc_buffer_t
*buf1
= NULL
;
1038 isc_buffer_t
*buf2
= NULL
;
1039 isc_result_t result
;
1041 isc_boolean_t tcp
= ISC_FALSE
;
1042 dns_compress_t cctx
;
1043 isc_boolean_t cleanup_cctx
= ISC_FALSE
;
1045 REQUIRE(bufferp
!= NULL
&& *bufferp
== NULL
);
1047 req_log(ISC_LOG_DEBUG(3), "request_render");
1050 * Create buffer able to hold largest possible message.
1052 result
= isc_buffer_allocate(mctx
, &buf1
, 65535);
1053 if (result
!= ISC_R_SUCCESS
)
1056 result
= dns_compress_init(&cctx
, -1, mctx
);
1057 if (result
!= ISC_R_SUCCESS
)
1059 cleanup_cctx
= ISC_TRUE
;
1064 result
= dns_message_renderbegin(message
, &cctx
, buf1
);
1065 if (result
!= ISC_R_SUCCESS
)
1067 result
= dns_message_rendersection(message
, DNS_SECTION_QUESTION
, 0);
1068 if (result
!= ISC_R_SUCCESS
)
1070 result
= dns_message_rendersection(message
, DNS_SECTION_ANSWER
, 0);
1071 if (result
!= ISC_R_SUCCESS
)
1073 result
= dns_message_rendersection(message
, DNS_SECTION_AUTHORITY
, 0);
1074 if (result
!= ISC_R_SUCCESS
)
1076 result
= dns_message_rendersection(message
, DNS_SECTION_ADDITIONAL
, 0);
1077 if (result
!= ISC_R_SUCCESS
)
1079 result
= dns_message_renderend(message
);
1080 if (result
!= ISC_R_SUCCESS
)
1083 dns_compress_invalidate(&cctx
);
1084 cleanup_cctx
= ISC_FALSE
;
1087 * Copy rendered message to exact sized buffer.
1089 isc_buffer_usedregion(buf1
, &r
);
1090 if ((options
& DNS_REQUESTOPT_TCP
) != 0) {
1092 } else if (r
.length
> 512) {
1093 result
= DNS_R_USETCP
;
1096 result
= isc_buffer_allocate(mctx
, &buf2
, r
.length
+ (tcp
? 2 : 0));
1097 if (result
!= ISC_R_SUCCESS
)
1100 isc_buffer_putuint16(buf2
, (isc_uint16_t
)r
.length
);
1101 result
= isc_buffer_copyregion(buf2
, &r
);
1102 if (result
!= ISC_R_SUCCESS
)
1106 * Cleanup and return.
1108 isc_buffer_free(&buf1
);
1110 return (ISC_R_SUCCESS
);
1113 dns_message_renderreset(message
);
1115 isc_buffer_free(&buf1
);
1117 isc_buffer_free(&buf2
);
1119 dns_compress_invalidate(&cctx
);
1125 * If this request is no longer waiting for events,
1126 * send the completion event. This will ultimately
1127 * cause the request to be destroyed.
1130 * 'request' is locked by the caller.
1133 send_if_done(dns_request_t
*request
, isc_result_t result
) {
1134 if (!DNS_REQUEST_CONNECTING(request
) &&
1135 !DNS_REQUEST_SENDING(request
) &&
1136 !request
->canceling
)
1137 req_sendevent(request
, result
);
1141 * Handle the control event.
1144 do_cancel(isc_task_t
*task
, isc_event_t
*event
) {
1145 dns_request_t
*request
= event
->ev_arg
;
1147 INSIST(event
->ev_type
== DNS_EVENT_REQUESTCONTROL
);
1148 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1149 request
->canceling
= ISC_FALSE
;
1150 if (!DNS_REQUEST_CANCELED(request
))
1151 req_cancel(request
);
1152 send_if_done(request
, ISC_R_CANCELED
);
1153 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1157 dns_request_cancel(dns_request_t
*request
) {
1158 REQUIRE(VALID_REQUEST(request
));
1160 req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request
);
1162 REQUIRE(VALID_REQUEST(request
));
1164 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1165 if (!request
->canceling
&& !DNS_REQUEST_CANCELED(request
)) {
1166 isc_event_t
*ev
= &request
->ctlevent
;
1167 isc_task_send(request
->event
->ev_sender
, &ev
);
1168 request
->canceling
= ISC_TRUE
;
1170 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1174 dns_request_getresponse(dns_request_t
*request
, dns_message_t
*message
,
1175 unsigned int options
)
1177 isc_result_t result
;
1179 REQUIRE(VALID_REQUEST(request
));
1180 REQUIRE(request
->answer
!= NULL
);
1182 req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
1185 result
= dns_message_setquerytsig(message
, request
->tsig
);
1186 if (result
!= ISC_R_SUCCESS
)
1188 result
= dns_message_settsigkey(message
, request
->tsigkey
);
1189 if (result
!= ISC_R_SUCCESS
)
1191 result
= dns_message_parse(message
, request
->answer
, options
);
1192 if (result
!= ISC_R_SUCCESS
)
1194 if (request
->tsigkey
!= NULL
)
1195 result
= dns_tsig_verify(request
->answer
, message
, NULL
, NULL
);
1200 dns_request_usedtcp(dns_request_t
*request
) {
1201 REQUIRE(VALID_REQUEST(request
));
1203 return (ISC_TF((request
->flags
& DNS_REQUEST_F_TCP
) != 0));
1207 dns_request_destroy(dns_request_t
**requestp
) {
1208 dns_request_t
*request
;
1210 REQUIRE(requestp
!= NULL
&& VALID_REQUEST(*requestp
));
1212 request
= *requestp
;
1214 req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request
);
1216 LOCK(&request
->requestmgr
->lock
);
1217 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1218 ISC_LIST_UNLINK(request
->requestmgr
->requests
, request
, link
);
1219 INSIST(!DNS_REQUEST_CONNECTING(request
));
1220 INSIST(!DNS_REQUEST_SENDING(request
));
1221 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1222 UNLOCK(&request
->requestmgr
->lock
);
1225 * These should have been cleaned up by req_cancel() before
1226 * the completion event was sent.
1228 INSIST(!ISC_LINK_LINKED(request
, link
));
1229 INSIST(request
->dispentry
== NULL
);
1230 INSIST(request
->dispatch
== NULL
);
1231 INSIST(request
->timer
== NULL
);
1233 req_destroy(request
);
1239 *** Private: request.
1242 static isc_socket_t
*
1243 req_getsocket(dns_request_t
*request
) {
1244 unsigned int dispattr
;
1245 isc_socket_t
*socket
;
1247 dispattr
= dns_dispatch_getattributes(request
->dispatch
);
1248 if ((dispattr
& DNS_DISPATCHATTR_EXCLUSIVE
) != 0) {
1249 INSIST(request
->dispentry
!= NULL
);
1250 socket
= dns_dispatch_getentrysocket(request
->dispentry
);
1252 socket
= dns_dispatch_getsocket(request
->dispatch
);
1258 req_connected(isc_task_t
*task
, isc_event_t
*event
) {
1259 isc_socketevent_t
*sevent
= (isc_socketevent_t
*)event
;
1260 isc_result_t result
;
1261 dns_request_t
*request
= event
->ev_arg
;
1263 REQUIRE(event
->ev_type
== ISC_SOCKEVENT_CONNECT
);
1264 REQUIRE(VALID_REQUEST(request
));
1265 REQUIRE(DNS_REQUEST_CONNECTING(request
));
1267 req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request
);
1269 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1270 request
->flags
&= ~DNS_REQUEST_F_CONNECTING
;
1272 if (DNS_REQUEST_CANCELED(request
)) {
1274 * Send delayed event.
1276 if (DNS_REQUEST_TIMEDOUT(request
))
1277 send_if_done(request
, ISC_R_TIMEDOUT
);
1279 send_if_done(request
, ISC_R_CANCELED
);
1281 dns_dispatch_starttcp(request
->dispatch
);
1282 result
= sevent
->result
;
1283 if (result
== ISC_R_SUCCESS
)
1284 result
= req_send(request
, task
, NULL
);
1286 if (result
!= ISC_R_SUCCESS
) {
1287 req_cancel(request
);
1288 send_if_done(request
, ISC_R_CANCELED
);
1291 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1292 isc_event_free(&event
);
1296 req_senddone(isc_task_t
*task
, isc_event_t
*event
) {
1297 isc_socketevent_t
*sevent
= (isc_socketevent_t
*)event
;
1298 dns_request_t
*request
= event
->ev_arg
;
1300 REQUIRE(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1301 REQUIRE(VALID_REQUEST(request
));
1302 REQUIRE(DNS_REQUEST_SENDING(request
));
1304 req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request
);
1308 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1309 request
->flags
&= ~DNS_REQUEST_F_SENDING
;
1311 if (DNS_REQUEST_CANCELED(request
)) {
1313 * Send delayed event.
1315 if (DNS_REQUEST_TIMEDOUT(request
))
1316 send_if_done(request
, ISC_R_TIMEDOUT
);
1318 send_if_done(request
, ISC_R_CANCELED
);
1319 } else if (sevent
->result
!= ISC_R_SUCCESS
) {
1320 req_cancel(request
);
1321 send_if_done(request
, ISC_R_CANCELED
);
1323 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1325 isc_event_free(&event
);
1329 req_response(isc_task_t
*task
, isc_event_t
*event
) {
1330 isc_result_t result
;
1331 dns_request_t
*request
= event
->ev_arg
;
1332 dns_dispatchevent_t
*devent
= (dns_dispatchevent_t
*)event
;
1335 REQUIRE(VALID_REQUEST(request
));
1336 REQUIRE(event
->ev_type
== DNS_EVENT_DISPATCH
);
1340 req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request
,
1341 dns_result_totext(devent
->result
));
1343 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1344 result
= devent
->result
;
1345 if (result
!= ISC_R_SUCCESS
)
1349 * Copy buffer to request.
1351 isc_buffer_usedregion(&devent
->buffer
, &r
);
1352 result
= isc_buffer_allocate(request
->mctx
, &request
->answer
,
1354 if (result
!= ISC_R_SUCCESS
)
1356 result
= isc_buffer_copyregion(request
->answer
, &r
);
1357 if (result
!= ISC_R_SUCCESS
)
1358 isc_buffer_free(&request
->answer
);
1363 dns_dispatch_removeresponse(&request
->dispentry
, &devent
);
1364 req_cancel(request
);
1366 * Send completion event.
1368 send_if_done(request
, result
);
1369 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1373 req_timeout(isc_task_t
*task
, isc_event_t
*event
) {
1374 dns_request_t
*request
= event
->ev_arg
;
1375 isc_result_t result
;
1377 REQUIRE(VALID_REQUEST(request
));
1379 req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request
);
1382 LOCK(&request
->requestmgr
->locks
[request
->hash
]);
1383 if (event
->ev_type
== ISC_TIMEREVENT_TICK
&&
1384 request
->udpcount
-- != 0) {
1385 if (! DNS_REQUEST_SENDING(request
)) {
1386 result
= req_send(request
, task
, &request
->destaddr
);
1387 if (result
!= ISC_R_SUCCESS
) {
1388 req_cancel(request
);
1389 send_if_done(request
, result
);
1393 request
->flags
|= DNS_REQUEST_F_TIMEDOUT
;
1394 req_cancel(request
);
1395 send_if_done(request
, ISC_R_TIMEDOUT
);
1397 UNLOCK(&request
->requestmgr
->locks
[request
->hash
]);
1398 isc_event_free(&event
);
1402 req_sendevent(dns_request_t
*request
, isc_result_t result
) {
1405 REQUIRE(VALID_REQUEST(request
));
1407 req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request
);
1410 * Lock held by caller.
1412 task
= request
->event
->ev_sender
;
1413 request
->event
->ev_sender
= request
;
1414 request
->event
->result
= result
;
1415 isc_task_sendanddetach(&task
, (isc_event_t
**)&request
->event
);
1419 req_destroy(dns_request_t
*request
) {
1422 REQUIRE(VALID_REQUEST(request
));
1424 req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request
);
1427 if (request
->query
!= NULL
)
1428 isc_buffer_free(&request
->query
);
1429 if (request
->answer
!= NULL
)
1430 isc_buffer_free(&request
->answer
);
1431 if (request
->event
!= NULL
)
1432 isc_event_free((isc_event_t
**)&request
->event
);
1433 if (request
->dispentry
!= NULL
)
1434 dns_dispatch_removeresponse(&request
->dispentry
, NULL
);
1435 if (request
->dispatch
!= NULL
)
1436 dns_dispatch_detach(&request
->dispatch
);
1437 if (request
->timer
!= NULL
)
1438 isc_timer_detach(&request
->timer
);
1439 if (request
->tsig
!= NULL
)
1440 isc_buffer_free(&request
->tsig
);
1441 if (request
->tsigkey
!= NULL
)
1442 dns_tsigkey_detach(&request
->tsigkey
);
1443 if (request
->requestmgr
!= NULL
)
1444 requestmgr_detach(&request
->requestmgr
);
1445 mctx
= request
->mctx
;
1446 isc_mem_put(mctx
, request
, sizeof(*request
));
1447 isc_mem_detach(&mctx
);
1451 * Stop the current request. Must be called from the request's task.
1454 req_cancel(dns_request_t
*request
) {
1455 isc_socket_t
*socket
;
1456 unsigned int dispattr
;
1458 REQUIRE(VALID_REQUEST(request
));
1460 req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request
);
1463 * Lock held by caller.
1465 request
->flags
|= DNS_REQUEST_F_CANCELED
;
1467 if (request
->timer
!= NULL
)
1468 isc_timer_detach(&request
->timer
);
1469 dispattr
= dns_dispatch_getattributes(request
->dispatch
);
1471 if (DNS_REQUEST_CONNECTING(request
) || DNS_REQUEST_SENDING(request
)) {
1472 if ((dispattr
& DNS_DISPATCHATTR_EXCLUSIVE
) != 0) {
1473 if (request
->dispentry
!= NULL
) {
1474 socket
= dns_dispatch_getentrysocket(
1475 request
->dispentry
);
1478 socket
= dns_dispatch_getsocket(request
->dispatch
);
1479 if (DNS_REQUEST_CONNECTING(request
) && socket
!= NULL
)
1480 isc_socket_cancel(socket
, NULL
, ISC_SOCKCANCEL_CONNECT
);
1481 if (DNS_REQUEST_SENDING(request
) && socket
!= NULL
)
1482 isc_socket_cancel(socket
, NULL
, ISC_SOCKCANCEL_SEND
);
1484 if (request
->dispentry
!= NULL
)
1485 dns_dispatch_removeresponse(&request
->dispentry
, NULL
);
1486 dns_dispatch_detach(&request
->dispatch
);
1490 req_log(int level
, const char *fmt
, ...) {
1494 isc_log_vwrite(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
1495 DNS_LOGMODULE_REQUEST
, level
, fmt
, ap
);