diff options
Diffstat (limited to 'lib/dns/request.c')
-rw-r--r-- | lib/dns/request.c | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/lib/dns/request.c b/lib/dns/request.c index dd3e6700..e1709a6a 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.79 2007/06/19 23:47:16 tbox Exp $ */ +/* $Id: request.c,v 1.79.128.2 2008/06/24 23:46:26 tbox Exp $ */ /*! \file */ @@ -121,6 +121,7 @@ static isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer, 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); @@ -146,6 +147,7 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_socket_t *socket; isc_result_t result; int i; + unsigned int dispattr; req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create"); @@ -154,13 +156,14 @@ dns_requestmgr_create(isc_mem_t *mctx, REQUIRE(socketmgr != NULL); REQUIRE(taskmgr != NULL); REQUIRE(dispatchmgr != NULL); + UNUSED(socket); if (dispatchv4 != NULL) { - socket = dns_dispatch_getsocket(dispatchv4); - REQUIRE(isc_socket_gettype(socket) == isc_sockettype_udp); + dispattr = dns_dispatch_getattributes(dispatchv4); + REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); } if (dispatchv6 != NULL) { - socket = dns_dispatch_getsocket(dispatchv6); - REQUIRE(isc_socket_gettype(socket) == isc_sockettype_udp); + dispattr = dns_dispatch_getattributes(dispatchv6); + REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); } requestmgr = isc_mem_get(mctx, sizeof(*requestmgr)); @@ -425,12 +428,19 @@ 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; + unsigned int dispattr; req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); REQUIRE(VALID_REQUEST(request)); - socket = dns_dispatch_getsocket(request->dispatch); + dispattr = dns_dispatch_getattributes(request->dispatch); + socket = req_getsocket(request); isc_buffer_usedregion(request->query, &r); + /* + * 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. + */ result = isc_socket_sendto(socket, &r, task, req_senddone, request, address, NULL); if (result == ISC_R_SUCCESS) @@ -685,7 +695,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, REQUIRE(action != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); - if (srcaddr != NULL) + if (srcaddr != NULL) REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); mctx = requestmgr->mctx; @@ -733,7 +743,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, result = DNS_R_FORMERR; goto cleanup; } - + if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) tcp = ISC_TRUE; @@ -742,14 +752,16 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, 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); + result = dns_dispatch_addresponse2(request->dispatch, destaddr, task, + req_response, request, &id, + &request->dispentry, + requestmgr->socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; + socket = req_getsocket(request); + INSIST(socket != NULL); + result = isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0)); if (result != ISC_R_SUCCESS) @@ -857,7 +869,7 @@ dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, 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, @@ -883,7 +895,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, REQUIRE(action != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); - if (srcaddr != NULL) + if (srcaddr != NULL) REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); mctx = requestmgr->mctx; @@ -935,13 +947,14 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, 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); + result = dns_dispatch_addresponse2(request->dispatch, destaddr, task, + req_response, request, &id, + &request->dispentry, + requestmgr->socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; + socket = req_getsocket(request); + INSIST(socket != NULL); message->id = id; if (setkey) { @@ -1137,7 +1150,7 @@ do_cancel(isc_task_t *task, isc_event_t *event) { if (!DNS_REQUEST_CANCELED(request)) req_cancel(request); send_if_done(request, ISC_R_CANCELED); - UNLOCK(&request->requestmgr->locks[request->hash]); + UNLOCK(&request->requestmgr->locks[request->hash]); } void @@ -1226,6 +1239,21 @@ dns_request_destroy(dns_request_t **requestp) { *** Private: request. ***/ +static isc_socket_t * +req_getsocket(dns_request_t *request) { + unsigned int dispattr; + isc_socket_t *socket; + + dispattr = dns_dispatch_getattributes(request->dispatch); + if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { + INSIST(request->dispentry != NULL); + socket = dns_dispatch_getentrysocket(request->dispentry); + } else + socket = dns_dispatch_getsocket(request->dispatch); + + return (socket); +} + static void req_connected(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; @@ -1425,6 +1453,7 @@ req_destroy(dns_request_t *request) { static void req_cancel(dns_request_t *request) { isc_socket_t *socket; + unsigned int dispattr; REQUIRE(VALID_REQUEST(request)); @@ -1437,16 +1466,23 @@ req_cancel(dns_request_t *request) { if (request->timer != NULL) isc_timer_detach(&request->timer); + dispattr = dns_dispatch_getattributes(request->dispatch); + socket = NULL; + if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) { + if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { + if (request->dispentry != NULL) { + socket = dns_dispatch_getentrysocket( + request->dispentry); + } + } else + socket = dns_dispatch_getsocket(request->dispatch); + if (DNS_REQUEST_CONNECTING(request) && socket != NULL) + isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT); + if (DNS_REQUEST_SENDING(request) && socket != NULL) + isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND); + } 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); } |