mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +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:
parent
d9184858dd
commit
ff62d4458a
4
CHANGES
4
CHANGES
@ -1,3 +1,7 @@
|
||||
4041. [func] TCP sockets can now be shared while connecting.
|
||||
(This will be used to enable client-side support
|
||||
of pipelined queries.) [RT #38231]
|
||||
|
||||
4040. [func] Added server-side support for pipelined TCP
|
||||
queries. TCP connections are no longer closed after
|
||||
the first query received from a client. (The new
|
||||
|
@ -70,7 +70,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
|
||||
dns64 dnssec dsdigest dscp ecdsa ednscompliance emptyzones
|
||||
filter-aaaa formerr forward geoip glue gost ixfr inline
|
||||
legacy limits logfileconfig lwresd masterfile masterformat
|
||||
metadata notify nslookup nsupdate pending piplined @PKCS11_TEST@
|
||||
metadata notify nslookup nsupdate pending pipelined @PKCS11_TEST@
|
||||
reclimit redirect resolver rndc rpz rrl rrchecker rrsetorder
|
||||
rsabigexponent runtime sit sfcache smartsign sortlist spf
|
||||
staticstub statistics stub tcp tkey tsig tsiggss unknown
|
||||
|
@ -17,3 +17,4 @@
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f raw* output*
|
||||
rm -f ns*/named.lock
|
||||
|
@ -1 +1 @@
|
||||
-m record,size,mctx -c named.conf -d 99 -g -T delay=200
|
||||
-m record,size,mctx -c named.conf -d 99 -X named.lock -g -T delay=200
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -26,6 +26,7 @@
|
||||
#include <isc/hash.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/task.h>
|
||||
@ -61,7 +62,9 @@
|
||||
|
||||
static isc_mem_t *mctx;
|
||||
static dns_requestmgr_t *requestmgr;
|
||||
isc_sockaddr_t address;
|
||||
static isc_boolean_t have_src = ISC_FALSE;
|
||||
static isc_sockaddr_t srcaddr;
|
||||
static isc_sockaddr_t dstaddr;
|
||||
static int onfly;
|
||||
|
||||
static void
|
||||
@ -124,8 +127,7 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
sendquery(isc_task_t *task)
|
||||
{
|
||||
sendquery(isc_task_t *task) {
|
||||
dns_request_t *request;
|
||||
dns_message_t *message;
|
||||
dns_name_t *qname;
|
||||
@ -175,18 +177,18 @@ sendquery(isc_task_t *task)
|
||||
dns_message_addname(message, qname, DNS_SECTION_QUESTION);
|
||||
|
||||
request = NULL;
|
||||
result = dns_request_create(requestmgr, message, &address,
|
||||
DNS_REQUESTOPT_TCP, NULL,
|
||||
TIMEOUT, task, recvresponse,
|
||||
message, &request);
|
||||
result = dns_request_createvia(requestmgr, message,
|
||||
have_src ? &srcaddr : NULL, &dstaddr,
|
||||
DNS_REQUESTOPT_TCP|DNS_REQUESTOPT_SHARE,
|
||||
NULL, TIMEOUT, task, recvresponse,
|
||||
message, &request);
|
||||
CHECK("dns_request_create", result);
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
sendqueries(isc_task_t *task, isc_event_t *event)
|
||||
{
|
||||
sendqueries(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
|
||||
isc_event_free(&event);
|
||||
@ -200,42 +202,44 @@ sendqueries(isc_task_t *task, isc_event_t *event)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
connecting(isc_task_t *task, isc_event_t *event)
|
||||
{
|
||||
isc_socket_t *sock = (isc_socket_t *)(event->ev_arg);
|
||||
|
||||
RUNCHECK(isc_socket_connect(sock, &address, task, sendqueries, NULL));
|
||||
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
isc_taskmgr_t *taskmgr;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
isc_socket_t *sock;
|
||||
unsigned int attrs, attrmask;
|
||||
isc_sockaddr_t bind_addr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_dispatch_t *tcpdispatch;
|
||||
dns_view_t *view;
|
||||
isc_entropy_t *ectx;
|
||||
isc_task_t *task;
|
||||
isc_log_t *lctx;
|
||||
isc_logconfig_t *lcfg;
|
||||
main(int argc, char *argv[]) {
|
||||
isc_sockaddr_t bind_any;
|
||||
struct in_addr inaddr;
|
||||
isc_result_t result;
|
||||
isc_log_t *lctx;
|
||||
isc_logconfig_t *lcfg;
|
||||
isc_entropy_t *ectx;
|
||||
isc_taskmgr_t *taskmgr;
|
||||
isc_task_t *task;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
unsigned int attrs, attrmask;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_view_t *view;
|
||||
|
||||
UNUSED(argv);
|
||||
|
||||
if (argc > 1)
|
||||
have_src = ISC_TRUE;
|
||||
|
||||
RUNCHECK(isc_app_start());
|
||||
|
||||
dns_result_register();
|
||||
|
||||
isc_sockaddr_any(&bind_any);
|
||||
|
||||
result = ISC_R_FAILURE;
|
||||
if (inet_pton(AF_INET, "10.53.0.7", &inaddr) != 1)
|
||||
CHECK("inet_pton", result);
|
||||
isc_sockaddr_fromin(&srcaddr, &inaddr, 0);
|
||||
|
||||
result = ISC_R_FAILURE;
|
||||
if (inet_pton(AF_INET, "10.53.0.4", &inaddr) != 1)
|
||||
CHECK("inet_pton", result);
|
||||
isc_sockaddr_fromin(&dstaddr, &inaddr, PORT);
|
||||
|
||||
mctx = NULL;
|
||||
RUNCHECK(isc_mem_create(0, 0, &mctx));
|
||||
|
||||
@ -261,14 +265,7 @@ main(int argc, char *argv[])
|
||||
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
dispatchmgr = NULL;
|
||||
RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr));
|
||||
if (argc == 1) {
|
||||
isc_sockaddr_any(&bind_addr);
|
||||
} else {
|
||||
result = ISC_R_FAILURE;
|
||||
if (inet_pton(AF_INET, "10.53.0.7", &inaddr) != 1)
|
||||
CHECK("inet_pton", result);
|
||||
isc_sockaddr_fromin(&bind_addr, &inaddr, 0);
|
||||
}
|
||||
|
||||
attrs = DNS_DISPATCHATTR_UDP |
|
||||
DNS_DISPATCHATTR_MAKEQUERY |
|
||||
DNS_DISPATCHATTR_IPV4;
|
||||
@ -278,8 +275,9 @@ main(int argc, char *argv[])
|
||||
DNS_DISPATCHATTR_IPV6;
|
||||
dispatchv4 = NULL;
|
||||
RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
|
||||
&bind_addr, 4096, 4, 2, 3, 5,
|
||||
attrs, attrmask, &dispatchv4));
|
||||
have_src ? &srcaddr : &bind_any,
|
||||
4096, 4, 2, 3, 5,
|
||||
attrs, attrmask, &dispatchv4));
|
||||
requestmgr = NULL;
|
||||
RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
|
||||
dispatchmgr, dispatchv4, NULL,
|
||||
@ -288,31 +286,7 @@ main(int argc, char *argv[])
|
||||
view = NULL;
|
||||
RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
|
||||
|
||||
sock = NULL;
|
||||
RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp,
|
||||
&sock));
|
||||
RUNCHECK(isc_socket_bind(sock, &bind_addr, 0));
|
||||
|
||||
result = ISC_R_FAILURE;
|
||||
if (inet_pton(AF_INET, "10.53.0.4", &inaddr) != 1)
|
||||
CHECK("inet_pton", result);
|
||||
isc_sockaddr_fromin(&address, &inaddr, PORT);
|
||||
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_TCP;
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
attrs |= DNS_DISPATCHATTR_CONNECTED;
|
||||
isc_socket_dscp(sock, -1);
|
||||
tcpdispatch = NULL;
|
||||
RUNCHECK(dns_dispatch_createtcp2(dispatchmgr, sock, taskmgr,
|
||||
&bind_addr, &address,
|
||||
4096, 20, 10, 3, 5,
|
||||
attrs, &tcpdispatch));
|
||||
|
||||
RUNCHECK(isc_app_onrun(mctx, task, connecting, sock));
|
||||
|
||||
isc_socket_detach(&sock);
|
||||
RUNCHECK(isc_app_onrun(mctx, task, sendqueries, NULL));
|
||||
|
||||
(void)isc_app_run();
|
||||
|
||||
@ -322,7 +296,6 @@ main(int argc, char *argv[])
|
||||
dns_requestmgr_detach(&requestmgr);
|
||||
|
||||
dns_dispatch_detach(&dispatchv4);
|
||||
dns_dispatch_detach(&tcpdispatch);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
|
@ -314,6 +314,9 @@ typedef __int64 off_t;
|
||||
/* Define to the flags type used by getnameinfo(3). */
|
||||
#define IRS_GETNAMEINFO_FLAGS_T int
|
||||
|
||||
/* Define to the sockaddr length type used by getnameinfo(3). */
|
||||
#define IRS_GETNAMEINFO_SOCKLEN_T socklen_t
|
||||
|
||||
/* Define to enable the "filter-aaaa-on-v4" and "filter-aaaa-on-v6" options.
|
||||
*/
|
||||
@ALLOW_FILTER_AAAA@
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -383,8 +383,13 @@ dns_dispatch_starttcp(dns_dispatch_t *disp);
|
||||
isc_result_t
|
||||
dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
|
||||
isc_sockaddr_t *localaddr, dns_dispatch_t **dispp);
|
||||
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);
|
||||
/*
|
||||
* Attempt to connect to a existing TCP connection.
|
||||
* Attempt to connect to a existing TCP connection (connection completed
|
||||
* for dns_dispatch_gettcp()).
|
||||
*/
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#define DNS_REQUESTOPT_TCP 0x00000001U
|
||||
#define DNS_REQUESTOPT_CASE 0x00000002U
|
||||
#define DNS_REQUESTOPT_FIXEDID 0x00000004U
|
||||
#define DNS_REQUESTOPT_SHARE 0x00000008U
|
||||
|
||||
typedef struct dns_requestevent {
|
||||
ISC_EVENT_COMMON(struct dns_requestevent);
|
||||
@ -174,7 +175,9 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
* Notes:
|
||||
*
|
||||
*\li 'message' will be rendered and sent to 'address'. If the
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used,
|
||||
* #DNS_REQUESTOPT_SHARE option is set too, connecting TCP
|
||||
* (vs. connected) will be shared too. The request
|
||||
* will timeout after 'timeout' seconds.
|
||||
*
|
||||
*\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive
|
||||
@ -238,7 +241,9 @@ dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
* Notes:
|
||||
*
|
||||
*\li 'message' will be rendered and sent to 'address'. If the
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used,
|
||||
* #DNS_REQUESTOPT_SHARE option is set too, connecting TCP
|
||||
* (vs. connected) will be shared too. The request
|
||||
* will timeout after 'timeout' seconds. UDP requests will be resent
|
||||
* at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero.
|
||||
*
|
||||
@ -305,7 +310,9 @@ dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
||||
* Notes:
|
||||
*
|
||||
*\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
|
||||
* #DNS_REQUESTOPT_TCP option is set, TCP will be used,
|
||||
* #DNS_REQUESTOPT_SHARE option is set too, connecting TCP
|
||||
* (vs. connected) will be shared too. The request
|
||||
* will timeout after 'timeout' seconds. UDP requests will be resent
|
||||
* at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero.
|
||||
*
|
||||
|
@ -525,7 +525,8 @@ isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
create_tcp_dispatch(isc_boolean_t newtcp, dns_requestmgr_t *requestmgr,
|
||||
create_tcp_dispatch(isc_boolean_t newtcp, isc_boolean_t share,
|
||||
dns_requestmgr_t *requestmgr,
|
||||
isc_sockaddr_t *srcaddr,
|
||||
isc_sockaddr_t *destaddr, isc_dscp_t dscp,
|
||||
isc_boolean_t *connected, dns_dispatch_t **dispatchp)
|
||||
@ -536,7 +537,20 @@ create_tcp_dispatch(isc_boolean_t newtcp, dns_requestmgr_t *requestmgr,
|
||||
unsigned int attrs;
|
||||
isc_sockaddr_t bind_any;
|
||||
|
||||
if (!newtcp) {
|
||||
if (!newtcp && share) {
|
||||
result = dns_dispatch_gettcp2(requestmgr->dispatchmgr,
|
||||
destaddr, srcaddr,
|
||||
connected, dispatchp);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
char peer[ISC_SOCKADDR_FORMATSIZE];
|
||||
|
||||
isc_sockaddr_format(destaddr, peer, sizeof(peer));
|
||||
req_log(ISC_LOG_DEBUG(1), "attached to %s TCP "
|
||||
"connection to %s",
|
||||
*connected ? "existing" : "pending", peer);
|
||||
return (result);
|
||||
}
|
||||
} else if (!newtcp) {
|
||||
result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr,
|
||||
srcaddr, dispatchp);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
@ -642,7 +656,7 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
get_dispatch(isc_boolean_t tcp, isc_boolean_t newtcp,
|
||||
get_dispatch(isc_boolean_t tcp, isc_boolean_t newtcp, isc_boolean_t share,
|
||||
dns_requestmgr_t *requestmgr,
|
||||
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
|
||||
isc_dscp_t dscp, isc_boolean_t *connected,
|
||||
@ -651,9 +665,9 @@ get_dispatch(isc_boolean_t tcp, isc_boolean_t newtcp,
|
||||
isc_result_t result;
|
||||
|
||||
if (tcp)
|
||||
result = create_tcp_dispatch(newtcp, requestmgr, srcaddr,
|
||||
destaddr, dscp, connected,
|
||||
dispatchp);
|
||||
result = create_tcp_dispatch(newtcp, share, requestmgr,
|
||||
srcaddr, destaddr, dscp,
|
||||
connected, dispatchp);
|
||||
else
|
||||
result = find_udp_dispatch(requestmgr, srcaddr,
|
||||
destaddr, dispatchp);
|
||||
@ -740,6 +754,7 @@ dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
||||
dns_messageid_t id;
|
||||
isc_boolean_t tcp = ISC_FALSE;
|
||||
isc_boolean_t newtcp = ISC_FALSE;
|
||||
isc_boolean_t share = ISC_FALSE;
|
||||
isc_region_t r;
|
||||
isc_boolean_t connected = ISC_FALSE;
|
||||
unsigned int dispopt = 0;
|
||||
@ -803,9 +818,11 @@ dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
||||
|
||||
if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
|
||||
tcp = ISC_TRUE;
|
||||
share = ISC_TF((options & DNS_REQUESTOPT_SHARE) != 0);
|
||||
|
||||
again:
|
||||
result = get_dispatch(tcp, newtcp, requestmgr, srcaddr, destaddr, dscp,
|
||||
result = get_dispatch(tcp, newtcp, share, requestmgr,
|
||||
srcaddr, destaddr, dscp,
|
||||
&connected, &request->dispatch);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
@ -971,6 +988,7 @@ dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
isc_mem_t *mctx;
|
||||
dns_messageid_t id;
|
||||
isc_boolean_t tcp;
|
||||
isc_boolean_t share;
|
||||
isc_boolean_t setkey = ISC_TRUE;
|
||||
isc_boolean_t connected = ISC_FALSE;
|
||||
|
||||
@ -1031,7 +1049,9 @@ dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
|
||||
use_tcp:
|
||||
tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
|
||||
result = get_dispatch(tcp, ISC_FALSE, requestmgr, srcaddr, destaddr,
|
||||
share = ISC_TF((options & DNS_REQUESTOPT_SHARE) != 0);
|
||||
result = get_dispatch(tcp, ISC_FALSE, share,
|
||||
requestmgr, srcaddr, destaddr,
|
||||
dscp, &connected, &request->dispatch);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
@ -59,7 +59,6 @@ dns_adb_noedns
|
||||
dns_adb_plainresponse
|
||||
dns_adb_probesize
|
||||
dns_adb_probesize2
|
||||
dns_adb_probesize512
|
||||
dns_adb_setadbsize
|
||||
dns_adb_setudpsize
|
||||
dns_adb_setsit
|
||||
@ -257,6 +256,7 @@ dns_dispatch_getentrysocket
|
||||
dns_dispatch_getlocaladdress
|
||||
dns_dispatch_getsocket
|
||||
dns_dispatch_gettcp
|
||||
dns_dispatch_gettcp2
|
||||
dns_dispatch_getudp
|
||||
dns_dispatch_getudp_dup
|
||||
dns_dispatch_importrecv
|
||||
|
@ -347,7 +347,7 @@ struct isc__socket {
|
||||
ISC_LIST(isc_socketevent_t) send_list;
|
||||
ISC_LIST(isc_socketevent_t) recv_list;
|
||||
ISC_LIST(isc_socket_newconnev_t) accept_list;
|
||||
isc_socket_connev_t *connect_ev;
|
||||
ISC_LIST(isc_socket_connev_t) connect_list;
|
||||
|
||||
/*
|
||||
* Internal events. Posted when a descriptor is readable or
|
||||
@ -471,6 +471,7 @@ static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf,
|
||||
isc_socket_t *dup_socket);
|
||||
static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **);
|
||||
static void send_senddone_event(isc__socket_t *, isc_socketevent_t **);
|
||||
static void send_connectdone_event(isc__socket_t *, isc_socket_connev_t **);
|
||||
static void free_socket(isc__socket_t **);
|
||||
static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t,
|
||||
isc__socket_t **);
|
||||
@ -2216,10 +2217,10 @@ destroy(isc__socket_t **sockp) {
|
||||
socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_DESTROYING, "destroying");
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(sock->connect_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->send_list));
|
||||
INSIST(sock->connect_ev == NULL);
|
||||
REQUIRE(sock->fd == -1 || sock->fd < (int)manager->maxsocks);
|
||||
|
||||
if (sock->fd >= 0) {
|
||||
@ -2326,7 +2327,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
|
||||
ISC_LIST_INIT(sock->recv_list);
|
||||
ISC_LIST_INIT(sock->send_list);
|
||||
ISC_LIST_INIT(sock->accept_list);
|
||||
sock->connect_ev = NULL;
|
||||
ISC_LIST_INIT(sock->connect_list);
|
||||
sock->pending_recv = 0;
|
||||
sock->pending_send = 0;
|
||||
sock->pending_accept = 0;
|
||||
@ -2394,6 +2395,7 @@ free_socket(isc__socket_t **socketp) {
|
||||
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->send_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->connect_list));
|
||||
INSIST(!ISC_LINK_LINKED(sock, link));
|
||||
|
||||
if (sock->recvcmsgbuf != NULL)
|
||||
@ -3223,7 +3225,7 @@ isc__socket_close(isc_socket_t *sock0) {
|
||||
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->send_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||
INSIST(sock->connect_ev == NULL);
|
||||
INSIST(ISC_LIST_EMPTY(sock->connect_list));
|
||||
|
||||
manager = sock->manager;
|
||||
fd = sock->fd;
|
||||
@ -3356,7 +3358,7 @@ dispatch_connect(isc__socket_t *sock) {
|
||||
|
||||
iev = &sock->writable_ev;
|
||||
|
||||
ev = sock->connect_ev;
|
||||
ev = ISC_LIST_HEAD(sock->connect_list);
|
||||
INSIST(ev != NULL); /* XXX */
|
||||
|
||||
INSIST(sock->connecting);
|
||||
@ -3421,6 +3423,26 @@ send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
|
||||
isc_task_send(task, (isc_event_t **)dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* See comments for send_recvdone_event() above.
|
||||
*
|
||||
* Caller must have the socket locked if the event is attached to the socket.
|
||||
*/
|
||||
static void
|
||||
send_connectdone_event(isc__socket_t *sock, isc_socket_connev_t **dev) {
|
||||
isc_task_t *task;
|
||||
|
||||
INSIST(dev != NULL && *dev != NULL);
|
||||
|
||||
task = (*dev)->ev_sender;
|
||||
(*dev)->ev_sender = sock;
|
||||
|
||||
if (ISC_LINK_LINKED(*dev, ev_link))
|
||||
ISC_LIST_DEQUEUE(sock->connect_list, *dev, ev_link);
|
||||
|
||||
isc_task_sendanddetach(&task, (isc_event_t **)dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call accept() on a socket, to get the new file descriptor. The listen
|
||||
* socket is used as a prototype to create a new isc_socket_t. The new
|
||||
@ -5682,8 +5704,6 @@ isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
|
||||
|
||||
LOCK(&sock->lock);
|
||||
|
||||
REQUIRE(!sock->connecting);
|
||||
|
||||
dev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_CONNECT,
|
||||
action, arg,
|
||||
@ -5694,6 +5714,11 @@ isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
|
||||
}
|
||||
ISC_LINK_INIT(dev, ev_link);
|
||||
|
||||
if (sock->connecting) {
|
||||
INSIST(isc_sockaddr_equal(&sock->peer_address, addr));
|
||||
goto queue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to do the connect right away, as there can be only one
|
||||
* outstanding, and it might happen to complete.
|
||||
@ -5780,8 +5805,6 @@ isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
|
||||
*/
|
||||
isc_task_attach(task, &ntask);
|
||||
|
||||
sock->connecting = 1;
|
||||
|
||||
dev->ev_sender = ntask;
|
||||
|
||||
/*
|
||||
@ -5789,10 +5812,12 @@ isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
|
||||
* is no race condition. We will keep the lock for such a short
|
||||
* bit of time waking it up now or later won't matter all that much.
|
||||
*/
|
||||
if (sock->connect_ev == NULL)
|
||||
if (ISC_LIST_EMPTY(sock->connect_list) && !sock->connecting)
|
||||
select_poke(manager, sock->fd, SELECT_POKE_CONNECT);
|
||||
|
||||
sock->connect_ev = dev;
|
||||
sock->connecting = 1;
|
||||
|
||||
ISC_LIST_ENQUEUE(sock->connect_list, dev, ev_link);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
@ -5805,8 +5830,8 @@ static void
|
||||
internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
isc__socket_t *sock;
|
||||
isc_socket_connev_t *dev;
|
||||
isc_task_t *task;
|
||||
int cc;
|
||||
isc_result_t result;
|
||||
ISC_SOCKADDR_LEN_T optlen;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||
@ -5832,9 +5857,10 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Has this event been canceled?
|
||||
* Get the first item off the connect list.
|
||||
* If it is empty, unlock the socket and return.
|
||||
*/
|
||||
dev = sock->connect_ev;
|
||||
dev = ISC_LIST_HEAD(sock->connect_list);
|
||||
if (dev == NULL) {
|
||||
INSIST(!sock->connecting);
|
||||
UNLOCK(&sock->lock);
|
||||
@ -5875,7 +5901,7 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
* Translate other errors into ISC_R_* flavors.
|
||||
*/
|
||||
switch (errno) {
|
||||
#define ERROR_MATCH(a, b) case a: dev->result = b; break;
|
||||
#define ERROR_MATCH(a, b) case a: result = b; break;
|
||||
ERROR_MATCH(EACCES, ISC_R_NOPERM);
|
||||
ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
|
||||
ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL);
|
||||
@ -5892,7 +5918,7 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET);
|
||||
#undef ERROR_MATCH
|
||||
default:
|
||||
dev->result = ISC_R_UNEXPECTED;
|
||||
result = ISC_R_UNEXPECTED;
|
||||
isc_sockaddr_format(&sock->peer_address, peerbuf,
|
||||
sizeof(peerbuf));
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
@ -5903,18 +5929,18 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
} else {
|
||||
inc_stats(sock->manager->stats,
|
||||
sock->statsindex[STATID_CONNECT]);
|
||||
dev->result = ISC_R_SUCCESS;
|
||||
result = ISC_R_SUCCESS;
|
||||
sock->connected = 1;
|
||||
sock->bound = 1;
|
||||
}
|
||||
|
||||
sock->connect_ev = NULL;
|
||||
do {
|
||||
dev->result = result;
|
||||
send_connectdone_event(sock, &dev);
|
||||
dev = ISC_LIST_HEAD(sock->connect_list);
|
||||
} while (dev != NULL);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
task = dev->ev_sender;
|
||||
dev->ev_sender = sock;
|
||||
isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@ -6072,27 +6098,26 @@ isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Connecting is not a list.
|
||||
*/
|
||||
if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT)
|
||||
&& sock->connect_ev != NULL) {
|
||||
&& !ISC_LIST_EMPTY(sock->connect_list)) {
|
||||
isc_socket_connev_t *dev;
|
||||
isc_socket_connev_t *next;
|
||||
isc_task_t *current_task;
|
||||
|
||||
INSIST(sock->connecting);
|
||||
sock->connecting = 0;
|
||||
|
||||
dev = sock->connect_ev;
|
||||
current_task = dev->ev_sender;
|
||||
dev = ISC_LIST_HEAD(sock->connect_list);
|
||||
|
||||
if ((task == NULL) || (task == current_task)) {
|
||||
sock->connect_ev = NULL;
|
||||
while (dev != NULL) {
|
||||
current_task = dev->ev_sender;
|
||||
next = ISC_LIST_NEXT(dev, ev_link);
|
||||
|
||||
dev->result = ISC_R_CANCELED;
|
||||
dev->ev_sender = sock;
|
||||
isc_task_sendanddetach(¤t_task,
|
||||
ISC_EVENT_PTR(&dev));
|
||||
if ((task == NULL) || (task == current_task)) {
|
||||
dev->result = ISC_R_CANCELED;
|
||||
send_connectdone_event(sock, &dev);
|
||||
}
|
||||
dev = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,9 +483,6 @@ isc_portset_isset
|
||||
isc_portset_nports
|
||||
isc_portset_remove
|
||||
isc_portset_removerange
|
||||
isc_print_snprintf
|
||||
isc_print_sprintf
|
||||
isc_print_vsnprintf
|
||||
isc_quota_attach
|
||||
isc_quota_destroy
|
||||
isc_quota_detach
|
||||
@ -583,42 +580,8 @@ isc_sockaddr_pf
|
||||
isc_sockaddr_setport
|
||||
isc_sockaddr_totext
|
||||
isc_sockaddr_v6fromin
|
||||
isc_socket_accept
|
||||
isc_socket_attach
|
||||
isc_socket_bind
|
||||
isc_socket_cancel
|
||||
isc_socket_cleanunix
|
||||
isc_socket_close
|
||||
isc_socket_connect
|
||||
isc_socket_create
|
||||
isc_socket_detach
|
||||
isc_socket_dscp
|
||||
isc_socket_dup
|
||||
isc_socket_fdwatchcreate
|
||||
isc_socket_fdwatchpoke
|
||||
isc_socket_filter
|
||||
isc_socket_getpeername
|
||||
isc_socket_getsockname
|
||||
isc_socket_gettype
|
||||
isc_socket_ipv6only
|
||||
isc_socket_listen
|
||||
isc_socket_open
|
||||
isc_socket_permunix
|
||||
isc_socket_register
|
||||
isc_socket_recv
|
||||
isc_socket_recv2
|
||||
isc_socket_recvv
|
||||
isc_socket_send
|
||||
isc_socket_sendto
|
||||
isc_socket_sendto2
|
||||
isc_socket_sendtov
|
||||
isc_socket_sendtov2
|
||||
isc_socket_sendv
|
||||
isc_socket_socketevent
|
||||
isc_socketmgr_create
|
||||
isc_socketmgr_create2
|
||||
isc_socketmgr_createinctx
|
||||
isc_socketmgr_destroy
|
||||
@IF LIBXML2
|
||||
isc_socketmgr_renderxml
|
||||
@END LIBXML2
|
||||
|
@ -266,7 +266,7 @@ struct isc_socket {
|
||||
ISC_LIST(isc_socketevent_t) send_list;
|
||||
ISC_LIST(isc_socketevent_t) recv_list;
|
||||
ISC_LIST(isc_socket_newconnev_t) accept_list;
|
||||
isc_socket_connev_t *connect_ev;
|
||||
ISC_LIST(isc_socket_connev_t) connect_list;
|
||||
|
||||
isc_sockaddr_t address; /* remote address */
|
||||
|
||||
@ -375,6 +375,7 @@ static void send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev);
|
||||
static void send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev);
|
||||
static void send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev);
|
||||
static void send_recvdone_abort(isc_socket_t *sock, isc_result_t result);
|
||||
static void send_connectdone_abort(isc_socket_t *sock, isc_result_t result);
|
||||
static void queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev);
|
||||
static void queue_receive_request(isc_socket_t *sock);
|
||||
|
||||
@ -388,6 +389,7 @@ void
|
||||
sock_dump(isc_socket_t *sock) {
|
||||
isc_socketevent_t *ldev;
|
||||
isc_socket_newconnev_t *ndev;
|
||||
isc_socket_connev_t *cdev;
|
||||
|
||||
#if 0
|
||||
isc_sockaddr_t addr;
|
||||
@ -436,6 +438,13 @@ sock_dump(isc_socket_t *sock) {
|
||||
printf("\t\tdev: %p\n", ldev);
|
||||
ndev = ISC_LIST_NEXT(ndev, ev_link);
|
||||
}
|
||||
|
||||
printf("\n\t\tSock Connect List\n");
|
||||
cdev = ISC_LIST_HEAD(sock->connect_list);
|
||||
while (cdev != NULL) {
|
||||
printf("\t\tdev: %p\n", cdev);
|
||||
cdev = ISC_LIST_NEXT(cdev, ev_link);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1486,7 +1495,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
|
||||
ISC_LIST_INIT(sock->recv_list);
|
||||
ISC_LIST_INIT(sock->send_list);
|
||||
ISC_LIST_INIT(sock->accept_list);
|
||||
sock->connect_ev = NULL;
|
||||
ISC_LIST_INIT(sock->connect_list);
|
||||
sock->pending_accept = 0;
|
||||
sock->pending_recv = 0;
|
||||
sock->pending_send = 0;
|
||||
@ -1565,7 +1574,7 @@ consistent(isc_socket_t *sock) {
|
||||
}
|
||||
if (count > sock->pending_accept) {
|
||||
crash = ISC_TRUE;
|
||||
crash_reason = "send_list > sock->pending_send";
|
||||
crash_reason = "accept_list > sock->pending_accept";
|
||||
}
|
||||
|
||||
if (crash) {
|
||||
@ -1609,6 +1618,7 @@ maybe_free_socket(isc_socket_t **socketp, int lineno) {
|
||||
|| !ISC_LIST_EMPTY(sock->recv_list)
|
||||
|| !ISC_LIST_EMPTY(sock->send_list)
|
||||
|| !ISC_LIST_EMPTY(sock->accept_list)
|
||||
|| !ISC_LIST_EMPTY(sock->connect_list)
|
||||
|| sock->fd != INVALID_SOCKET) {
|
||||
UNLOCK(&sock->lock);
|
||||
return;
|
||||
@ -2030,7 +2040,8 @@ send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev) {
|
||||
task = (*cdev)->ev_sender;
|
||||
(*cdev)->ev_sender = sock;
|
||||
|
||||
sock->connect_ev = NULL;
|
||||
if (ISC_LINK_LINKED(*cdev, ev_link))
|
||||
ISC_LIST_DEQUEUE(sock->connect_list, *cdev, ev_link);
|
||||
|
||||
isc_task_sendanddetach(&task, (isc_event_t **)cdev);
|
||||
|
||||
@ -2148,6 +2159,7 @@ done:
|
||||
static void
|
||||
internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
|
||||
isc_socket_connev_t *cdev;
|
||||
isc_result_t result;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
INSIST(VALID_SOCKET(sock));
|
||||
@ -2160,7 +2172,7 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
|
||||
sock->pending_connect = 0;
|
||||
|
||||
/*
|
||||
* Has this event been canceled?
|
||||
* If the event is no longer in the list we can just close and return.
|
||||
*/
|
||||
cdev = lpo->cdev;
|
||||
if (!connectdone_is_active(sock, cdev)) {
|
||||
@ -2195,7 +2207,7 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
|
||||
* Translate other errors into ISC_R_* flavors.
|
||||
*/
|
||||
switch (connect_errno) {
|
||||
#define ERROR_MATCH(a, b) case a: cdev->result = b; break;
|
||||
#define ERROR_MATCH(a, b) case a: result = b; break;
|
||||
ERROR_MATCH(WSAEACCES, ISC_R_NOPERM);
|
||||
ERROR_MATCH(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
|
||||
ERROR_MATCH(WSAEAFNOSUPPORT, ISC_R_ADDRNOTAVAIL);
|
||||
@ -2210,7 +2222,7 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
|
||||
ERROR_MATCH(WSAETIMEDOUT, ISC_R_TIMEDOUT);
|
||||
#undef ERROR_MATCH
|
||||
default:
|
||||
cdev->result = ISC_R_UNEXPECTED;
|
||||
result = ISC_R_UNEXPECTED;
|
||||
isc__strerror(connect_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"internal_connect: connect() %s",
|
||||
@ -2219,14 +2231,18 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
|
||||
} else {
|
||||
INSIST(setsockopt(sock->fd, SOL_SOCKET,
|
||||
SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == 0);
|
||||
cdev->result = ISC_R_SUCCESS;
|
||||
result = ISC_R_SUCCESS;
|
||||
sock->connected = 1;
|
||||
socket_log(__LINE__, sock, &sock->address, IOEVENT,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
|
||||
"internal_connect: success");
|
||||
}
|
||||
|
||||
send_connectdone_event(sock, &cdev);
|
||||
do {
|
||||
cdev->result = result;
|
||||
send_connectdone_event(sock, &cdev);
|
||||
cdev = ISC_LIST_HEAD(sock->connect_list);
|
||||
} while (cdev != NULL);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
}
|
||||
@ -2245,6 +2261,20 @@ send_recvdone_abort(isc_socket_t *sock, isc_result_t result) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through the socket, returning result for each done event pending.
|
||||
*/
|
||||
static void
|
||||
send_connectdone_abort(isc_socket_t *sock, isc_result_t result) {
|
||||
isc_socket_connev_t *dev;
|
||||
|
||||
while (!ISC_LIST_EMPTY(sock->connect_list)) {
|
||||
dev = ISC_LIST_HEAD(sock->connect_list);
|
||||
dev->result = result;
|
||||
send_connectdone_event(sock, &dev);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Take the data we received in our private buffer, and if any recv() calls on
|
||||
* our list are satisfied, send the corresponding done event.
|
||||
@ -2361,9 +2391,8 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
}
|
||||
|
||||
/*
|
||||
* These return if the done event passed in is on the list (or for connect, is
|
||||
* the one we're waiting for. Using these ensures we will not double-send an
|
||||
* event.
|
||||
* These return if the done event passed in is on the list.
|
||||
* Using these ensures we will not double-send an event.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev)
|
||||
@ -2392,7 +2421,13 @@ acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev)
|
||||
static isc_boolean_t
|
||||
connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev)
|
||||
{
|
||||
return (sock->connect_ev == dev ? ISC_TRUE : ISC_FALSE);
|
||||
isc_socket_connev_t *cdev;
|
||||
|
||||
cdev = ISC_LIST_HEAD(sock->connect_list);
|
||||
while (cdev != NULL && cdev != dev)
|
||||
cdev = ISC_LIST_NEXT(cdev, ev_link);
|
||||
|
||||
return (cdev == NULL ? ISC_FALSE : ISC_TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
@ -2592,10 +2627,9 @@ SocketIoThread(LPVOID ThreadContext) {
|
||||
INSIST(sock->pending_connect == 1);
|
||||
sock->pending_connect = 0;
|
||||
if (connectdone_is_active(sock, lpo->cdev)) {
|
||||
lpo->cdev->result = isc_result;
|
||||
socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0,
|
||||
"canceled_connect");
|
||||
send_connectdone_event(sock, &lpo->cdev);
|
||||
send_connectdone_abort(sock, isc_result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3535,8 +3569,6 @@ isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
sock->bound = 1;
|
||||
}
|
||||
|
||||
REQUIRE(!sock->pending_connect);
|
||||
|
||||
cdev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_CONNECT,
|
||||
action, arg,
|
||||
@ -3547,7 +3579,7 @@ isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
}
|
||||
ISC_LINK_INIT(cdev, ev_link);
|
||||
|
||||
if (sock->type == isc_sockettype_tcp) {
|
||||
if ((sock->type == isc_sockettype_tcp) && !sock->pending_connect) {
|
||||
/*
|
||||
* Queue io completion for an accept().
|
||||
*/
|
||||
@ -3573,9 +3605,17 @@ isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
/*
|
||||
* Enqueue the request.
|
||||
*/
|
||||
sock->connect_ev = cdev;
|
||||
INSIST(!ISC_LINK_LINKED(cdev, ev_link));
|
||||
ISC_LIST_ENQUEUE(sock->connect_list, cdev, ev_link);
|
||||
sock->pending_iocp++;
|
||||
} else if (sock->type == isc_sockettype_tcp) {
|
||||
INSIST(isc_sockaddr_equal(&sock->address, addr));
|
||||
isc_task_attach(task, &ntask);
|
||||
cdev->ev_sender = ntask;
|
||||
INSIST(!ISC_LINK_LINKED(cdev, ev_link));
|
||||
ISC_LIST_ENQUEUE(sock->connect_list, cdev, ev_link);
|
||||
} else {
|
||||
REQUIRE(!sock->pending_connect);
|
||||
WSAConnect(sock->fd, &addr->type.sa, addr->length, NULL, NULL, NULL, NULL);
|
||||
cdev->result = ISC_R_SUCCESS;
|
||||
isc_task_send(task, (isc_event_t **)&cdev);
|
||||
@ -3761,28 +3801,28 @@ isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
|
||||
}
|
||||
how &= ~ISC_SOCKCANCEL_ACCEPT;
|
||||
|
||||
/*
|
||||
* Connecting is not a list.
|
||||
*/
|
||||
if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT)
|
||||
&& sock->connect_ev != NULL) {
|
||||
&& !ISC_LIST_EMPTY(sock->connect_list)) {
|
||||
isc_socket_connev_t *dev;
|
||||
isc_socket_connev_t *next;
|
||||
isc_task_t *current_task;
|
||||
|
||||
INSIST(sock->pending_connect);
|
||||
|
||||
dev = sock->connect_ev;
|
||||
current_task = dev->ev_sender;
|
||||
dev = ISC_LIST_HEAD(sock->connect_list);
|
||||
|
||||
if ((task == NULL) || (task == current_task)) {
|
||||
closesocket(sock->fd);
|
||||
sock->fd = INVALID_SOCKET;
|
||||
_set_state(sock, SOCK_CLOSED);
|
||||
|
||||
sock->connect_ev = NULL;
|
||||
dev->result = ISC_R_CANCELED;
|
||||
send_connectdone_event(sock, &dev);
|
||||
while (dev != NULL) {
|
||||
current_task = dev->ev_sender;
|
||||
next = ISC_LIST_NEXT(dev, ev_link);
|
||||
if ((task == NULL) || (task == current_task)) {
|
||||
dev->result = ISC_R_CANCELED;
|
||||
send_connectdone_event(sock, &dev);
|
||||
}
|
||||
dev = next;
|
||||
}
|
||||
closesocket(sock->fd);
|
||||
sock->fd = INVALID_SOCKET;
|
||||
_set_state(sock, SOCK_CLOSED);
|
||||
}
|
||||
how &= ~ISC_SOCKCANCEL_CONNECT;
|
||||
|
||||
|
@ -93,7 +93,6 @@ cfg_print_boolean
|
||||
cfg_print_bracketed_list
|
||||
cfg_print_chars
|
||||
cfg_print_cstr
|
||||
cfg_print_fixedpoint
|
||||
cfg_print_grammar
|
||||
cfg_print_map
|
||||
cfg_print_mapbody
|
||||
|
@ -1588,7 +1588,7 @@
|
||||
./bin/tests/system/pipelined/ns3/named.args X 2014
|
||||
./bin/tests/system/pipelined/ns3/named.conf CONF-C 2014
|
||||
./bin/tests/system/pipelined/ns4/named.conf CONF-C 2014
|
||||
./bin/tests/system/pipelined/pipequeries.c C 2014
|
||||
./bin/tests/system/pipelined/pipequeries.c C 2014,2015
|
||||
./bin/tests/system/pipelined/ref X 2014
|
||||
./bin/tests/system/pipelined/refb X 2014
|
||||
./bin/tests/system/pipelined/setup.sh SH 2014
|
||||
|
Loading…
x
Reference in New Issue
Block a user