From 2523be1cbebc366dc6bc8401e0e51fde0758cc51 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 4 Jan 2021 23:03:50 -0800 Subject: [PATCH] Move isc_socket_sendto2() calls into dispatch We now use dns_dispatch_send() for this purpose. --- lib/dns/dispatch.c | 40 ++++++++++++++++++++++++++++++++-- lib/dns/include/dns/dispatch.h | 14 ++++++++++++ lib/dns/request.c | 31 ++++++-------------------- lib/dns/resolver.c | 34 +++++------------------------ 4 files changed, 64 insertions(+), 55 deletions(-) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 24cb01fe6a..fcc43995b7 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -163,8 +163,8 @@ struct dns_dispatch { unsigned int attributes; isc_refcount_t refcount; dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ - unsigned int shutting_down : 1, shutdown_out : 1, connected : 1, - tcpmsg_valid : 1, recv_pending : 1; + unsigned int shutting_down : 1, shutdown_out : 1, recv_pending : 1, + tcpmsg_valid : 1; isc_result_t shutdown_why; ISC_LIST(dispsocket_t) activesockets; ISC_LIST(dispsocket_t) inactivesockets; @@ -2597,6 +2597,42 @@ dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp, return (isc_socket_connect(sock, address, task, action, arg)); } +isc_result_t +dns_dispatch_send(dns_dispentry_t *resp, bool tcp, isc_task_t *task, + isc_socketevent_t *sendevent, isc_region_t *r, + const isc_sockaddr_t *address, isc_dscp_t dscp, + isc_taskaction_t action, void *arg) { + isc_result_t result; + isc_socket_t *sock = NULL; + + REQUIRE(VALID_RESPONSE(resp)); + REQUIRE(sendevent != NULL); + + memset(sendevent, 0, sizeof(isc_socketevent_t)); + ISC_EVENT_INIT(sendevent, sizeof(isc_socketevent_t), 0, NULL, + ISC_SOCKEVENT_SENDDONE, action, arg, NULL, NULL, NULL); + + sock = dns_dispatch_getentrysocket(resp); + + if (dscp == -1) { + sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; + sendevent->dscp = 0; + } else { + sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; + sendevent->dscp = dscp; + if (tcp) { + isc_socket_dscp(sock, dscp); + } + } + + if (tcp) { + address = NULL; + } + + result = isc_socket_sendto2(sock, r, task, address, NULL, sendevent, 0); + return (result); +} + /* * disp must be locked. */ diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index 7ce569111b..180e17997a 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -276,6 +276,20 @@ dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp, *\li 'disp' is NULL and 'resp' is valid. */ +isc_result_t +dns_dispatch_send(dns_dispentry_t *resp, bool tcp, isc_task_t *task, + isc_socketevent_t *sendevent, isc_region_t *r, + const isc_sockaddr_t *address, isc_dscp_t dscp, + isc_taskaction_t action, void *arg); +/*%< + * Send region 'r' using the socket in 'resp', then run the specified + * callback. 'sendevent' must point to enough memory to hold an + * isc_socketevent; it will be overwritten. + * + * Requires: + *\li 'resp' is valid. + */ + void dns_dispatch_starttcp(dns_dispatch_t *disp); /*%< diff --git a/lib/dns/request.c b/lib/dns/request.c index 1a16f2d0e5..79c6b6147d 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -78,6 +78,7 @@ struct dns_request { dns_requestmgr_t *requestmgr; isc_buffer_t *tsig; dns_tsigkey_t *tsigkey; + isc_socketevent_t sendevent; isc_event_t ctlevent; bool canceling; /* ctlevent outstanding */ isc_sockaddr_t destaddr; @@ -412,40 +413,22 @@ mgr_gethash(dns_requestmgr_t *requestmgr) { static inline isc_result_t req_send(dns_request_t *request, isc_task_t *task, const isc_sockaddr_t *address) { - isc_region_t r; - isc_socket_t *sock = NULL; - isc_socketevent_t *sendevent = NULL; isc_result_t result; + isc_region_t r; + bool tcp; req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); REQUIRE(VALID_REQUEST(request)); - sock = dns_dispatch_getentrysocket(request->dispentry); 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. - */ - sendevent = isc_socket_socketevent(request->mctx, sock, - ISC_SOCKEVENT_SENDDONE, req_senddone, - request); - if (sendevent == NULL) { - return (ISC_R_NOMEMORY); - } - if (request->dscp == -1) { - sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; - sendevent->dscp = 0; - } else { - sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; - sendevent->dscp = request->dscp; - } + tcp = dns_request_usedtcp(request); request->flags |= DNS_REQUEST_F_SENDING; - result = isc_socket_sendto2(sock, &r, task, address, NULL, sendevent, - 0); + result = dns_dispatch_send(request->dispentry, tcp, task, + &request->sendevent, &r, address, + request->dscp, req_senddone, request); INSIST(result == ISC_R_SUCCESS); return (result); } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index c011dabae7..269cff7d2b 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2369,10 +2369,8 @@ resquery_send(resquery_t *query) { dns_rdataset_t *qrdataset = NULL; isc_region_t r; dns_resolver_t *res = NULL; - isc_task_t *task; - isc_socket_t *sock = NULL; + isc_task_t *task = NULL; isc_buffer_t tcpbuffer; - isc_sockaddr_t *address = NULL; isc_buffer_t *buffer = NULL; isc_netaddr_t ipaddr; dns_tsigkey_t *tsigkey = NULL; @@ -2808,33 +2806,11 @@ resquery_send(resquery_t *query) { isc_buffer_usedregion(buffer, &r); - sock = dns_dispatch_getentrysocket(query->dispentry); - - /* - * XXXRTH Make sure we don't send to ourselves! We should probably - * prune out these addresses when we get them from the ADB. - */ - memset(&query->sendevent, 0, sizeof(query->sendevent)); - ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL, - ISC_SOCKEVENT_SENDDONE, resquery_senddone, query, NULL, - NULL, NULL); - - if (query->dscp == -1) { - query->sendevent.attributes &= ~ISC_SOCKEVENTATTR_DSCP; - query->sendevent.dscp = 0; - } else { - query->sendevent.attributes |= ISC_SOCKEVENTATTR_DSCP; - query->sendevent.dscp = query->dscp; - if (tcp) { - isc_socket_dscp(sock, query->dscp); - } - } - - address = tcp ? NULL : &query->addrinfo->sockaddr; - result = isc_socket_sendto2(sock, &r, task, address, NULL, - &query->sendevent, 0); + result = dns_dispatch_send(query->dispentry, tcp, task, + &query->sendevent, &r, + &query->addrinfo->sockaddr, query->dscp, + resquery_senddone, query); INSIST(result == ISC_R_SUCCESS); - query->sends++; QTRACE("sent");