2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

[master] allow shared TCP sockets when connecting

4041.	[func]		TCP sockets can now be shared while connecting.
			(This will be used to enable client-side support
			of pipelined queries.) [RT #38231]
This commit is contained in:
Evan Hunt
2015-01-20 17:22:31 -08:00
parent d9184858dd
commit ff62d4458a
16 changed files with 314 additions and 195 deletions

View File

@@ -2677,6 +2677,83 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
}
isc_result_t
dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
isc_sockaddr_t *localaddr, isc_boolean_t *connected,
dns_dispatch_t **dispp)
{
dns_dispatch_t *disp;
isc_result_t result;
isc_sockaddr_t peeraddr;
isc_sockaddr_t sockname;
unsigned int attributes, mask;
isc_boolean_t match = ISC_FALSE;
REQUIRE(VALID_DISPATCHMGR(mgr));
REQUIRE(destaddr != NULL);
REQUIRE(dispp != NULL && *dispp == NULL);
REQUIRE(connected != NULL);
/* First pass (same than dns_dispatch_gettcp()) */
attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED;
mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE |
DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED;
LOCK(&mgr->lock);
disp = ISC_LIST_HEAD(mgr->list);
while (disp != NULL && !match) {
LOCK(&disp->lock);
if ((disp->shutting_down == 0) &&
ATTRMATCH(disp->attributes, attributes, mask) &&
(localaddr == NULL ||
isc_sockaddr_eqaddr(localaddr, &disp->local))) {
result = isc_socket_getsockname(disp->socket,
&sockname);
if (result == ISC_R_SUCCESS)
result = isc_socket_getpeername(disp->socket,
&peeraddr);
if (result == ISC_R_SUCCESS &&
isc_sockaddr_equal(destaddr, &peeraddr) &&
(localaddr == NULL ||
isc_sockaddr_eqaddr(localaddr, &sockname))) {
/* attach */
disp->refcount++;
*dispp = disp;
match = ISC_TRUE;
*connected = ISC_TRUE;
}
}
UNLOCK(&disp->lock);
disp = ISC_LIST_NEXT(disp, link);
}
if (match) {
UNLOCK(&mgr->lock);
return (ISC_R_SUCCESS);
}
/* Second pass */
attributes = DNS_DISPATCHATTR_TCP;
disp = ISC_LIST_HEAD(mgr->list);
while (disp != NULL && !match) {
LOCK(&disp->lock);
if ((disp->shutting_down == 0) &&
ATTRMATCH(disp->attributes, attributes, mask) &&
(localaddr == NULL ||
isc_sockaddr_eqaddr(localaddr, &disp->local)) &&
isc_sockaddr_equal(destaddr, &disp->peer)) {
/* attach */
disp->refcount++;
*dispp = disp;
match = ISC_TRUE;
}
UNLOCK(&disp->lock);
disp = ISC_LIST_NEXT(disp, link);
}
UNLOCK(&mgr->lock);
return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
}
isc_result_t
dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
@@ -3332,8 +3409,10 @@ dns_dispatch_starttcp(dns_dispatch_t *disp) {
dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]);
LOCK(&disp->lock);
disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
(void)startrecv(disp, NULL);
if ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) == 0) {
disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
(void)startrecv(disp, NULL);
}
UNLOCK(&disp->lock);
}