]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] allow shared TCP sockets when connecting
authorEvan Hunt <each@isc.org>
Wed, 21 Jan 2015 01:22:31 +0000 (17:22 -0800)
committerEvan Hunt <each@isc.org>
Wed, 21 Jan 2015 01:22:31 +0000 (17:22 -0800)
4041. [func] TCP sockets can now be shared while connecting.
(This will be used to enable client-side support
of pipelined queries.) [RT #38231]

16 files changed:
CHANGES
bin/tests/system/conf.sh.in
bin/tests/system/pipelined/clean.sh
bin/tests/system/pipelined/ns3/named.args
bin/tests/system/pipelined/pipequeries.c
config.h.win32
lib/dns/dispatch.c
lib/dns/include/dns/dispatch.h
lib/dns/include/dns/request.h
lib/dns/request.c
lib/dns/win32/libdns.def.in
lib/isc/unix/socket.c
lib/isc/win32/libisc.def.in
lib/isc/win32/socket.c
lib/isccfg/win32/libisccfg.def
util/copyrights

diff --git a/CHANGES b/CHANGES
index 7c64bdfe50d373ffc73cd924ad6d355c74fd1fcd..a85652202fa018fb73fb1bea18619d4afea425d9 100644 (file)
--- a/CHANGES
+++ b/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
index d8e4c4acddd7931750f89708e4aab1d94441d55c..968114ad9f228157d540392c5838bdd491932ba7 100644 (file)
@@ -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
index 1cca633dd190c671645eff9b363393c04b1cc6e5..7c2f21320932f5de399820aae06065dcdcf939b7 100644 (file)
@@ -17,3 +17,4 @@
 rm -f */named.memstats
 rm -f */named.run
 rm -f raw* output*
+rm -f ns*/named.lock
index a6b0f54e56e09d74647b95f4d2302c2edf33a145..51b9cc34dd3bad33ccda76420d9ae5ba2d873dd7 100644 (file)
@@ -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
index 41794ec84a80c67230ea04a716c7d3388407bb70..0b40f8cf57c2d1d8d0ed198998991a8029fc4620 100644 (file)
@@ -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[])
-{
+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;
-       isc_socket_t *sock;
-       unsigned int attrs, attrmask;
-       isc_sockaddr_t bind_addr;
        dns_dispatchmgr_t *dispatchmgr;
+       unsigned int attrs, attrmask;
        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;
-       struct in_addr inaddr;
-       isc_result_t result;
 
        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);
index 73a64ca45fbbe571f6387cc4dad9da7046739d58..bcd7fdd8d292675939e566fc1eddb728f75eac27 100644 (file)
@@ -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@
index 1e31209f16d278e75b4fa0ea29e2d2f9048f0194..325dc718bcefb6344f3d73c7f323fa1d3b44b99b 100644 (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);
 }
 
index 25622ed201bf2aeaefece3c00c5f6b68aa4a6145..14ebf61daabaa7828e9e0d2ffd8e77977123f704 100644 (file)
@@ -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()).
  */
 
 
index b19e91164de6459f9120d954a71b4157cfed89c6..767eea0356943607fb6f16d562ea41cc9eca8036 100644 (file)
@@ -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.
  *
index 4827bbd67475447cd95251fd1dbe868deb32d66f..e31239ab7478e75e4793e75542afd8131db3359b 100644 (file)
@@ -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;
index fe65fc81b36348d422aced24ebde2ec6f15abdec..4b9a60210584adc5bf85c1cb5a73c23862254567 100644 (file)
@@ -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
index 2aae76f11801c01552a38cc8958e10786cf18636..fea8e87e590eb9d24b1455a4a85710cd9a1b2441 100644 (file)
@@ -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(&current_task,
-                                              ISC_EVENT_PTR(&dev));
+                       if ((task == NULL) || (task == current_task)) {
+                               dev->result = ISC_R_CANCELED;
+                               send_connectdone_event(sock, &dev);
+                       }
+                       dev = next;
                }
        }
 
index ade7a6e6a2d25ae607f1f710c10caba568f73f68..b56d4d6441e2fd6ee8d1743a9d37cf1e233f887b 100644 (file)
@@ -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
index 1e078fb67a5f1c7c9012359ce15692bb09fa7090..276b13b0fe852871dd89a179a4ff8611c511f9ef 100644 (file)
@@ -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;
 
index a0d464eb452bb711dfb6310eb37da2430ec54ee3..bbd6c43182b4d903588e7686afcc66035c8d0588 100644 (file)
@@ -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
index e62dd1da1f3b9d65323018f678b6a021b516cda7..c66cd14e10000b3f377db02097afe4ea0003bbf8 100644 (file)
 ./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